More work on CAPWAP VM

FossilOrigin-Name: 9d9a86d2bafe31253a6f505e874f188792539485bb4462f4d778e6c53ac3000b
This commit is contained in:
7u83@mail.ru 2015-04-05 18:27:17 +00:00
parent ab8128a20f
commit 1158167262
33 changed files with 648 additions and 532 deletions

View File

@ -198,7 +198,7 @@ AP = RAD = WTP
| ResetBtnState | | ResetBtnState |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
Type: 128 for Cisco Rest Button State Type: 128 for Cisco Reset Button State
Length: 1 Length: 1
ResetBtnState: 1 = Enabeled ResetBtnState: 1 = Enabeled

View File

@ -98,7 +98,13 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data
*/ */
/*
int avlprint(void *priv, void *data)
{
struct cw_str * d = (struct cw_str*) data;
printf("String: %d - %s\n",d->id,d->str);
}
*/
int main (int argc, const char * argv[]) int main (int argc, const char * argv[])
{ {
@ -117,7 +123,19 @@ int main (int argc, const char * argv[])
cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP; cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP;
cw_register_actions_capwap_ac(&capwap_actions); cw_register_actions_cipwap_ac(&capwap_actions);
/*
struct avltree *avlt = capwap_actions.strelem;
avltree_foreach_asc(avlt,avlprint,0);
exit(0);
*/
ac_global_init(); ac_global_init();
/* /*

View File

@ -353,6 +353,7 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti
return cwrmsg; return cwrmsg;
} }
int conn_msg_processor(struct conn *conn);
static void wtpman_run_discovery(void *arg) static void wtpman_run_discovery(void *arg)
@ -361,7 +362,6 @@ static void wtpman_run_discovery(void *arg)
struct wtpman * wtpman = (struct wtpman *)arg; struct wtpman * wtpman = (struct wtpman *)arg;
struct cwrmsg * cwrmsg; struct cwrmsg * cwrmsg;
void conn_msg_processor(struct conn *conn);
time_t timer = cw_timer_start(10); time_t timer = cw_timer_start(10);
@ -370,7 +370,6 @@ extern cw_actionlist_in_t the_tree;
wtpman->conn->capwap_state=CW_STATE_DISCOVERY; wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
wtpman->conn->actions = &capwap_actions; wtpman->conn->actions = &capwap_actions;
wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->local = ac_config; wtpman->conn->local = ac_config;
wtpman->conn->remote = cw_itemstore_create(); wtpman->conn->remote = cw_itemstore_create();
@ -379,6 +378,12 @@ extern cw_actionlist_in_t the_tree;
conn_msg_processor(wtpman->conn); conn_msg_processor(wtpman->conn);
} }
struct cw_item * wn = cw_itemstore_get(wtpman->conn->remote,CW_ITEM_WTP_NAME);
if (wn ) {
printf("WTP Name: %s\n",wn->data);
}
wtpman_remove(wtpman); wtpman_remove(wtpman);
return; return;
@ -594,16 +599,20 @@ wtpman->conn->capwap_state=CW_STATE_JOIN;
wtpman->conn->capwap_state=CW_STATE_JOIN; wtpman->conn->capwap_state=CW_STATE_JOIN;
wtpman->conn->actions = &capwap_actions; wtpman->conn->actions = &capwap_actions;
wtpman->conn->itemstore = cw_itemstore_create(); // wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->local = ac_config; wtpman->conn->local = ac_config;
wtpman->conn->remote = cw_itemstore_create(); wtpman->conn->remote = cw_itemstore_create();
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_JOIN){ while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_JOIN){
conn_msg_processor(wtpman->conn); int rc = conn_msg_processor(wtpman->conn);
if (rc <0 ) {
break;
}
} }
printf("Breaked\n");
exit(0); exit(0);

View File

@ -169,12 +169,15 @@ CAPWAPOBJS= \
capwap_strings_elem.o \ capwap_strings_elem.o \
itemstore.o \ itemstore.o \
cw_in_vendor_specific_payload.o \ cw_in_vendor_specific_payload.o \
cw_in_wtp_name.o \
cw_in_wtp_board_data.o \ cw_in_wtp_board_data.o \
cw_out_generic.o \ cw_out_generic.o \
cw_out_ac_descriptor.o \ cw_out_ac_descriptor.o \
cw_out_capwap_control_ip_addrs.o cw_out_cisco_ac_descriptor.o \
cw_out_cisco_ap_timesync.o \
cw_out_capwap_control_ip_addrs.o \
strheap.o
#cw_in_wtp_name.o \
#cw_msgtostr.o \ #cw_msgtostr.o \
#cw_msgelemtostr.o \ #cw_msgelemtostr.o \
#cwmsg_addelem_ctrl_ip_addrs.o \ #cwmsg_addelem_ctrl_ip_addrs.o \
@ -265,6 +268,9 @@ CWACTION=action.o \
cw_in_generic.o \ cw_in_generic.o \
cw_in_wtp_descriptor.o \ cw_in_wtp_descriptor.o \
cipwap_actions_ac.o \ cipwap_actions_ac.o \
cipwap_strings_elem.o \
cw_put_msg.o \
capwap_action_helpers.o \

View File

@ -119,6 +119,10 @@ static int cw_action_out_cmp(const void *elem1,const void *elem2)
if (r!=0) if (r!=0)
return r; return r;
r = e1->vendor_id - e2->vendor_id;
if (r!=0)
return r;
return 0; return 0;
} }
@ -163,3 +167,6 @@ cw_action_out_t * cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_
} }

View File

@ -25,6 +25,7 @@
#include "avltree.h" #include "avltree.h"
#include "conn.h" #include "conn.h"
#include "itemstore.h" #include "itemstore.h"
#include "strheap.h"
/* Generic functions and structs */ /* Generic functions and structs */
@ -63,11 +64,12 @@ extern int cw_actionlist_in_register_actions(cw_actionlist_in_t t,cw_action_in_t
struct cw_action_out{ struct cw_action_out{
uint32_t msg_id; uint32_t msg_id;
uint32_t item_id; uint32_t item_id;
uint32_t vendor_id;
uint16_t elem_id; uint16_t elem_id;
int (*out)(struct conn * conn, uint32_t elem_id, uint8_t * dst ,struct cw_item * item); int (*out)(struct conn * conn, struct cw_action_out *a, uint8_t * dst);
struct cw_item *(*get)(struct conn *conn,uint32_t item_id); struct cw_item *(*get)(struct conn *conn,struct cw_action_out *a);
}; };
typedef struct cw_action_out cw_action_out_t; typedef struct cw_action_out cw_action_out_t;
@ -84,6 +86,10 @@ extern int cw_actionlist_out_register_actions(cw_actionlist_out_t t,cw_action_ou
struct cw_actiondef{ struct cw_actiondef{
cw_actionlist_in_t in; cw_actionlist_in_t in;
cw_actionlist_out_t out; cw_actionlist_out_t out;
cw_strheap_t strmsg;
cw_strheap_t strelem;
}; };

View File

@ -19,7 +19,7 @@
/** /**
* @file * @file
* @brief Yet another AVL tree implementation * @brief Yet another AVL tree implementation
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -32,35 +32,36 @@
* @param cmp pointer compare function * @param cmp pointer compare function
* @param del pointer to delete function which is called when an element will be deletet * @param del pointer to delete function which is called when an element will be deletet
* @return pointer to an #avltree struct * @return pointer to an #avltree struct
*/ */
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*)) struct avltree *avltree_create(int (*cmp) (const void *, const void *),
void (*del) (void *))
{ {
struct avltree * t = malloc(sizeof(struct avltree)); struct avltree *t = malloc(sizeof(struct avltree));
if (!t) if (!t)
return NULL; return NULL;
t->root=0; t->root = 0;
t->count=0; t->count = 0;
t->cmp=cmp; t->cmp = cmp;
t->del=del; t->del = del;
return t; return t;
} }
struct avlnode * avlnode_create(void * data) struct avlnode *avlnode_create(void *data)
{ {
struct avlnode * n = malloc(sizeof(struct avlnode)); struct avlnode *n = malloc(sizeof(struct avlnode));
if(!n) if (!n)
return NULL; return NULL;
n->left=n->right=0; n->left = n->right = 0;
n->bal=0; n->bal = 0;
n->data = data; n->data = data;
return n; return n;
} }
void avlnode_destroy(struct avltree *t,struct avlnode *n) void avlnode_destroy(struct avltree *t, struct avlnode *n)
{ {
if(t->del){ if (t->del) {
t->del(n->data); t->del(n->data);
} }
free(n); free(n);
@ -68,66 +69,62 @@ void avlnode_destroy(struct avltree *t,struct avlnode *n)
} }
static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** data) static int avltree_add0(struct avltree *t, struct avlnode **parent, void **data)
{ {
// struct avlnode * rn; // struct avlnode * rn;
struct avlnode *tmp; struct avlnode *tmp;
struct avlnode * n = *parent; struct avlnode *n = *parent;
int rc=t->cmp(*data,n->data); int rc = t->cmp(*data, n->data);
int bal; int bal;
if (rc==0){ if (rc == 0) {
*data=n->data; *data = n->data;
return 2; return 2;
} }
if (rc<0){ if (rc < 0) {
if (n->left) if (n->left) {
{ bal = avltree_add0(t, &n->left, data);
bal = avltree_add0(t,&n->left,data); if (bal > 1)
if (bal>1)
return bal; return bal;
n->bal -=bal; n->bal -= bal;
if (n->bal==0) if (n->bal == 0)
return 0; return 0;
if (n->bal==-2){ if (n->bal == -2) {
if (n->left->bal==-1){ if (n->left->bal == -1) {
n->bal=0; n->bal = 0;
n->left->bal=0; n->left->bal = 0;
*parent=n->left; *parent = n->left;
tmp=n->left->right; tmp = n->left->right;
n->left->right=n; n->left->right = n;
n->left=tmp; n->left = tmp;
return 0; return 0;
} }
if (n->left->bal==1){ if (n->left->bal == 1) {
*parent=n->left->right; *parent = n->left->right;
if ((*parent)->bal==1) { if ((*parent)->bal == 1) {
n->bal=0; n->bal = 0;
n->left->bal=-1; n->left->bal = -1;
} } else if ((*parent)->bal == -1) {
else if ((*parent)->bal==-1){ n->bal = 1;
n->bal=1; n->left->bal = 0;
n->left->bal=0; } else {
} n->bal = 0;
else{ n->left->bal = 0;
n->bal=0;
n->left->bal=0;
} }
(*parent)->bal=0; (*parent)->bal = 0;
n->left->right=(*parent)->left; n->left->right = (*parent)->left;
(*parent)->left=n->left; (*parent)->left = n->left;
tmp = (*parent)->right; tmp = (*parent)->right;
(*parent)->right=n; (*parent)->right = n;
n->left=tmp; n->left = tmp;
return 0; return 0;
} }
//printf("!!!!left bal = %i\n",n->left->bal); //printf("!!!!left bal = %i\n",n->left->bal);
//exit(0); //exit(0);
@ -137,67 +134,63 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
} }
/* n->left is 0 */ /* n->left is 0 */
n->left=avlnode_create(*data); n->left = avlnode_create(*data);
if (!n->left) if (!n->left)
return 3; return 3;
t->count++; t->count++;
if(n->right==0){ if (n->right == 0) {
n->bal=-1; n->bal = -1;
return 1; return 1;
} }
n->bal=0; n->bal = 0;
return 0; return 0;
} } else {
else{ if (n->right) {
if (n->right){ bal = avltree_add0(t, &n->right, data);
bal = avltree_add0(t,&n->right,data); if (bal > 1)
if(bal>1)
return bal; return bal;
n->bal+=bal; n->bal += bal;
if (n->bal==0) if (n->bal == 0)
return 0; return 0;
if (n->bal==2){ if (n->bal == 2) {
if (n->right->bal==1){ if (n->right->bal == 1) {
n->bal=0; n->bal = 0;
n->right->bal=0; n->right->bal = 0;
*parent=n->right; *parent = n->right;
tmp=n->right->left; tmp = n->right->left;
n->right->left=n; n->right->left = n;
n->right=tmp; n->right = tmp;
return 0; return 0;
} } else if (n->right->bal == -1) {
else if(n->right->bal==-1){ *parent = n->right->left;
*parent=n->right->left;
if ((*parent)->bal==-1) { if ((*parent)->bal == -1) {
n->bal=0; n->bal = 0;
n->right->bal=1; n->right->bal = 1;
} } else if ((*parent)->bal == 1) {
else if ((*parent)->bal==1){ n->bal = -1;
n->bal=-1; n->right->bal = 0;
n->right->bal=0; } else {
} n->bal = 0;
else{ n->right->bal = 0;
n->bal=0;
n->right->bal=0;
} }
(*parent)->bal=0; (*parent)->bal = 0;
n->right->left=(*parent)->right; n->right->left = (*parent)->right;
(*parent)->right=n->right; (*parent)->right = n->right;
tmp = (*parent)->left; tmp = (*parent)->left;
(*parent)->left=n; (*parent)->left = n;
n->right=tmp; n->right = tmp;
return 0; return 0;
} }
//printf("!!!!iright bal = %i\n",n->left->bal); //printf("!!!!iright bal = %i\n",n->left->bal);
@ -211,16 +204,16 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
/* n->right is 0 */ /* n->right is 0 */
n->right=avlnode_create(*data); n->right = avlnode_create(*data);
if (!n->right) if (!n->right)
return 3; return 3;
t->count++; t->count++;
if(n->left==0){ if (n->left == 0) {
n->bal=1; n->bal = 1;
return 1; return 1;
} }
n->bal=0; n->bal = 0;
return 0; return 0;
} }
} }
@ -232,18 +225,18 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
* @data pointer to element * @data pointer to element
* @return added alement or NULL if error. * @return added alement or NULL if error.
*/ */
void * avltree_add(struct avltree *t, void * data) void *avltree_add(struct avltree *t, void *data)
{ {
if (t->root==0){ if (t->root == 0) {
t->root = avlnode_create(data); t->root = avlnode_create(data);
if (t->root) if (t->root)
t->count++; t->count++;
return t->root->data; return t->root->data;
} }
void * d = data; void *d = data;
int rc = avltree_add0(t,&t->root,&d); int rc = avltree_add0(t, &t->root, &d);
if (rc>3) if (rc > 3)
return NULL; return NULL;
return d; return d;
@ -252,21 +245,21 @@ void * avltree_add(struct avltree *t, void * data)
static void rot_l(struct avlnode *n, struct avlnode **parent) static void rot_l(struct avlnode *n, struct avlnode **parent)
{ {
struct avlnode *tmp; struct avlnode *tmp;
*parent=n->right; *parent = n->right;
tmp=n->right->left; tmp = n->right->left;
n->right->left=n; n->right->left = n;
n->right=tmp; n->right = tmp;
} }
static void rot_r(struct avlnode *n, struct avlnode **parent) static void rot_r(struct avlnode *n, struct avlnode **parent)
{ {
struct avlnode *tmp; struct avlnode *tmp;
*parent=n->left; *parent = n->left;
tmp=n->left->right; tmp = n->left->right;
n->left->right=n; n->left->right = n;
n->left=tmp; n->left = tmp;
} }
@ -308,84 +301,79 @@ static int avltree_delete_hi(struct avlnode **parent, void **data)
static void rot_rl(struct avlnode *n, struct avlnode **parent) static void rot_rl(struct avlnode *n, struct avlnode **parent)
{ {
struct avlnode * tmp; struct avlnode *tmp;
*parent=n->right->left; *parent = n->right->left;
n->right->left=(*parent)->right; n->right->left = (*parent)->right;
(*parent)->right=n->right; (*parent)->right = n->right;
tmp = (*parent)->left; tmp = (*parent)->left;
(*parent)->left=n; (*parent)->left = n;
n->right=tmp; n->right = tmp;
} }
static void rot_lr(struct avlnode *n, struct avlnode **parent) static void rot_lr(struct avlnode *n, struct avlnode **parent)
{ {
struct avlnode * tmp; struct avlnode *tmp;
*parent=n->left->right; *parent = n->left->right;
n->left->right=(*parent)->left; n->left->right = (*parent)->left;
(*parent)->left=n->left; (*parent)->left = n->left;
tmp = (*parent)->right; tmp = (*parent)->right;
(*parent)->right=n; (*parent)->right = n;
n->left=tmp; n->left = tmp;
} }
static int adj_bal_l(struct avlnode *n, struct avlnode **parent) static int adj_bal_l(struct avlnode *n, struct avlnode **parent)
{ {
if (n->right->bal==1){ if (n->right->bal == 1) {
n->bal=0; n->bal = 0;
n->right->bal=0; n->right->bal = 0;
rot_l(n,parent); rot_l(n, parent);
return 1; return 1;
} } else if (n->right->bal == 0) {
else if(n->right->bal==0){ n->bal = 1;
n->bal=1; n->right->bal = -1;
n->right->bal=-1; rot_l(n, parent);
rot_l(n,parent);
return 0; return 0;
}else if(n->right->bal==-1){ } else if (n->right->bal == -1) {
// int rb; // int rb;
n->bal=0; n->bal = 0;
n->right->bal=0; n->right->bal = 0;
// rb = n->right->left->bal; // rb = n->right->left->bal;
n->right->left->bal=0; n->right->left->bal = 0;
rot_rl(n,parent); rot_rl(n, parent);
return 1; return 1;
} }
// printf("adj bal l not handled \n");
// exit(0);
// printf("adj bal l not handled \n"); return -11; /* that should never happen */
// exit(0);
return -11; /* that should never happen */
} }
int adj_bal_r(struct avlnode *n, struct avlnode **parent) int adj_bal_r(struct avlnode *n, struct avlnode **parent)
{ {
if (n->left->bal==-1){ if (n->left->bal == -1) {
n->bal=0; n->bal = 0;
n->left->bal=0; n->left->bal = 0;
rot_r(n,parent); rot_r(n, parent);
return 1; return 1;
} } else if (n->left->bal == 0) {
else if(n->left->bal==0){ n->bal = -1;
n->bal=-1; n->left->bal = 1;
n->left->bal=1; rot_r(n, parent);
rot_r(n,parent);
return 0; return 0;
} } else if (n->left->bal == 1) {
else if(n->left->bal==1){ // int rb;
// int rb; n->bal = 0;
n->bal=0; n->left->bal = 0;
n->left->bal=0; // rb = n->left->right->bal;
// rb = n->left->right->bal; n->left->right->bal = 0;
n->left->right->bal=0; rot_lr(n, parent);
rot_lr(n,parent);
return 1; return 1;
} }
// printf("adj bal li left not handled \n");
// printf("adj bal li left not handled \n"); // exit(0);
// exit(0); return -11; /* that should never happen */
return -11; /* that should never happen */
} }
@ -393,29 +381,29 @@ int adj_bal_r(struct avlnode *n, struct avlnode **parent)
static int avltree_del_lo(struct avlnode **parent, void **data) static int avltree_del_lo(struct avlnode **parent, void **data)
{ {
struct avlnode * n = *parent; struct avlnode *n = *parent;
if(n->left!=0){ if (n->left != 0) {
int bal = avltree_del_lo(&n->left,data); int bal = avltree_del_lo(&n->left, data);
n->bal+=bal; n->bal += bal;
if (n->bal==1){ if (n->bal == 1) {
return 0; return 0;
} }
if (n->bal!=2) if (n->bal != 2)
return bal; return bal;
adj_bal_l(n,parent); adj_bal_l(n, parent);
return 0; return 0;
} }
/* found the lowest element */ /* found the lowest element */
*parent=n->right; *parent = n->right;
*data = n->data; *data = n->data;
free (n); free(n);
return 1; return 1;
if (n->right){ if (n->right) {
free(n); free(n);
return 1; return 1;
} }
@ -429,98 +417,98 @@ static int avltree_del_lo(struct avlnode **parent, void **data)
int avltree_del0(struct avltree *t, struct avlnode **parent, void **data) int avltree_del0(struct avltree *t, struct avlnode **parent, void **data)
{ {
struct avlnode * n = *parent; struct avlnode *n = *parent;
int rc; int rc;
int bal; int bal;
rc = t->cmp(*data, n->data);
rc =t->cmp(*data,n->data); if (rc == 0) {
if (n->right == 0 && n->left == 0) {
if (rc==0){ *parent = 0;
if (n->right == 0 && n->left ==0){ avlnode_destroy(t, n);
*parent=0;
avlnode_destroy(t,n);
return 1; return 1;
} }
if (n->right && n->left==0){ if (n->right && n->left == 0) {
*parent=n->right; *parent = n->right;
avlnode_destroy(t,n); avlnode_destroy(t, n);
return 1; return 1;
} }
if (n->left && n->right==0){ if (n->left && n->right == 0) {
avlnode_destroy(t,n); avlnode_destroy(t, n);
*parent=n->left; *parent = n->left;
return 1; return 1;
} }
/* node has two childs */ /* node has two childs */
if (t->del){ if (t->del) {
t->del(n->data); t->del(n->data);
} }
t->count--; t->count--;
bal = avltree_del_lo(&n->right,&n->data); bal = avltree_del_lo(&n->right, &n->data);
n->bal-= bal; n->bal -= bal;
if (n->bal==-1) if (n->bal == -1)
return 0; return 0;
if (n->bal != -2) if (n->bal != -2)
return bal; return bal;
return adj_bal_r(n,parent); return adj_bal_r(n, parent);
} }
if (rc<0){ if (rc < 0) {
if (n->left) if (n->left) {
{ bal = avltree_del0(t, &n->left, data);
bal = avltree_del0(t,&n->left,data); if (bal == 2)
if (bal==2)
return 2; return 2;
n->bal+=bal; n->bal += bal;
if (n->bal==1) if (n->bal == 1)
return 0; return 0;
if (n->bal!=2) if (n->bal != 2)
return bal; return bal;
return adj_bal_l(n,parent); return adj_bal_l(n, parent);
} }
return 2; /* not found */ return 2; /* not found */
} } else { /* rc must be > 0 */
else { /* rc must be > 0 */ if (n->right) {
if (n->right){ bal = avltree_del0(t, &n->right, data);
bal = avltree_del0(t,&n->right,data); if (bal == 2)
if (bal==2)
return 2; return 2;
n->bal-=bal; n->bal -= bal;
if (n->bal==-1) if (n->bal == -1)
return 0; return 0;
if (n->bal != -2) if (n->bal != -2)
return bal; return bal;
return adj_bal_r(n,parent); return adj_bal_r(n, parent);
} }
return 2; /* not found */ return 2; /* not found */
} }
} }
void * avltree_del(struct avltree *t, void *data) void *avltree_del(struct avltree *t, void *data)
{ {
if (!t->root)
return NULL;
void *d = data; void *d = data;
int rc = avltree_del0(t,&t->root,&d); int rc = avltree_del0(t, &t->root, &d);
if (rc==2) if (rc == 2)
return 0; return NULL;
return data; return data;
} }
@ -609,11 +597,13 @@ void walk(struct avlnode *n)
*/ */
/*
void avltree_destroy(struct avltree *t) void avltree_destroy(struct avltree *t)
{ {
avltree_del_all(t); avltree_del_all(t);
free (t); free (t);
} }
*/
//#include <time.h> //#include <time.h>

View File

@ -16,65 +16,81 @@
*/ */
/* /**
* yet another avl tree implementation! * @file
* @brief Yet another avl tree implementation!
*/ */
#ifndef __AVLTREE_H #ifndef __AVLTREE_H
#define __AVLTREE_H #define __AVLTREE_H
#include <string.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
struct avlnode{
void * data; struct avlnode {
struct avlnode * left; void *data;
struct avlnode * right; struct avlnode *left;
struct avlnode *right;
int bal; int bal;
}; };
struct avltree{ struct avltree {
struct avlnode * root; struct avlnode *root;
int (*cmp)(const void*,const void*); int (*cmp) (const void *, const void *);
void(*del)(void*); void (*del) (void *);
int count; int count;
}; };
void avlnode_destroy(struct avltree *t,struct avlnode *n); void avlnode_destroy(struct avltree *t, struct avlnode *n);
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*)); struct avltree *avltree_create(int (*cmp) (const void *, const void *),
void avltree_destroy(struct avltree *t); void (*del) (void *));
//void avltree_destroy(struct avltree *t);
void avltree_del_all(struct avltree *t); void avltree_del_all(struct avltree *t);
void * avltree_del(struct avltree *t, void *data); void *avltree_del(struct avltree *t, void *data);
void * avltree_add(struct avltree *t, void *data); void *avltree_add(struct avltree *t, void *data);
//void * avltree_get(struct avltree *t ,void *data); //void * avltree_get(struct avltree *t ,void *data);
struct avlnode * avltree_get_node(struct avltree *t ,void *data); struct avlnode *avltree_get_node(struct avltree *t, void *data);
extern int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv); extern int avltree_foreach_lr(struct avlnode *n, int (*callback) (void *, void *),
extern int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv); void *cbpriv);
int avltree_foreach_from_lr(struct avltree *t, struct avlnode *n, void *data,int (*callback)(void *,void *),void *cbpriv); extern int avltree_foreach_rl(struct avlnode *n, int (*callback) (void *, void *),
void *cbpriv);
int avltree_foreach_from_lr(struct avltree *t, struct avlnode *n, void *data,
int (*callback) (void *, void *), void *cbpriv);
//extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir); //extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir);
static inline void * avltree_get(struct avltree *t ,void *data){ static inline void *avltree_get(struct avltree *t, void *data)
struct avlnode * n = avltree_get_node(t,data); {
struct avlnode *n = avltree_get_node(t, data);
if (!n) if (!n)
return NULL; return NULL;
return n->data; return n->data;
} }
static inline void * avltree_replace_data(struct avltree *t ,void *data,int len) { static inline void *avltree_replace_data(struct avltree *t, void *data, int len)
void * df = avltree_get(t,data); {
if(!df) void *df = avltree_get(t, data);
if (!df)
return NULL; return NULL;
memcpy(df,data,len); memcpy(df, data, len);
return df; return df;
} }
static inline void avltree_destroy(struct avltree *t)
{
avltree_del_all(t);
free (t);
}
#define avltree_find(t,d) avltree_get(t,d) #define avltree_find(t,d) avltree_get(t,d)
#define avltree_insert(t,d) avltree_add(t,d) #define avltree_insert(t,d) avltree_add(t,d)
//#define avltree_walk(t,dir) avltree_foreach(t,dir) //#define avltree_walk(t,dir) avltree_foreach(t,dir)
@ -86,5 +102,3 @@ static inline void * avltree_replace_data(struct avltree *t ,void *data,int len)
#endif #endif

View File

@ -13,14 +13,22 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>. along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file
* @brief Implementation of avltree_get
*/
#include <stdio.h> #include <stdio.h>
#include "avltree.h" #include "avltree.h"
/**
* Get an AVL tree element.
* @param data Element to get
* @return pointer to element or NULL if not found.
*/
void * avltree_get(struct avltree *t ,void *data) void * avltree_get(struct avltree *t ,void *data)
{ {
struct avlnode *n = t->root; struct avlnode *n = t->root;

View File

@ -34,6 +34,7 @@
#include "conn.h" #include "conn.h"
#include "lwapp.h" #include "lwapp.h"
#include "strheap.h"
/* capwap version and iana number */ /* capwap version and iana number */
#define CW_VERSION 0 #define CW_VERSION 0
@ -83,6 +84,9 @@ enum capwap_states {
#define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */ #define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */
/**
* CAWAP header flags.
*/
#define CW_FLAG_HDR_R1 0x01 /* bit 0 reserved 1 */ #define CW_FLAG_HDR_R1 0x01 /* bit 0 reserved 1 */
#define CW_FLAG_HDR_R2 0x02 /* bit 1 reserved 2 */ #define CW_FLAG_HDR_R2 0x02 /* bit 1 reserved 2 */
#define CW_FLAG_HDR_R3 0x04 /* bit 2 reserved 3 */ #define CW_FLAG_HDR_R3 0x04 /* bit 2 reserved 3 */
@ -521,6 +525,9 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
#define cw_put_data lw_put_data #define cw_put_data lw_put_data
#define cw_put_bstr lw_put_bstr #define cw_put_bstr lw_put_bstr
#define cw_set_dword lw_set_dword
#define cw_get_byte lw_get_byte #define cw_get_byte lw_get_byte
#define cw_get_word lw_get_word #define cw_get_word lw_get_word
#define cw_get_dword lw_get_dword #define cw_get_dword lw_get_dword
@ -557,6 +564,36 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
#define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th)) #define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th))
#define cw_get_hdr_msg_elems_offset(th) (cw_get_hdr_msg_offset(th)+8) #define cw_get_hdr_msg_elems_offset(th) (cw_get_hdr_msg_offset(th)+8)
#define cw_set_hdr_preamble(th,v) ((*th)=v)
/**
* Set the HLEN field of a CAWAP Header
* @param th pointer to the header
* @param hlen velue to set (max. 5 bits)
*/
static inline void cw_set_hdr_hlen(uint8_t *th,int hlen){
uint32_t d = cw_get_dword(th);
d &= (0x1f << 19) ^ 0xffffffff;
d |= ((hlen) & 0x1f) <<19;
cw_set_dword(th,d);
}
/**
* Set CAPWAP header flags
* @param th pointer to header
* @param flags list of flags to set or unset
* @param set 1=set flag, 0=unset flag
*/
#define cw_set_hdr_flags(th,flags,set) \
( set ? ((*((uint32_t*)th)) |= htonl(flags)) : ((*((uint32_t*)th)) &= (0xffffffff^htonl(flags))) )
#define cw_set_hdr_flag_f(th,set) cw_set_hdr_flag(th, CW_FLAG_HDR_F)
/* Macros for message headers */
#define cw_get_msg_id(msgptr) (cw_get_dword(msgptr)) #define cw_get_msg_id(msgptr) (cw_get_dword(msgptr))
#define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr) #define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr)
@ -565,15 +602,6 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8) #define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
#define cw_set_hdr_preamble(th,v) ((*th)=v)
#define cw_set_hdr_flags(th,val,set) \
( set ? ((*((uint32_t*)th)) |= htonl(val)) : ((*((uint32_t*)th)) &= (0xffffffff^htonl(val))) )
#define cw_set_hdr_flag_f(th,set) cw_set_hdr_flag(th, CW_FLAG_HDR_F)
#define cw_set_msg_id(msgptr,t) cw_put_dword(msgptr,t) #define cw_set_msg_id(msgptr,t) cw_put_dword(msgptr,t)
#define cw_set_msg_type(msgptr,t) cw_set_msg_id(msgptr,t) #define cw_set_msg_type(msgptr,t) cw_set_msg_id(msgptr,t)
#define cw_set_msg_seqnum(msgptr,s) cw_put_byte( (msgptr) +4,s); #define cw_set_msg_seqnum(msgptr,s) cw_put_byte( (msgptr) +4,s);
@ -606,14 +634,14 @@ static inline int cw_get_hdr_msg_total_len(uint8_t * rawmsg)
* @pram e pointer to element (uint8_t*) * @pram e pointer to element (uint8_t*)
* @return type of element * @return type of element
*/ */
#define cw_get_elem_len(e) cw_get_word(e+2) #define cw_get_elem_len(e) cw_get_word((e)+2)
/** /**
* Get a pointer to the data of a CAPWAP message element * Get a pointer to the data of a CAPWAP message element
* @param e pointer to message element * @param e pointer to message element
* @return pointer to data * @return pointer to data
*/ */
#define cw_get_elem_data(e) (e+4) #define cw_get_elem_data(e) ((e)+4)
/** /**
* Iterate through message elements of a CAPWAP message * Iterate through message elements of a CAPWAP message
@ -770,19 +798,11 @@ extern int cw_send_configuration_update_response(struct conn *conn, int seqnum,
/* Message to text stuff */ /* Message to text stuff */
struct cw_strlist {
uint32_t id;
const char *str;
};
extern const char *cw_strlist_get_str(struct cw_strlist *s, int id);
/* Constants to string conversion lists */ /* Constants to string conversion lists */
extern struct cw_strlist capwap_strings_msg[]; extern struct cw_str capwap_strings_msg[];
extern struct cw_strlist capwap_strings_state[]; extern struct cw_str capwap_strings_state[];
extern struct cw_strlist capwap_strings_vendor[]; extern struct cw_str capwap_strings_vendor[];
extern struct cw_strlist capwap_strings_elem[]; extern struct cw_str capwap_strings_elem[];
#define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id) #define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id)
@ -791,6 +811,13 @@ extern struct cw_strlist capwap_strings_elem[];
#define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,id) #define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,id)
#define cw_strelemp(p,id) cw_strheap_get((p)->strelem,id)
extern const char *cw_strlist_get_str(struct cw_str *s, int id);
int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len); int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len);
@ -806,13 +833,18 @@ extern int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8
int len); int len);
//extern int cw_out_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len); //extern int cw_out_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
extern int cw_out_generic(struct conn *conn, uint32_t elem_id, uint8_t * dst, extern int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst); //, struct cw_item *item);
struct cw_item *item);
extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
struct cw_item *item);
extern int cw_out_capwap_control_ip_addrs(struct conn *conn, uint32_t elem_id,
uint8_t * dst, struct cw_item *item);
//extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
//struct cw_item *item);
extern int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst); //,struct cw_item * item)
//extern int cw_out_capwap_control_ip_addrs(struct conn *conn, uint32_t elem_id,
// uint8_t * dst, struct cw_item *item);
extern int cw_out_capwap_control_ip_addrs(struct conn *conn,struct cw_action_out *a,uint8_t *dst) ;
extern int cw_put_msg(struct conn *conn, uint8_t * rawout);
struct cw_ac_status { struct cw_ac_status {
@ -825,9 +857,42 @@ struct cw_ac_status {
int dtls_policy; int dtls_policy;
}; };
/**
* Put an cw_ac_stauts structure to a buffer
* @param dst destination buffer
* @param s #cw_ac_status to put
* @return number of bytes put
* This function is only useful (used) in conjunction with
* putting AC Descriptor message elements.
*/
static inline int cw_put_ac_status(uint8_t *dst, struct cw_ac_status *s){
uint8_t *d=dst;
d += cw_put_dword (d, (s->stations << 16) | (s->limit) );
d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) );
d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy));
return d-dst;
}
static inline int cw_put_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
{
uint8_t *d=dst;
d += cw_put_dword(d,vendor_id);
d += cw_put_dword(d, (subelem_id<<16) | bstr16_len(data));
d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
return d-dst;
}
int cw_register_actions_capwap_ac(struct cw_actiondef *def); int cw_register_actions_capwap_ac(struct cw_actiondef *def);
int cw_register_actions_cipwap_ac(struct cw_actiondef *def); int cw_register_actions_cipwap_ac(struct cw_actiondef *def);
int cw_in_set_state_none(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
struct cw_item *cw_out_get_local(struct conn *conn, struct cw_action_out *a);
#endif #endif

View File

@ -61,7 +61,7 @@
CW_ITEM_WTP_MAC_TYPE, /* ID to use store */ \ CW_ITEM_WTP_MAC_TYPE, /* ID to use store */ \
1, 1 /* min/max length */ 1, 1 /* min/max length */
#define CW_ACTION_VENDOR_SPECIFIC_PAYLOAD \ #define CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD \
CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, /* Element ID */ \ CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, /* Element ID */ \
cw_in_vendor_specific_payload, 0 /* start/end callback*/ \ cw_in_vendor_specific_payload, 0 /* start/end callback*/ \

View File

@ -21,13 +21,7 @@
#include "action.h" #include "action.h"
#include "capwap_items.h" #include "capwap_items.h"
#include "capwap_actions.h" #include "capwap_actions.h"
#include "strheap.h"
int cw_in_set_state_none(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len)
{
conn->capwap_state=CW_STATE_NONE;
return 1;
}
@ -58,8 +52,7 @@ cw_action_in_t capwap_actions_ac_in[] = {
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE} {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
, ,
/* Vendor Specific Payload */ /* Vendor Specific Payload */
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD}
cw_in_vendor_specific_payload, 0}
, ,
/* -------------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------------*/
@ -90,6 +83,9 @@ cw_action_in_t capwap_actions_ac_in[] = {
/* Element WTP MAC Type */ /* Element WTP MAC Type */
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE} {0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
, ,
/* Element Vendor Specific Payload */
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD}
,
@ -121,6 +117,7 @@ cw_action_in_t capwap_actions_ac_in[] = {
}; };
/*
int cw_out_ac_name(uint8_t * dst, struct cw_item *item) int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
{ {
@ -130,13 +127,8 @@ int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
int len = cw_put_data(dst + 4, data, strlen((char *) data)); int len = cw_put_data(dst + 4, data, strlen((char *) data));
return len + cw_put_elem_hdr(dst, CW_ELEM_AC_NAME, len); return len + cw_put_elem_hdr(dst, CW_ELEM_AC_NAME, len);
} }
*/
struct cw_item *cw_get_local(struct conn *conn, uint32_t item_id)
{
struct cw_item i;
i.id = item_id;
return cw_itemstore_get(conn->local, item_id);
}
@ -145,26 +137,38 @@ cw_action_out_t capwap_actions_ac_out[] = {
, ,
/* AC Descriptor */ /* AC Descriptor */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0
CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0} ,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
, ,
/* AC Name */ /* AC Name */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME, {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME, 0,
CW_ELEM_AC_NAME, cw_out_generic, cw_get_local} CW_ELEM_AC_NAME, cw_out_generic, cw_out_get_local}
, ,
/* List of CAPWAP Control IPv4 and IPv6 addresses */ /* List of CAPWAP Control IPv4 and IPv6 addresses */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST, {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST, 0,
0, cw_out_capwap_control_ip_addrs, cw_get_local} 0, cw_out_capwap_control_ip_addrs, cw_out_get_local}
, ,
/* -------------------------------------------------------------------------------
* Join Response OUT
*/
{CW_MSG_JOIN_RESPONSE, CW_ITEM_NONE}
,
/* Result Code */
{CW_MSG_JOIN_RESPONSE, CW_ITEM_RESULT_CODE, 0,
CW_ELEM_RESULT_CODE, cw_out_generic, cw_out_get_local}
,
/* AC Descriptor */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0
,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
,
{CW_MSG_JOIN_RESPONSE, CW_ITEM_AC_NAME}
,
{CW_MSG_JOIN_RESPONSE, CW_ITEM_RESULT_CODE}
,
{0, 0} {0, 0}
@ -180,9 +184,18 @@ int cw_register_actions_capwap_ac(struct cw_actiondef *def)
{ {
def->in = cw_actionlist_in_create(); def->in = cw_actionlist_in_create();
def->out = cw_actionlist_out_create(); def->out = cw_actionlist_out_create();
def->strmsg = cw_strheap_create();
def->strelem = cw_strheap_create();
cw_actionlist_in_register_actions(def->in, capwap_actions_ac_in); cw_actionlist_in_register_actions(def->in, capwap_actions_ac_in);
cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out); cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out);
int rc ;
rc = cw_strheap_register_strings(def->strmsg,capwap_strings_msg);
rc += cw_strheap_register_strings(def->strelem,capwap_strings_elem);
printf("Registered %d strings\n",rc);
return 1; return 1;
} }

View File

@ -46,6 +46,7 @@
#define CW_CISCO_DIRECT_SEQUENCE_CONTROL LW_ELEM_DIRECT_SEQUENCE_CONTROL /* 14 */ #define CW_CISCO_DIRECT_SEQUENCE_CONTROL LW_ELEM_DIRECT_SEQUENCE_CONTROL /* 14 */
#define CW_CISCO_SUPPORTED_RATES LW_ELEM_80211_RATE_SET /* 16 */ #define CW_CISCO_SUPPORTED_RATES LW_ELEM_80211_RATE_SET /* 16 */
#define CW_CISCO_MWAR_NAME LW_ELEM_AC_NAME /* 31 */
#define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */ #define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */
#define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */ #define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */
@ -92,15 +93,20 @@
* @param dst destination buffer * @param dst destination buffer
* @param time a unix timestamp * @param time a unix timestamp
* @param type of time * @param type of time
* @return number of bytes put (15) * @return number of bytes put (5)
*/ */
static inline int cw_addelem_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type) static inline int cw_put_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type)
{ {
cw_put_dword(dst + 10, time); cw_put_dword(dst , time);
cw_put_byte(dst + 14, type); cw_put_byte(dst + 4, type);
return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_TIMESYNC, 5); return 5;
} }
int cw_out_cisco_ap_timesync(struct conn *conn,struct cw_action_out * a,uint8_t *dst);
/** /**
* Add a Cisco RAD Name message element to buffer * Add a Cisco RAD Name message element to buffer
* @param dst destination buffer * @param dst destination buffer
@ -184,6 +190,8 @@ extern const char * cw_cisco_id_to_str(int elem_id);
int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct radioinfo *ri); int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct radioinfo *ri);
int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri); int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri);
extern int cw_out_cisco_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) ;
/* /*

View File

@ -37,7 +37,12 @@ enum capwap_items {
CW_ITEM_LOCATION_DATA, CW_ITEM_LOCATION_DATA,
CW_ITEM_SESSION_ID, CW_ITEM_SESSION_ID,
CW_ITEM_AC_TIMESTAMP,
/* CIPWAP and Cisco */
CW_ITEM_WTP_GROUP_NAME
}; };

View File

@ -1,6 +1,6 @@
#include "capwap.h" #include "capwap.h"
struct cw_strlist capwap_strings_elem[] = { struct cw_str capwap_strings_elem[] = {
{CW_ELEM_AC_DESCRIPTOR, "AC Descriptor"}, {CW_ELEM_AC_DESCRIPTOR, "AC Descriptor"},
{CW_ELEM_AC_IPV4_LIST, "AC IPv4 List"}, {CW_ELEM_AC_IPV4_LIST, "AC IPv4 List"},
@ -55,12 +55,13 @@ struct cw_strlist capwap_strings_elem[] = {
{CW_ELEM_RESERVED_46, "Reserved 46"}, {CW_ELEM_RESERVED_46, "Reserved 46"},
{CW_ELEM_WTP_RADIO_STATISTICS, "WTP Radio Statistics"}, {CW_ELEM_WTP_RADIO_STATISTICS, "WTP Radio Statistics"},
{CWMSGELEM_WTP_REBOOT_STATISTICS, "WTP Reboot Statistics"}, {CWMSGELEM_WTP_REBOOT_STATISTICS, "WTP Reboot Statistics"},
{CW_ELEM_WTP_STATIC_IP_ADDRESS_INFORMATION, "WTP Static IP Address Information"} {CW_ELEM_WTP_STATIC_IP_ADDRESS_INFORMATION, "WTP Static IP Address Information"},
/* Cisco's CAPWAP definitions (CAPWAP draft 7) */ /* Cisco's CAPWAP definitions (CAPWAP draft 7) */
/* CW_ELEM_WTP_IPV4_IP_ADDRESS 42 /* CW_ELEM_WTP_IPV4_IP_ADDRESS 42
CW_ELEM_WTP_IPV6_IP_ADDRESS 43 CW_ELEM_WTP_IPV6_IP_ADDRESS 43
*/ */
{0,"Unknown Element"}
}; };

View File

@ -1,6 +1,6 @@
#include "capwap.h" #include "capwap.h"
struct cw_strlist capwap_strings_msg[] = { struct cw_str capwap_strings_msg[] = {
{ CW_MSG_DISCOVERY_REQUEST, "Discovery Request" }, { CW_MSG_DISCOVERY_REQUEST, "Discovery Request" },
{ CW_MSG_DISCOVERY_RESPONSE,"Discovery Response" }, { CW_MSG_DISCOVERY_RESPONSE,"Discovery Response" },
{ CW_MSG_JOIN_REQUEST, "Join Request"}, { CW_MSG_JOIN_REQUEST, "Join Request"},

View File

@ -1,8 +1,10 @@
#include "capwap.h" #include "capwap.h"
struct cw_strlist capwap_strings_state[] = { struct cw_str capwap_strings_state[] = {
{ CW_STATE_DISCOVERY, "Discovery" }, { CW_STATE_DISCOVERY, "Discovery" },
{ CW_STATE_JOIN,"Join" }, { CW_STATE_JOIN,"Join" },
{ CW_STATE_RUN,"Run" }, { CW_STATE_RUN,"Run" },
{ CW_STATE_CONFIGURE,"Configure" },
{ 0,"Undefined" } { 0,"Undefined" }
}; };

View File

@ -1,7 +1,7 @@
#include "capwap.h" #include "capwap.h"
struct cw_strlist capwap_strings_vendor[] = { struct cw_str capwap_strings_vendor[] = {
{ CW_VENDOR_ID_CISCO, "Cisco" }, { CW_VENDOR_ID_CISCO, "Cisco" },
{ CW_VENDOR_ID_ZYXEL, "Zyxel" }, { CW_VENDOR_ID_ZYXEL, "Zyxel" },
{ CW_VENDOR_ID_FSF, "FSF"} { CW_VENDOR_ID_FSF, "FSF"}

View File

@ -1,28 +1,71 @@
#include "capwap.h" #include "capwap.h"
#include "capwap_cisco.h"
#include "capwap_actions.h" #include "capwap_actions.h"
#include "cipwap.h"
/**
*@file
*brief CIPWAP Actions
*/
cw_action_in_t cipwap_actions_ac_in[] = { cw_action_in_t cipwap_actions_ac_in[] = {
/* Element Discovery Type */ /* -------------------------------------------------------------------------------
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE, * Discovery Request IN
cw_in_generic, 0, CW_ITEMTYPE_BYTE, CW_ITEM_DISCOVERY_TYPE, 4, 4} */
{CW_VENDOR_ID_CISCO, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME,
cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_NAME,1,512}
,
{CW_VENDOR_ID_CISCO, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_CISCO_AP_GROUP_NAME,
cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_GROUP_NAME,1,512}
,
{0,0,0}
}; };
extern struct cw_item *cw_get_local(struct conn *conn, struct cw_action_out *a);
cw_action_out_t cipwap_actions_ac_out[] = {
/* -------------------------------------------------------------------------------
* Discovery Response OUT
*/
/* AC Descriptor (Cisco) */
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0 ,
CW_ELEM_AC_DESCRIPTOR, cw_out_cisco_ac_descriptor, 0}
,
/* Cisco AP Timesync - Important to get the WTP a DTLS
connection stablished*/
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_TIMESTAMP, CW_VENDOR_ID_CISCO,
CW_CISCO_AP_TIMESYNC, cw_out_cisco_ap_timesync, 0}
,
{0,0,0}
};
/**
* Register CiPWAP actions
*/
int cw_register_actions_cipwap_ac(struct cw_actiondef *def) int cw_register_actions_cipwap_ac(struct cw_actiondef *def)
{ {
cw_register_actions_capwap_ac(def); cw_register_actions_capwap_ac(def);
cw_actionlist_in_register_actions(def->in, cipwap_actions_ac_in); cw_actionlist_in_register_actions(def->in, cipwap_actions_ac_in);
// cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out); cw_actionlist_out_register_actions(def->out, cipwap_actions_ac_out);
cw_strheap_register_strings(def->strelem,cipwap_strings_elem);
return 1; return 1;
} }

View File

@ -16,6 +16,10 @@
*/ */
/**
* @file
* @brief Connection object stuff
*/
#ifndef __CONN_H #ifndef __CONN_H
#define __CONN_H #define __CONN_H
@ -35,14 +39,18 @@
#include "itemstore.h" #include "itemstore.h"
/**
* Connection Object
*/
struct conn { struct conn {
int sock; int sock;
struct sockaddr_storage addr; struct sockaddr_storage addr;
int recv_timeout; int recv_timeout;
cw_itemstore_t itemstore; /** Basically used to store local conig data */
cw_itemstore_t local; cw_itemstore_t local;
/** used to maintain the remote config, an AC holds here the WTP config.
A WTP holds here data about it's AC */
cw_itemstore_t remote; cw_itemstore_t remote;

View File

@ -32,12 +32,15 @@ static int message_cb(void *p, uint8_t *rawmsg, int len)
} }
void conn_msg_processor(struct conn *conn) int conn_msg_processor(struct conn *conn)
{ {
uint8_t buf[2024]; uint8_t buf[2024];
int len = 2024; int len = 2024;
int n = conn->read(conn, buf, len); int n = conn->read(conn, buf, len);
if (n<0 )
return n;
if (n > 0) if (n > 0)
conn_process_packet(conn, buf, n, cw_process_msg, conn); conn_process_packet(conn, buf, n, cw_process_msg, conn);

View File

@ -1,5 +1,38 @@
#include "cw_log.h" #include "cw_log.h"
#include "capwap.h" #include "capwap.h"
#include "capwap_cisco.h"
#include "dbg.h"
static int cw_format_vendor(char *dst, uint32_t vendor_id, int elem_id, const uint8_t * elem_data)
{
switch (vendor_id) {
case CW_VENDOR_ID_CISCO:
{
sprintf(dst, "%d - %s", elem_id,
cw_cisco_id_to_str(elem_id));
/* dive into LWAPP vendor specific decoding */
/*
if (elem_id == CW_CISCO_SPAM_VENDOR_SPECIFIC) {
uint32_t lw_elem_id = lw_get_word(elem_data + 4 + 6);
char b[256];
sprintf(b, "\n\t LWAPP Cisco Specific: %d - %s",
lw_elem_id, lw_cisco_id_to_str(lw_elem_id));
strcat(dst, b);
}
*/
break;
}
}
return 0;
}
@ -7,7 +40,7 @@
* print debug info for message elements * print debug info for message elements
*/ */
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len) void cw_dbg_elem_(struct conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len)
{ {
if (!cw_dbg_is_level(DBG_ELEM)) if (!cw_dbg_is_level(DBG_ELEM))
return; return;
@ -20,26 +53,26 @@ void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len)
if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) { if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) {
uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf)); uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf));
int type = ntohs(*((uint16_t *) (msgbuf + 4))); int type = ntohs(*((uint16_t *) (msgbuf + 4)));
sprintf(vendorname, "%s/%s/%d",
(char *) cw_strelem(msgelem),
(char *) lw_vendor_id_to_str(vendor_id), type);
elemname = vendorname;
cw_format_vendor(vendor_details, vendor_id, type, msgbuf); cw_format_vendor(vendor_details, vendor_id, type, msgbuf);
sprintf(vendorname, "%s/%s/%s",
cw_strelemp(conn->actions,msgelem),
(char *) lw_vendor_id_to_str(vendor_id), vendor_details);
elemname = vendorname;
} else { } else {
elemname = cw_strelem(msgelem); elemname = cw_strelemp(conn->actions,msgelem);
} }
if (!cw_dbg_is_level(DBG_ELEM_DMP)) if (!cw_dbg_is_level(DBG_ELEM_DMP))
cw_dbg(DBG_ELEM, cw_dbg(DBG_ELEM,
"%s, CAWPAP element: %d (%s), len=%d%s", "%s, CAWPAP element: %d (%s), len=%d%s",
cw_strmsg(msg), msgelem, elemname, len, vendor_details); cw_strmsg(msg), msgelem, elemname, len, "");
else else
cw_dbg_dmp(DBG_ELEM, msgbuf, len, cw_dbg_dmp(DBG_ELEM, msgbuf, len,
"%s, CAPWAP element: %d (%s), len=%d%s\n\tDump ...", "%s, CAPWAP element: %d (%s), len=%d%s\n\tDump ...",
cw_strmsg(msg), msgelem, elemname, len, vendor_details); cw_strmsg(msg), msgelem, elemname, len, "");
} }

View File

@ -31,7 +31,7 @@ int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int le
return 0; return 0;
} }
cw_itemstore_set(conn->itemstore,a->item_id,a->itemtype,data,len); cw_itemstore_set(conn->remote,a->item_id,a->itemtype,data,len);
return 0; return 0;
} }

View File

@ -16,7 +16,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint
as.vendor_id = cw_get_dword(data); as.vendor_id = cw_get_dword(data);
as.elem_id = cw_get_word(data+4); as.elem_id = cw_get_word(data+4);
// printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id);
af = cw_actionlist_in_get(conn->actions->in,&as); af = cw_actionlist_in_get(conn->actions->in,&as);
@ -27,8 +26,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint
return 0; return 0;
} }
printf("Found\n");
if (af->start) { if (af->start) {
af->start(conn,af,data+6,len-6); af->start(conn,af,data+6,len-6);
} }

View File

@ -96,7 +96,7 @@ int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * da
return 1; return 1;
} }
cw_itemstore_t itemstore = conn->itemstore; cw_itemstore_t itemstore = conn->remote;
cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data)); cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data));
readsubelems_wtp_board_data(itemstore,data+4,len-4); readsubelems_wtp_board_data(itemstore,data+4,len-4);

View File

@ -34,7 +34,7 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, ui
if (len<6) if (len<6)
return -1; return -1;
cw_itemstore_t itemstore = conn->itemstore; cw_itemstore_t itemstore = conn->remote;
cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data)); cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data));
cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1)); cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1));

View File

@ -13,14 +13,21 @@ void cw_init(struct conn * conn, uint8_t *buffer, int type, int seqnum, struct r
void cw_init_response(struct conn * conn, uint8_t *req) void cw_init_response(struct conn * conn, uint8_t *req)
{ {
uint8_t *buffer=conn->resp_buffer; uint8_t *buffer=conn->resp_buffer;
int hbytes = cw_get_hdr_msg_offset(req); int shbytes = cw_get_hdr_msg_offset(req);
memcpy(buffer,req,hbytes); int dhbytes;
memcpy(buffer,req,shbytes);
cw_set_hdr_hlen(buffer,2);
cw_set_hdr_flags(buffer,CW_FLAG_HDR_M,1);
dhbytes = cw_get_hdr_msg_offset(buffer);
uint8_t * msgptr = req+hbytes; uint8_t * msgptr = req+shbytes;
uint8_t * dmsgptr = buffer+hbytes; uint8_t * dmsgptr = buffer+dhbytes;
cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1); cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1);
cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr)); cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr));

View File

@ -6,9 +6,9 @@
#include "capwap.h" #include "capwap.h"
/*
int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data) int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
{ {
printf("Vendor putter %d\n",vendor_id);
uint8_t *d=dst; uint8_t *d=dst;
d += cw_put_dword(d,vendor_id); d += cw_put_dword(d,vendor_id);
@ -16,10 +16,10 @@ printf("Vendor putter %d\n",vendor_id);
d += cw_put_data(d,bstr16_data(data),bstr16_len(data)); d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
return d-dst; return d-dst;
} }
*/
int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst)
int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
{ {
uint8_t *d = dst+4; uint8_t *d = dst+4;
@ -31,18 +31,14 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
return 0; return 0;
} }
struct cw_ac_status *s = (struct cw_ac_status*)(i->data); d+=cw_put_ac_status(d ,(struct cw_ac_status*)(i->data));
d += cw_put_dword (d, (s->stations << 16) | (s->limit) );
d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) );
d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy));
i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION); i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION);
if ( i ) { if ( i ) {
d += cw_put_subelem_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4); d += cw_put_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
} }
else { else {
cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set."); cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set.");
@ -52,7 +48,7 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION); i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION);
if ( i ) { if ( i ) {
d += cw_put_subelem_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4); d += cw_put_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
} }
else { else {
cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set."); cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set.");
@ -60,7 +56,7 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
int len = d-dst-4; int len = d-dst-4;
return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len); return len + cw_put_elem_hdr(dst,a->elem_id,len);
} }

View File

@ -41,8 +41,10 @@ static int put_ip(void *priv, void *data)
} }
int cw_out_capwap_control_ip_addrs(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item) int cw_out_capwap_control_ip_addrs(struct conn *conn,struct cw_action_out *a,uint8_t *dst)
{ {
struct cw_item * item = cw_itemstore_get(conn->local,a->item_id);
if ( !item ) { if ( !item ) {
cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found"); cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found");
return 0; return 0;

View File

@ -9,27 +9,50 @@ int cw_put_item(uint8_t *dst,struct cw_item*item)
{ {
switch (item->type){ switch (item->type){
case CW_ITEMTYPE_STR: case CW_ITEMTYPE_STR:
printf("Outing str %s\n",item->data);
return cw_put_data(dst,item->data,strlen( (char*)item->data)); return cw_put_data(dst,item->data,strlen( (char*)item->data));
case CW_ITEMTYPE_BYTE: case CW_ITEMTYPE_BYTE:
return cw_put_byte(dst,item->byte); return cw_put_byte(dst,item->byte);
case CW_ITEMTYPE_WORD: case CW_ITEMTYPE_WORD:
return cw_put_word(dst,item->word); return cw_put_word(dst,item->word);
case CW_ITEMTYPE_DWORD: case CW_ITEMTYPE_DWORD:
return cw_put_word(dst,item->dword); return cw_put_dword(dst,item->dword);
} }
return 0; return 0;
} }
int cw_out_generic(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item) int cw_out_generic(struct conn *conn,struct cw_action_out *a,uint8_t *dst) // ,struct cw_item * item)
{ {
/* Get the item to put */
struct cw_item *item=NULL;
if (a->get){
item = a->get (conn,a);
}
printf("Out generic item %p\n",item);
/* Size for msg elem header depends on
vendor specific payload */
int start = a->vendor_id ? 10:4;
int len; int len;
if ( !item ) if ( !item )
len=0; len=0;
else else{
len = cw_put_item(dst+4,item); printf("Putting it\n");
return len + cw_put_elem_hdr(dst,elem_id,len); printf("To put: %d %s\n",len,item->data);
len = cw_put_item(dst+start,item);
printf("Putted: %d %s\n",len,item->data);
}
if (a->vendor_id)
return len + cw_put_elem_vendor_hdr(dst,a->vendor_id,a->elem_id,len);
return len + cw_put_elem_hdr(dst,a->elem_id,len);
} }

View File

@ -12,174 +12,26 @@
#include "dbg.h" #include "dbg.h"
//int cw_out_msg(struct conn *conn, uint8_t * rawout);
int snd_cb(void *c, void *d)
{
struct conn *conn = (struct conn *) c;
struct cw_action_in *a = (struct cw_action_in *) d;
if (a->start) {
a->start(conn, a, conn->resp_buffer, 0);
}
return 1;
}
extern int cw_init_response(struct conn *conn, uint8_t * req);
struct priv {
struct conn *conn;
uint8_t *buffer;
uint32_t msg_id;
int len;
};
int cw_additems_cb(void *p, void *i)
{
struct priv *priv = (struct priv *) p;
struct cw_item *item = (struct cw_item *) i;
printf("Item: %d - %d \n", priv->msg_id, item->id);
cw_action_out_t as;
as.item_id = item->id;
as.msg_id = priv->msg_id;
cw_action_out_t *a = cw_actionlist_out_get(priv->conn->actions->out, &as);
if (!a) {
printf("No out action found for %d\n", item->id);
return 1;
}
printf("Out action found\n");
return 1;
}
/*
int cw_additems( struct conn *conn,cw_itemstore_t itemstore)
{
struct priv priv;
priv.msg_id=CW_MSG_DISCOVERY_RESPONSE;
priv.conn=conn;
avltree_foreach_asc(itemstore, cw_additems_cb,&priv);
}
*/
int cb(void *p, void *ain)
{
cw_action_out_t *a = (cw_action_out_t *) ain;
struct priv *priv = (struct priv *) p;
if (priv->msg_id != a->msg_id)
return 0;
if (!a->item_id)
return 1;
printf("Put Msg ID %d (%s) - %d\n", a->msg_id, cw_strmsg(a->msg_id), a->elem_id);
struct cw_item *item = NULL;
if (a->get)
item = a->get(priv->conn, a->item_id);
int l = 0;
uint8_t *buffer = priv->buffer + priv->len;
printf("Writing to %p\n", buffer);
if (a->out) {
l = a->out(priv->conn, a->elem_id, buffer, item);
printf("The length is %d\n", l);
}
printf("+++++++++++++++++++Adding %d to privlen\n", l);
priv->len += l;
printf("Priveln is now %d\n", priv->len);
return 1;
}
int conn_send_msg(struct conn *conn, uint8_t * rawmsg); int conn_send_msg(struct conn *conn, uint8_t * rawmsg);
int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len) int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len)
{ {
struct priv priv; // struct priv priv;
cw_init_response(conn, rawmsg); cw_init_response(conn, rawmsg);
uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg); // uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
cw_action_out_t as; // cw_action_out_t as;
as.msg_id = cw_get_msg_type(msgptr) + 1;
as.item_id = CW_ITEM_NONE;
priv.msg_id = as.msg_id;
priv.conn = conn;
priv.len = 0;
priv.buffer = cw_get_hdr_msg_elems_ptr(conn->resp_buffer);
int off = cw_get_hdr_msg_offset(conn->resp_buffer);
printf("Offset is %d\n", off);
avltree_foreach_from_asc(conn->actions->out, &as, cb, &priv);
uint8_t *smptr = conn->resp_buffer + cw_get_hdr_msg_offset(conn->resp_buffer);
printf("Send Type: %d\n", cw_get_msg_type(smptr));
printf("The total msgelems length is %d\n", priv.len); cw_put_msg(conn,conn->resp_buffer);
int offset = cw_get_hdr_msg_offset(conn->resp_buffer);
printf("Privlen = %d\n", priv.len);
cw_set_msg_elems_len(conn->resp_buffer + offset, priv.len);
int total = cw_get_hdr_msg_total_len(conn->resp_buffer);
printf("TOTAL lenz: %p %d\n", conn->resp_buffer, total);
conn_send_msg(conn, conn->resp_buffer); conn_send_msg(conn, conn->resp_buffer);
return 1;
return 0;
/*
printf("The repoinse finder\n");
struct cw_action_in as,*af;
uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg);
as.msg_id = cw_get_msg_id(msg_ptr)+1;
if (as.msg_id & 1)
return 0;
printf("Message ID = %d\n",as.msg_id);
as.elem_id=0;
as.vendor_id=0;
as.proto=1;
as.capwap_state=1;
//avltree_foreach_from_asc(conn->msgtr, &as,snd_cb,conn);
printf("BLA\n");
*/
} }
@ -248,7 +100,7 @@ int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len)
as.elem_id = cw_get_elem_id(elem); as.elem_id = cw_get_elem_id(elem);
int elem_len = cw_get_elem_len(elem); int elem_len = cw_get_elem_len(elem);
cw_dbg_elem(as.msg_id, as.elem_id, cw_get_elem_data(elem), elem_len); cw_dbg_elem(conn,as.msg_id, as.elem_id, cw_get_elem_data(elem), elem_len);
af = cw_actionlist_in_get(conn->actions->in, &as); af = cw_actionlist_in_get(conn->actions->in, &as);

View File

@ -1,6 +1,6 @@
#include "capwap.h" #include "capwap.h"
const char * cw_strlist_get_str(struct cw_strlist *s,int id) const char * cw_strlist_get_str(struct cw_str *s,int id)
{ {
while ( s->id!=0){ while ( s->id!=0){
if (s->id==id) if (s->id==id)

View File

@ -1,14 +1,14 @@
#ifndef __DBG_H #ifndef __DBG_H
#define __DBG_H #define __DBG_H
#include "conn.h"
void cw_dbg_elem_(struct conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len);
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len);
#ifdef WITH_CW_LOG_DEBUG #ifdef WITH_CW_LOG_DEBUG
#define cw_dbg_elem(msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(msgtype,msgelemtype,msgbuf,msglen) #define cw_dbg_elem(conn,msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(conn,msgtype,msgelemtype,msgbuf,msglen)
#else #else