diff --git a/doc/capwap_cisco.txt b/doc/capwap_cisco.txt index 0aed08d6..33f0edf3 100644 --- a/doc/capwap_cisco.txt +++ b/doc/capwap_cisco.txt @@ -198,7 +198,7 @@ AP = RAD = WTP | ResetBtnState | +-+-+-+-+-+-+-+-+ - Type: 128 for Cisco Rest Button State + Type: 128 for Cisco Reset Button State Length: 1 ResetBtnState: 1 = Enabeled diff --git a/src/ac/ac_main.c b/src/ac/ac_main.c index dafcb3f5..b5935890 100644 --- a/src/ac/ac_main.c +++ b/src/ac/ac_main.c @@ -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[]) { @@ -117,7 +123,19 @@ int main (int argc, const char * argv[]) 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(); /* diff --git a/src/ac/wtpman.c b/src/ac/wtpman.c index 4cf5899b..c610f712 100644 --- a/src/ac/wtpman.c +++ b/src/ac/wtpman.c @@ -353,6 +353,7 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti return cwrmsg; } + int conn_msg_processor(struct conn *conn); 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 cwrmsg * cwrmsg; - void conn_msg_processor(struct conn *conn); 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->actions = &capwap_actions; - wtpman->conn->itemstore = cw_itemstore_create(); wtpman->conn->local = ac_config; wtpman->conn->remote = cw_itemstore_create(); @@ -379,6 +378,12 @@ extern cw_actionlist_in_t the_tree; 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); return; @@ -594,16 +599,20 @@ wtpman->conn->capwap_state=CW_STATE_JOIN; wtpman->conn->capwap_state=CW_STATE_JOIN; wtpman->conn->actions = &capwap_actions; - wtpman->conn->itemstore = cw_itemstore_create(); +// wtpman->conn->itemstore = cw_itemstore_create(); wtpman->conn->local = ac_config; wtpman->conn->remote = cw_itemstore_create(); 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); diff --git a/src/capwap/Makefile b/src/capwap/Makefile index 99b183e4..eeab4a5f 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -169,12 +169,15 @@ CAPWAPOBJS= \ capwap_strings_elem.o \ itemstore.o \ cw_in_vendor_specific_payload.o \ - cw_in_wtp_name.o \ cw_in_wtp_board_data.o \ cw_out_generic.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_msgelemtostr.o \ #cwmsg_addelem_ctrl_ip_addrs.o \ @@ -265,6 +268,9 @@ CWACTION=action.o \ cw_in_generic.o \ cw_in_wtp_descriptor.o \ cipwap_actions_ac.o \ + cipwap_strings_elem.o \ + cw_put_msg.o \ + capwap_action_helpers.o \ diff --git a/src/capwap/action.c b/src/capwap/action.c index e1c417c2..673898a3 100644 --- a/src/capwap/action.c +++ b/src/capwap/action.c @@ -119,6 +119,10 @@ static int cw_action_out_cmp(const void *elem1,const void *elem2) if (r!=0) return r; + r = e1->vendor_id - e2->vendor_id; + if (r!=0) + return r; + return 0; } @@ -163,3 +167,6 @@ cw_action_out_t * cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_ } + + + diff --git a/src/capwap/action.h b/src/capwap/action.h index cdd40a86..51f9170d 100644 --- a/src/capwap/action.h +++ b/src/capwap/action.h @@ -25,6 +25,7 @@ #include "avltree.h" #include "conn.h" #include "itemstore.h" +#include "strheap.h" /* 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{ uint32_t msg_id; uint32_t item_id; - + uint32_t vendor_id; uint16_t elem_id; - int (*out)(struct conn * conn, uint32_t elem_id, uint8_t * dst ,struct cw_item * item); - struct cw_item *(*get)(struct conn *conn,uint32_t item_id); + int (*out)(struct conn * conn, struct cw_action_out *a, uint8_t * dst); + struct cw_item *(*get)(struct conn *conn,struct cw_action_out *a); + }; 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{ cw_actionlist_in_t in; cw_actionlist_out_t out; + + cw_strheap_t strmsg; + cw_strheap_t strelem; + }; diff --git a/src/capwap/avltree.c b/src/capwap/avltree.c index f6a1b4c5..77050f2c 100644 --- a/src/capwap/avltree.c +++ b/src/capwap/avltree.c @@ -19,7 +19,7 @@ /** * @file * @brief Yet another AVL tree implementation - */ + */ #include #include @@ -32,35 +32,36 @@ * @param cmp pointer compare function * @param del pointer to delete function which is called when an element will be deletet * @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) return NULL; - t->root=0; - t->count=0; - t->cmp=cmp; - t->del=del; + t->root = 0; + t->count = 0; + t->cmp = cmp; + t->del = del; return t; } -struct avlnode * avlnode_create(void * data) +struct avlnode *avlnode_create(void *data) { - struct avlnode * n = malloc(sizeof(struct avlnode)); - if(!n) + struct avlnode *n = malloc(sizeof(struct avlnode)); + if (!n) return NULL; - - n->left=n->right=0; - n->bal=0; + + n->left = n->right = 0; + n->bal = 0; n->data = data; 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); } 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 * n = *parent; - int rc=t->cmp(*data,n->data); + struct avlnode *n = *parent; + int rc = t->cmp(*data, n->data); - int bal; - if (rc==0){ - *data=n->data; + int bal; + if (rc == 0) { + *data = n->data; return 2; } - if (rc<0){ - if (n->left) - { - bal = avltree_add0(t,&n->left,data); - if (bal>1) + if (rc < 0) { + if (n->left) { + bal = avltree_add0(t, &n->left, data); + if (bal > 1) return bal; - n->bal -=bal; - if (n->bal==0) + n->bal -= bal; + if (n->bal == 0) return 0; - - if (n->bal==-2){ - if (n->left->bal==-1){ - n->bal=0; - n->left->bal=0; - *parent=n->left; - tmp=n->left->right; - n->left->right=n; - n->left=tmp; + + if (n->bal == -2) { + if (n->left->bal == -1) { + n->bal = 0; + n->left->bal = 0; + *parent = n->left; + tmp = n->left->right; + n->left->right = n; + n->left = tmp; return 0; } - if (n->left->bal==1){ - *parent=n->left->right; - if ((*parent)->bal==1) { - n->bal=0; - n->left->bal=-1; - } - else if ((*parent)->bal==-1){ - n->bal=1; - n->left->bal=0; - } - else{ - n->bal=0; - n->left->bal=0; + if (n->left->bal == 1) { + *parent = n->left->right; + if ((*parent)->bal == 1) { + n->bal = 0; + n->left->bal = -1; + } else if ((*parent)->bal == -1) { + n->bal = 1; + n->left->bal = 0; + } else { + n->bal = 0; + n->left->bal = 0; } - (*parent)->bal=0; - n->left->right=(*parent)->left; - (*parent)->left=n->left; + (*parent)->bal = 0; + n->left->right = (*parent)->left; + (*parent)->left = n->left; tmp = (*parent)->right; - (*parent)->right=n; - n->left=tmp; + (*parent)->right = n; + n->left = tmp; return 0; - } - + } //printf("!!!!left bal = %i\n",n->left->bal); //exit(0); @@ -137,67 +134,63 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da } /* n->left is 0 */ - n->left=avlnode_create(*data); + n->left = avlnode_create(*data); if (!n->left) return 3; t->count++; - if(n->right==0){ - n->bal=-1; + if (n->right == 0) { + n->bal = -1; return 1; } - n->bal=0; + n->bal = 0; return 0; - } - else{ - if (n->right){ - bal = avltree_add0(t,&n->right,data); - if(bal>1) + } else { + if (n->right) { + bal = avltree_add0(t, &n->right, data); + if (bal > 1) return bal; - n->bal+=bal; - if (n->bal==0) + n->bal += bal; + if (n->bal == 0) return 0; - if (n->bal==2){ - if (n->right->bal==1){ - n->bal=0; - n->right->bal=0; - *parent=n->right; - tmp=n->right->left; - n->right->left=n; - n->right=tmp; + if (n->bal == 2) { + if (n->right->bal == 1) { + n->bal = 0; + n->right->bal = 0; + *parent = n->right; + tmp = n->right->left; + n->right->left = n; + n->right = tmp; return 0; - } - else if(n->right->bal==-1){ - *parent=n->right->left; + } else if (n->right->bal == -1) { + *parent = n->right->left; - if ((*parent)->bal==-1) { - n->bal=0; - n->right->bal=1; - } - else if ((*parent)->bal==1){ - n->bal=-1; - n->right->bal=0; - } - else{ - n->bal=0; - n->right->bal=0; + if ((*parent)->bal == -1) { + n->bal = 0; + n->right->bal = 1; + } else if ((*parent)->bal == 1) { + n->bal = -1; + n->right->bal = 0; + } else { + n->bal = 0; + n->right->bal = 0; } - (*parent)->bal=0; - n->right->left=(*parent)->right; - (*parent)->right=n->right; + (*parent)->bal = 0; + n->right->left = (*parent)->right; + (*parent)->right = n->right; tmp = (*parent)->left; - (*parent)->left=n; - n->right=tmp; + (*parent)->left = n; + n->right = tmp; return 0; } //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=avlnode_create(*data); + n->right = avlnode_create(*data); if (!n->right) return 3; t->count++; - if(n->left==0){ - n->bal=1; + if (n->left == 0) { + n->bal = 1; return 1; } - n->bal=0; + n->bal = 0; return 0; } } @@ -232,18 +225,18 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da * @data pointer to element * @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); if (t->root) t->count++; return t->root->data; } - void * d = data; - int rc = avltree_add0(t,&t->root,&d); + void *d = data; + int rc = avltree_add0(t, &t->root, &d); - if (rc>3) + if (rc > 3) return NULL; return d; @@ -252,21 +245,21 @@ void * avltree_add(struct avltree *t, void * data) static void rot_l(struct avlnode *n, struct avlnode **parent) { struct avlnode *tmp; - *parent=n->right; - tmp=n->right->left; - n->right->left=n; - n->right=tmp; + *parent = n->right; + tmp = n->right->left; + n->right->left = n; + n->right = tmp; } static void rot_r(struct avlnode *n, struct avlnode **parent) { struct avlnode *tmp; - *parent=n->left; - tmp=n->left->right; - n->left->right=n; - n->left=tmp; -} + *parent = n->left; + tmp = n->left->right; + n->left->right = n; + 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) { - struct avlnode * tmp; - *parent=n->right->left; - n->right->left=(*parent)->right; - (*parent)->right=n->right; + struct avlnode *tmp; + *parent = n->right->left; + n->right->left = (*parent)->right; + (*parent)->right = n->right; tmp = (*parent)->left; - (*parent)->left=n; - n->right=tmp; + (*parent)->left = n; + n->right = tmp; } static void rot_lr(struct avlnode *n, struct avlnode **parent) { - struct avlnode * tmp; - *parent=n->left->right; - n->left->right=(*parent)->left; - (*parent)->left=n->left; + struct avlnode *tmp; + *parent = n->left->right; + n->left->right = (*parent)->left; + (*parent)->left = n->left; tmp = (*parent)->right; - (*parent)->right=n; - n->left=tmp; + (*parent)->right = n; + n->left = tmp; } static int adj_bal_l(struct avlnode *n, struct avlnode **parent) { - if (n->right->bal==1){ - n->bal=0; - n->right->bal=0; - rot_l(n,parent); + if (n->right->bal == 1) { + n->bal = 0; + n->right->bal = 0; + rot_l(n, parent); return 1; - } - else if(n->right->bal==0){ - n->bal=1; - n->right->bal=-1; - rot_l(n,parent); + } else if (n->right->bal == 0) { + n->bal = 1; + n->right->bal = -1; + rot_l(n, parent); return 0; - }else if(n->right->bal==-1){ -// int rb; - n->bal=0; - n->right->bal=0; -// rb = n->right->left->bal; - n->right->left->bal=0; - rot_rl(n,parent); + } else if (n->right->bal == -1) { +// int rb; + n->bal = 0; + n->right->bal = 0; +// rb = n->right->left->bal; + n->right->left->bal = 0; + rot_rl(n, parent); return 1; } +// printf("adj bal l not handled \n"); +// exit(0); -// printf("adj bal l not handled \n"); -// exit(0); - - return -11; /* that should never happen */ + return -11; /* that should never happen */ } int adj_bal_r(struct avlnode *n, struct avlnode **parent) { - if (n->left->bal==-1){ - n->bal=0; - n->left->bal=0; - rot_r(n,parent); + if (n->left->bal == -1) { + n->bal = 0; + n->left->bal = 0; + rot_r(n, parent); return 1; - } - else if(n->left->bal==0){ - n->bal=-1; - n->left->bal=1; - rot_r(n,parent); + } else if (n->left->bal == 0) { + n->bal = -1; + n->left->bal = 1; + rot_r(n, parent); return 0; - } - else if(n->left->bal==1){ -// int rb; - n->bal=0; - n->left->bal=0; -// rb = n->left->right->bal; - n->left->right->bal=0; - rot_lr(n,parent); + } else if (n->left->bal == 1) { +// int rb; + n->bal = 0; + n->left->bal = 0; +// rb = n->left->right->bal; + n->left->right->bal = 0; + rot_lr(n, parent); return 1; } - -// printf("adj bal li left not handled \n"); -// exit(0); - return -11; /* that should never happen */ +// printf("adj bal li left not handled \n"); +// exit(0); + 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) { - struct avlnode * n = *parent; + struct avlnode *n = *parent; - if(n->left!=0){ - int bal = avltree_del_lo(&n->left,data); - n->bal+=bal; - if (n->bal==1){ + if (n->left != 0) { + int bal = avltree_del_lo(&n->left, data); + n->bal += bal; + if (n->bal == 1) { return 0; - } - if (n->bal!=2) + } + if (n->bal != 2) return bal; - adj_bal_l(n,parent); + adj_bal_l(n, parent); return 0; } /* found the lowest element */ - *parent=n->right; + *parent = n->right; *data = n->data; - free (n); + free(n); return 1; - if (n->right){ + if (n->right) { free(n); 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) { - struct avlnode * n = *parent; + struct avlnode *n = *parent; int rc; int bal; + rc = t->cmp(*data, n->data); - rc =t->cmp(*data,n->data); - - if (rc==0){ - if (n->right == 0 && n->left ==0){ - *parent=0; - avlnode_destroy(t,n); + if (rc == 0) { + if (n->right == 0 && n->left == 0) { + *parent = 0; + avlnode_destroy(t, n); return 1; } - if (n->right && n->left==0){ - *parent=n->right; - avlnode_destroy(t,n); + if (n->right && n->left == 0) { + *parent = n->right; + avlnode_destroy(t, n); return 1; } - if (n->left && n->right==0){ - avlnode_destroy(t,n); - *parent=n->left; + if (n->left && n->right == 0) { + avlnode_destroy(t, n); + *parent = n->left; return 1; } /* node has two childs */ - if (t->del){ + if (t->del) { t->del(n->data); } t->count--; - bal = avltree_del_lo(&n->right,&n->data); - n->bal-= bal; - if (n->bal==-1) + bal = avltree_del_lo(&n->right, &n->data); + n->bal -= bal; + if (n->bal == -1) return 0; if (n->bal != -2) return bal; - return adj_bal_r(n,parent); + return adj_bal_r(n, parent); } - if (rc<0){ - if (n->left) - { - bal = avltree_del0(t,&n->left,data); - if (bal==2) + if (rc < 0) { + if (n->left) { + bal = avltree_del0(t, &n->left, data); + if (bal == 2) return 2; - n->bal+=bal; - if (n->bal==1) + n->bal += bal; + if (n->bal == 1) return 0; - if (n->bal!=2) + if (n->bal != 2) return bal; - return adj_bal_l(n,parent); + return adj_bal_l(n, parent); } - return 2; /* not found */ - } - else { /* rc must be > 0 */ - if (n->right){ - bal = avltree_del0(t,&n->right,data); - if (bal==2) + return 2; /* not found */ + } else { /* rc must be > 0 */ + if (n->right) { + bal = avltree_del0(t, &n->right, data); + if (bal == 2) return 2; - n->bal-=bal; - if (n->bal==-1) + n->bal -= bal; + if (n->bal == -1) return 0; if (n->bal != -2) 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; - int rc = avltree_del0(t,&t->root,&d); - if (rc==2) - return 0; + int rc = avltree_del0(t, &t->root, &d); + if (rc == 2) + return NULL; return data; } @@ -609,11 +597,13 @@ void walk(struct avlnode *n) */ +/* void avltree_destroy(struct avltree *t) { avltree_del_all(t); free (t); } +*/ //#include diff --git a/src/capwap/avltree.h b/src/capwap/avltree.h index e0a40b5e..a8fddc81 100644 --- a/src/capwap/avltree.h +++ b/src/capwap/avltree.h @@ -16,65 +16,81 @@ */ -/* - * yet another avl tree implementation! +/** + * @file + * @brief Yet another avl tree implementation! */ #ifndef __AVLTREE_H #define __AVLTREE_H -#include +#include #include +#include -struct avlnode{ - void * data; - struct avlnode * left; - struct avlnode * right; + +struct avlnode { + void *data; + struct avlnode *left; + struct avlnode *right; int bal; }; -struct avltree{ - struct avlnode * root; - int (*cmp)(const void*,const void*); - void(*del)(void*); +struct avltree { + struct avlnode *root; + int (*cmp) (const void *, const void *); + void (*del) (void *); 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*)); -void avltree_destroy(struct avltree *t); +struct avltree *avltree_create(int (*cmp) (const void *, const void *), + void (*del) (void *)); +//void avltree_destroy(struct avltree *t); void avltree_del_all(struct avltree *t); -void * avltree_del(struct avltree *t, void *data); -void * avltree_add(struct avltree *t, void *data); +void *avltree_del(struct avltree *t, void *data); +void *avltree_add(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_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 int avltree_foreach_lr(struct avlnode *n, 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); -static inline void * avltree_get(struct avltree *t ,void *data){ - struct avlnode * n = avltree_get_node(t,data); +static inline void *avltree_get(struct avltree *t, void *data) +{ + struct avlnode *n = avltree_get_node(t, data); if (!n) return NULL; return n->data; } -static inline void * avltree_replace_data(struct avltree *t ,void *data,int len) { - void * df = avltree_get(t,data); - if(!df) +static inline void *avltree_replace_data(struct avltree *t, void *data, int len) +{ + void *df = avltree_get(t, data); + if (!df) return NULL; - memcpy(df,data,len); + memcpy(df, data, len); 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_insert(t,d) avltree_add(t,d) //#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 - - diff --git a/src/capwap/avltree_get.c b/src/capwap/avltree_get.c index bcf9769b..62950050 100644 --- a/src/capwap/avltree_get.c +++ b/src/capwap/avltree_get.c @@ -13,14 +13,22 @@ You should have received a copy of the GNU General Public License along with Foobar. If not, see . - */ +/** + * @file + * @brief Implementation of avltree_get + */ + #include #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) { struct avlnode *n = t->root; diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index ea48ee11..015980ad 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -34,6 +34,7 @@ #include "conn.h" #include "lwapp.h" +#include "strheap.h" /* capwap version and iana number */ #define CW_VERSION 0 @@ -83,6 +84,9 @@ enum capwap_states { #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_R2 0x02 /* bit 1 reserved 2 */ #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_bstr lw_put_bstr +#define cw_set_dword lw_set_dword + + #define cw_get_byte lw_get_byte #define cw_get_word lw_get_word #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_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_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_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_type(msgptr,t) cw_set_msg_id(msgptr,t) #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*) * @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 * @param e pointer to message element * @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 @@ -770,19 +798,11 @@ extern int cw_send_configuration_update_response(struct conn *conn, int seqnum, /* 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 */ -extern struct cw_strlist capwap_strings_msg[]; -extern struct cw_strlist capwap_strings_state[]; -extern struct cw_strlist capwap_strings_vendor[]; -extern struct cw_strlist capwap_strings_elem[]; +extern struct cw_str capwap_strings_msg[]; +extern struct cw_str capwap_strings_state[]; +extern struct cw_str capwap_strings_vendor[]; +extern struct cw_str capwap_strings_elem[]; #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_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); @@ -806,13 +833,18 @@ extern int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8 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, - 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_generic(struct conn *conn, struct cw_action_out *a, 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 { @@ -825,9 +857,42 @@ struct cw_ac_status { 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_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 diff --git a/src/capwap/capwap_actions.h b/src/capwap/capwap_actions.h index 4d397fd7..613ce8ed 100644 --- a/src/capwap/capwap_actions.h +++ b/src/capwap/capwap_actions.h @@ -61,7 +61,7 @@ CW_ITEM_WTP_MAC_TYPE, /* ID to use store */ \ 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_in_vendor_specific_payload, 0 /* start/end callback*/ \ diff --git a/src/capwap/capwap_actions_ac.c b/src/capwap/capwap_actions_ac.c index b0924f6d..738ce8a1 100644 --- a/src/capwap/capwap_actions_ac.c +++ b/src/capwap/capwap_actions_ac.c @@ -21,13 +21,7 @@ #include "action.h" #include "capwap_items.h" #include "capwap_actions.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; -} - +#include "strheap.h" @@ -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} , /* Vendor Specific Payload */ - {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, - cw_in_vendor_specific_payload, 0} + {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD} , /* -------------------------------------------------------------------------------*/ @@ -90,6 +83,9 @@ cw_action_in_t capwap_actions_ac_in[] = { /* Element 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) { @@ -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)); 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 */ - {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, - CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0} + {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0 + ,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0} , + /* AC Name */ - {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME, - CW_ELEM_AC_NAME, cw_out_generic, cw_get_local} + {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME, 0, + CW_ELEM_AC_NAME, cw_out_generic, cw_out_get_local} , /* List of CAPWAP Control IPv4 and IPv6 addresses */ - {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST, - 0, cw_out_capwap_control_ip_addrs, cw_get_local} + {CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST, 0, + 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} @@ -180,9 +184,18 @@ int cw_register_actions_capwap_ac(struct cw_actiondef *def) { def->in = cw_actionlist_in_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_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; } diff --git a/src/capwap/capwap_cisco.h b/src/capwap/capwap_cisco.h index 07a01c14..1e0d2aa5 100644 --- a/src/capwap/capwap_cisco.h +++ b/src/capwap/capwap_cisco.h @@ -46,6 +46,7 @@ #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_MWAR_NAME LW_ELEM_AC_NAME /* 31 */ #define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */ #define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */ @@ -92,15 +93,20 @@ * @param dst destination buffer * @param time a unix timestamp * @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_byte(dst + 14, type); - return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_TIMESYNC, 5); + cw_put_dword(dst , time); + cw_put_byte(dst + 4, type); + 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 * @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_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) ; + /* diff --git a/src/capwap/capwap_items.h b/src/capwap/capwap_items.h index c85ac995..9e941f90 100644 --- a/src/capwap/capwap_items.h +++ b/src/capwap/capwap_items.h @@ -37,7 +37,12 @@ enum capwap_items { CW_ITEM_LOCATION_DATA, CW_ITEM_SESSION_ID, + + CW_ITEM_AC_TIMESTAMP, + + /* CIPWAP and Cisco */ + CW_ITEM_WTP_GROUP_NAME }; diff --git a/src/capwap/capwap_strings_elem.c b/src/capwap/capwap_strings_elem.c index 8f7a37f6..e02bad9c 100644 --- a/src/capwap/capwap_strings_elem.c +++ b/src/capwap/capwap_strings_elem.c @@ -1,6 +1,6 @@ #include "capwap.h" -struct cw_strlist capwap_strings_elem[] = { +struct cw_str capwap_strings_elem[] = { {CW_ELEM_AC_DESCRIPTOR, "AC Descriptor"}, {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_WTP_RADIO_STATISTICS, "WTP Radio 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) */ /* CW_ELEM_WTP_IPV4_IP_ADDRESS 42 CW_ELEM_WTP_IPV6_IP_ADDRESS 43 */ + {0,"Unknown Element"} }; diff --git a/src/capwap/capwap_strings_msg.c b/src/capwap/capwap_strings_msg.c index 93a9a29a..f9d4826d 100644 --- a/src/capwap/capwap_strings_msg.c +++ b/src/capwap/capwap_strings_msg.c @@ -1,6 +1,6 @@ #include "capwap.h" -struct cw_strlist capwap_strings_msg[] = { +struct cw_str capwap_strings_msg[] = { { CW_MSG_DISCOVERY_REQUEST, "Discovery Request" }, { CW_MSG_DISCOVERY_RESPONSE,"Discovery Response" }, { CW_MSG_JOIN_REQUEST, "Join Request"}, diff --git a/src/capwap/capwap_strings_state.c b/src/capwap/capwap_strings_state.c index fa6a44be..2df07447 100644 --- a/src/capwap/capwap_strings_state.c +++ b/src/capwap/capwap_strings_state.c @@ -1,8 +1,10 @@ #include "capwap.h" -struct cw_strlist capwap_strings_state[] = { +struct cw_str capwap_strings_state[] = { { CW_STATE_DISCOVERY, "Discovery" }, { CW_STATE_JOIN,"Join" }, { CW_STATE_RUN,"Run" }, +{ CW_STATE_CONFIGURE,"Configure" }, { 0,"Undefined" } }; + diff --git a/src/capwap/capwap_strings_vendor.c b/src/capwap/capwap_strings_vendor.c index 191c9a41..565be546 100644 --- a/src/capwap/capwap_strings_vendor.c +++ b/src/capwap/capwap_strings_vendor.c @@ -1,7 +1,7 @@ #include "capwap.h" -struct cw_strlist capwap_strings_vendor[] = { +struct cw_str capwap_strings_vendor[] = { { CW_VENDOR_ID_CISCO, "Cisco" }, { CW_VENDOR_ID_ZYXEL, "Zyxel" }, { CW_VENDOR_ID_FSF, "FSF"} diff --git a/src/capwap/cipwap_actions_ac.c b/src/capwap/cipwap_actions_ac.c index 42ebe534..aba47269 100644 --- a/src/capwap/cipwap_actions_ac.c +++ b/src/capwap/cipwap_actions_ac.c @@ -1,28 +1,71 @@ #include "capwap.h" +#include "capwap_cisco.h" #include "capwap_actions.h" +#include "cipwap.h" + +/** + *@file + *brief CIPWAP Actions + */ cw_action_in_t cipwap_actions_ac_in[] = { - /* Element Discovery Type */ - {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE, - cw_in_generic, 0, CW_ITEMTYPE_BYTE, CW_ITEM_DISCOVERY_TYPE, 4, 4} + /* ------------------------------------------------------------------------------- + * Discovery Request IN + */ + {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) { cw_register_actions_capwap_ac(def); - 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; } diff --git a/src/capwap/conn.h b/src/capwap/conn.h index e4581fde..630bb819 100644 --- a/src/capwap/conn.h +++ b/src/capwap/conn.h @@ -16,6 +16,10 @@ */ +/** + * @file + * @brief Connection object stuff + */ #ifndef __CONN_H #define __CONN_H @@ -35,14 +39,18 @@ #include "itemstore.h" +/** + * Connection Object + */ struct conn { int sock; struct sockaddr_storage addr; int recv_timeout; - cw_itemstore_t itemstore; - + /** Basically used to store local conig data */ 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; diff --git a/src/capwap/conn_get_message.c b/src/capwap/conn_get_message.c index 6de4f9f1..ad3e25e6 100644 --- a/src/capwap/conn_get_message.c +++ b/src/capwap/conn_get_message.c @@ -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]; int len = 2024; int n = conn->read(conn, buf, len); + if (n<0 ) + return n; + if (n > 0) conn_process_packet(conn, buf, n, cw_process_msg, conn); diff --git a/src/capwap/cw_dbg_elem.c b/src/capwap/cw_dbg_elem.c index 93dbb69d..b8ae1d2c 100644 --- a/src/capwap/cw_dbg_elem.c +++ b/src/capwap/cw_dbg_elem.c @@ -1,5 +1,38 @@ #include "cw_log.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 */ -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)) 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) { uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf)); 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); + sprintf(vendorname, "%s/%s/%s", + cw_strelemp(conn->actions,msgelem), + (char *) lw_vendor_id_to_str(vendor_id), vendor_details); + elemname = vendorname; } else { - elemname = cw_strelem(msgelem); + elemname = cw_strelemp(conn->actions,msgelem); } if (!cw_dbg_is_level(DBG_ELEM_DMP)) cw_dbg(DBG_ELEM, "%s, CAWPAP element: %d (%s), len=%d%s", - cw_strmsg(msg), msgelem, elemname, len, vendor_details); + cw_strmsg(msg), msgelem, elemname, len, ""); else cw_dbg_dmp(DBG_ELEM, msgbuf, len, "%s, CAPWAP element: %d (%s), len=%d%s\n\tDump ...", - cw_strmsg(msg), msgelem, elemname, len, vendor_details); + cw_strmsg(msg), msgelem, elemname, len, ""); } diff --git a/src/capwap/cw_in_generic.c b/src/capwap/cw_in_generic.c index 67177acb..3787a808 100644 --- a/src/capwap/cw_in_generic.c +++ b/src/capwap/cw_in_generic.c @@ -31,7 +31,7 @@ int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int le 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; } diff --git a/src/capwap/cw_in_vendor_specific_payload.c b/src/capwap/cw_in_vendor_specific_payload.c index 777edb15..b13c94ac 100644 --- a/src/capwap/cw_in_vendor_specific_payload.c +++ b/src/capwap/cw_in_vendor_specific_payload.c @@ -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.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); @@ -27,8 +26,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint return 0; } - printf("Found\n"); - if (af->start) { af->start(conn,af,data+6,len-6); } diff --git a/src/capwap/cw_in_wtp_board_data.c b/src/capwap/cw_in_wtp_board_data.c index dab23353..43ba4135 100644 --- a/src/capwap/cw_in_wtp_board_data.c +++ b/src/capwap/cw_in_wtp_board_data.c @@ -96,7 +96,7 @@ int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * da 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)); readsubelems_wtp_board_data(itemstore,data+4,len-4); diff --git a/src/capwap/cw_in_wtp_descriptor.c b/src/capwap/cw_in_wtp_descriptor.c index 04eae57f..0636d076 100644 --- a/src/capwap/cw_in_wtp_descriptor.c +++ b/src/capwap/cw_in_wtp_descriptor.c @@ -34,7 +34,7 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, ui if (len<6) 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_RADIOS_IN_USE,cw_get_byte(data+1)); diff --git a/src/capwap/cw_msg_init.c b/src/capwap/cw_msg_init.c index 2e30c3ce..92b8164e 100644 --- a/src/capwap/cw_msg_init.c +++ b/src/capwap/cw_msg_init.c @@ -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) { uint8_t *buffer=conn->resp_buffer; - int hbytes = cw_get_hdr_msg_offset(req); - memcpy(buffer,req,hbytes); + int shbytes = cw_get_hdr_msg_offset(req); + 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 * dmsgptr = buffer+hbytes; + uint8_t * msgptr = req+shbytes; + uint8_t * dmsgptr = buffer+dhbytes; cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1); cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr)); diff --git a/src/capwap/cw_out_ac_descriptor.c b/src/capwap/cw_out_ac_descriptor.c index 0de0fcf0..e5e723d6 100644 --- a/src/capwap/cw_out_ac_descriptor.c +++ b/src/capwap/cw_out_ac_descriptor.c @@ -6,9 +6,9 @@ #include "capwap.h" +/* 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; 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)); return d-dst; } +*/ - -int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item) +int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) { 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; } - struct cw_ac_status *s = (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)); + d+=cw_put_ac_status(d ,(struct cw_ac_status*)(i->data)); i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION); 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 { 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); 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 { 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; - return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len); + return len + cw_put_elem_hdr(dst,a->elem_id,len); } diff --git a/src/capwap/cw_out_capwap_control_ip_addrs.c b/src/capwap/cw_out_capwap_control_ip_addrs.c index 321bd27a..9c562cce 100644 --- a/src/capwap/cw_out_capwap_control_ip_addrs.c +++ b/src/capwap/cw_out_capwap_control_ip_addrs.c @@ -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 ) { cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found"); return 0; diff --git a/src/capwap/cw_out_generic.c b/src/capwap/cw_out_generic.c index cd2c27d8..6c0278df 100644 --- a/src/capwap/cw_out_generic.c +++ b/src/capwap/cw_out_generic.c @@ -9,27 +9,50 @@ int cw_put_item(uint8_t *dst,struct cw_item*item) { switch (item->type){ case CW_ITEMTYPE_STR: - printf("Outing str %s\n",item->data); return cw_put_data(dst,item->data,strlen( (char*)item->data)); case CW_ITEMTYPE_BYTE: return cw_put_byte(dst,item->byte); case CW_ITEMTYPE_WORD: return cw_put_word(dst,item->word); case CW_ITEMTYPE_DWORD: - return cw_put_word(dst,item->dword); + return cw_put_dword(dst,item->dword); } 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; if ( !item ) len=0; - else - len = cw_put_item(dst+4,item); - return len + cw_put_elem_hdr(dst,elem_id,len); + else{ + printf("Putting it\n"); + 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); } diff --git a/src/capwap/cw_process_msg.c b/src/capwap/cw_process_msg.c index 321e0e12..bbcb8b84 100644 --- a/src/capwap/cw_process_msg.c +++ b/src/capwap/cw_process_msg.c @@ -12,174 +12,26 @@ #include "dbg.h" - - -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 cw_out_msg(struct conn *conn, uint8_t * rawout); int conn_send_msg(struct conn *conn, uint8_t * rawmsg); int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len) { - struct priv priv; +// struct priv priv; 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; - - 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)); +// cw_action_out_t as; - printf("The total msgelems length is %d\n", priv.len); - - 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); - + cw_put_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); 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); diff --git a/src/capwap/cw_strlist_get_str.c b/src/capwap/cw_strlist_get_str.c index 14157929..023f4156 100644 --- a/src/capwap/cw_strlist_get_str.c +++ b/src/capwap/cw_strlist_get_str.c @@ -1,6 +1,6 @@ #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){ if (s->id==id) diff --git a/src/capwap/dbg.h b/src/capwap/dbg.h index 6944bf58..f2b076d3 100644 --- a/src/capwap/dbg.h +++ b/src/capwap/dbg.h @@ -1,14 +1,14 @@ #ifndef __DBG_H #define __DBG_H +#include "conn.h" - -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); #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