diff --git a/src/ac/ac_main.c b/src/ac/ac_main.c index 2b4ff51f..6a8ee5a9 100644 --- a/src/ac/ac_main.c +++ b/src/ac/ac_main.c @@ -83,9 +83,35 @@ static int parse_args(int argc, char *argv[]) #include "capwap/mod.h" extern struct mod_ac * cw_get_mod_ac(const char *name); +#include "capwap/mlist.h" + +static int mcmp(void *v1,void*v2) +{ + return strcmp((char*)v1,(char*)v2); +} + int main(int argc, char *argv[]) { + int rc = 0; + + /* + struct mlist_elem *e; + + mlist_t * l = mlist_create(mcmp); + + mlist_append(l,"Hallo"); + + mlist_append(l,"Welt"); + + e = mlist_find(l,NULL,"Welt"); + + printf("Found: %p\n",e); + + exit(0); + */ + + /* struct mod_ac *m = cw_get_mod_ac("cipwap"); printf("Ptr: %p\n",m); @@ -100,6 +126,7 @@ m->init(); read_config("ac.conf"); + /* Show debug options if there are any set */ if (cw_dbg_opt_level) cw_log(LOG_INFO, "Debug Options: %08X", cw_dbg_opt_level); @@ -134,13 +161,27 @@ m->init(); int regn; /* Load CAPWAP base protocol */ - if (conf_capwap_mode == CW_MODE_CIPWAP) { +/* if (conf_capwap_mode == CW_MODE_CIPWAP) { cw_dbg(DBG_INFO, "Loading CIPWAP Actions ..."); regn = cw_register_actions_cipwap_ac(&capwap_actions); } else { cw_dbg(DBG_INFO, "Loading standard CAPWAP Actions ..."); regn = cw_register_actions_capwap_ac(&capwap_actions); } +*/ + + regn = cw_register_actions_capwap_ac(&capwap_actions); + + + struct outelem * l = cw_actionlist_out_get_mlist(capwap_actions.out,CW_MSG_DISCOVERY_RESPONSE); + + printf("List got: %p\n",l); + + + + +// exit(0); + /* Load bindings */ cw_dbg(DBG_INFO, "Loading 802.11 Bindings ..."); diff --git a/src/capwap/Makefile b/src/capwap/Makefile index aebfcc16..5752bd76 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -80,6 +80,7 @@ MAVLOBJS= \ mavl_foreach_lr.o \ mavl_merge.o \ mavl_create_conststr.o \ + mlist.o \ utf8.o \ cw_load_file.o \ cw_save_file.o diff --git a/src/capwap/action.c b/src/capwap/action.c index 36cbed69..4b1e3f25 100644 --- a/src/capwap/action.c +++ b/src/capwap/action.c @@ -27,6 +27,8 @@ #include "action.h" + + static inline int cw_action_in_cmp(const void *elem1, const void *elem2) { struct cw_action_in *e1 = (struct cw_action_in *) elem1; @@ -112,7 +114,7 @@ int cw_actionlist_in_register_actions(cw_actionlist_in_t t, cw_action_in_t * act int n=0; while (actions->capwap_state) { cw_action_in_t *rc = cw_actionlist_in_add(t, actions); - if (rc == 0) + if (!rc) return 0; actions++; n++; @@ -122,6 +124,9 @@ int cw_actionlist_in_register_actions(cw_actionlist_in_t t, cw_action_in_t * act int cw_actionlist_out_register_actions(cw_actionlist_out_t t, cw_action_out_t * actions) { + + + int n=0; while (actions->msg_id != 0) { cw_action_out_t *rc = cw_actionlist_out_add(t, actions); @@ -135,16 +140,22 @@ int cw_actionlist_out_register_actions(cw_actionlist_out_t t, cw_action_out_t * - /* * Compare function for actionlist_out_t lists */ static int cw_action_out_cmp(const void *elem1, const void *elem2) { - struct cw_action_out *e1 = (struct cw_action_out *) elem1; - struct cw_action_out *e2 = (struct cw_action_out *) elem2; - int r; + + + struct outelem *e1 = (struct outelem *) elem1; + struct outelem *e2 = (struct outelem *) elem2; + + + //printf("cmp %d and %d\n",e1->msg_id,e2->msg_id); + return e1->msg_id - e2->msg_id; + +/* r = e1->msg_id - e2->msg_id; if (r != 0) return r; @@ -165,7 +176,7 @@ static int cw_action_out_cmp(const void *elem1, const void *elem2) } if (r != 0) return r; - +*/ /* r = e1->vendor_id - e2->vendor_id; @@ -177,6 +188,41 @@ static int cw_action_out_cmp(const void *elem1, const void *elem2) +static int mout_cmp(void *elem1,void *elem2) +{ + + struct cw_action_out *e1 = (struct cw_action_out *) elem1; + struct cw_action_out *e2 = (struct cw_action_out *) elem2; + int r; + + r = e1->msg_id - e2->msg_id; + if (r ) + return r; + + r = e1->elem_id - e2->elem_id; + if (r ) + return r; + + + r = e1->vendor_id - e2->vendor_id; + if (r ) + return r; + + if (e1->item_id == e1->item_id) + return 0; + + if (e1->item_id && e2->item_id) + return strcmp(e1->item_id,e2->item_id); + + + return 1; + +} + + + + + /** * Add an action to an action * @param t actionlist @@ -209,13 +255,75 @@ void *cw_actionlist_add(struct avltree *t, void *a, size_t s) */ cw_actionlist_out_t cw_actionlist_out_create() { - return avltree_create(cw_action_out_cmp, free); + return mavl_create(cw_action_out_cmp, free); } +struct outelem * cw_actionlist_out_get_mlist(cw_actionlist_out_t t, int msg_id) +{ + struct outelem search; + search.msg_id=msg_id; + //printf("Searching for %d\n",msg_id); + return mavl_get(t,&search); + +} + +struct outelem * cw_actionlist_mout_create(int msg_id) +{ + struct outelem * o = malloc(sizeof(struct outelem)); + if (!o) + return NULL; + + o->mlist= mlist_create(mout_cmp); + if (!o->mlist){ + free(o); + return NULL; + } + o->msg_id=msg_id; + return o; +} + + + + +#include "capwap.h" + cw_action_out_t *cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_out * a) { - return cw_actionlist_add(t, a, sizeof(struct cw_action_out)); +/* if (a->msg_id==CW_MSG_DISCOVERY_RESPONSE){ + printf("Add discovery response\n"); + } +*/ + + struct outelem * o = cw_actionlist_out_get_mlist(t,a->msg_id); + + + if (!o){ + /* if (a->msg_id==CW_MSG_DISCOVERY_RESPONSE){ + printf("m was 0 creating \n"); + } + */ + o = cw_actionlist_mout_create(a->msg_id); + if (!o) { + return NULL; + } + mavl_add(t,o); + + + } + + + + struct mlist_elem * e = mlist_replace(o->mlist,NULL,a); + if (!e) + e = mlist_append(o->mlist,a); + + if (e) + return a; + + return 0; + + } diff --git a/src/capwap/action.h b/src/capwap/action.h index 99535569..6a6f11ba 100644 --- a/src/capwap/action.h +++ b/src/capwap/action.h @@ -55,8 +55,6 @@ struct cw_action_in{ uint16_t min_len; uint16_t max_len; uint8_t mand; -// mbag_t (*target)(struct conn *conn,struct cw_action_in *a); - }; typedef int(*cw_action_fun_t)(struct conn *,struct cw_action_in *,uint8_t*,int ,struct sockaddr *); @@ -90,6 +88,7 @@ struct cw_action_out{ const char * item_id; uint32_t vendor_id; uint16_t elem_id; + int (*init)(struct conn * conn, struct cw_action_out *a, uint8_t * dst); int (*out)(struct conn * conn, struct cw_action_out *a, uint8_t * dst); struct mbag_item *(*get)(struct conn *conn,struct cw_action_out *a); @@ -102,9 +101,18 @@ struct cw_action_out{ }; + + + + + + typedef struct cw_action_out cw_action_out_t; -typedef struct avltree *cw_actionlist_out_t; +typedef struct mavl *cw_actionlist_out_t; + + + extern cw_actionlist_out_t cw_actionlist_out_create(); extern cw_action_out_t * cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_out * a); extern int cw_actionlist_out_register_actions(cw_actionlist_out_t t,cw_action_out_t * actions); @@ -133,6 +141,9 @@ enum capwapmodes { }; +#include "mlist.h" + + struct cw_actiondef{ @@ -143,10 +154,22 @@ struct cw_actiondef{ cw_itemdefheap_t items; cw_itemdefheap_t radioitems; + mlist_t * mout; + /** Supported Wireless Binding IDs (WBID) */ struct avltree * wbids; }; +struct outelem{ + uint32_t msg_id; + mlist_t * mlist; +}; + + + +extern struct outelem * cw_actionlist_out_get_mlist(cw_actionlist_out_t t, int msg_id); + + #define cw_actionlist_get_node(t,a) avltree_get_node(t,a) diff --git a/src/capwap/cw_put_msg.c b/src/capwap/cw_put_msg.c index e7eaf782..9ccc200c 100644 --- a/src/capwap/cw_put_msg.c +++ b/src/capwap/cw_put_msg.c @@ -53,6 +53,67 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout) uint8_t *dst = msgptr+8; + + struct outelem *o; + + o = cw_actionlist_out_get_mlist(conn->actions->out,cw_get_msg_type(msgptr)); + + if (!o) + return -1; + mlist_t *m; + m=o->mlist; + + struct mlist_elem *e; + + int len = 0; + + for (e=m->list; e; e=e->next) { + printf("E: %p\n",e); + cw_action_out_t *ae=(cw_action_out_t*)e->data; + + + + DBGX("Put %d %i %p\n",ae->msg_id,ae->elem_id,ae->item_id); + DBGX("Elem ID %s",ae->item_id); + if ( ae->item_id ) { + DBGX("Item ID: %s %p",ae->item_id,CW_ITEM_NONE); + } + + if (ae->msg_id != as.msg_id) { + /* Element is from next msg, close action */ + break; + } + if (ae->out) { + int l=0; + l= ae->out(conn, ae, dst+len); + + + len +=l; + + } + + + } + + + cw_set_msg_elems_len(msgptr, len); + + if (as.msg_id & 1) { + /* It's a request, so we have to set seqnum */ + int s = conn_get_next_seqnum(conn); + cw_set_msg_seqnum(msgptr,s); +// printf("Set seqnum to : %d\n",s); + + } + + + return len; + + + exit(0); + + + DEFINE_AVLITER(i,conn->actions->out); cw_action_out_t *am; @@ -64,7 +125,6 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout) } cw_action_out_t *ae; - int len = 0; while(NULL != (ae=avliter_next(&i))) { DBGX("Put %d %i %p\n",ae->msg_id,ae->elem_id,ae->item_id); @@ -81,8 +141,6 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout) int l=0; l= ae->out(conn, ae, dst+len); len +=l; -// cw_dbg_elem_colored(DBG_ELEM, conn, ae->msg_id, ae->elem_id, -// dst+len-l,l); } diff --git a/src/capwap/mlist.c b/src/capwap/mlist.c new file mode 100644 index 00000000..7b10b905 --- /dev/null +++ b/src/capwap/mlist.c @@ -0,0 +1,65 @@ +#include +#include + + +#include "mlist.h" + +mlist_t *mlist_create(int (*cmp) (void *v1, void *v2)) +{ + mlist_t *l = malloc(sizeof(mlist_t)); + if (!l) + return NULL; + memset(l, 0, sizeof(mlist_t)); + l->cmp = cmp; + return l; +} + +struct mlist_elem *mlist_append(mlist_t * l, void *data) +{ + struct mlist_elem **n = &l->list; + while (*n != NULL) + n = &(*n)->next; + *n = malloc(sizeof(struct mlist_elem)); + if (!*n) + return NULL; + + (*n)->data = data; + (*n)->next = NULL; + + return *n; +} + +struct mlist_elem *mlist_find(mlist_t * l, struct mlist_elem *start, void *data) +{ + struct mlist_elem *e; + if (start) + e = start; + else + e = l->list; + + while (e) { + if (l->cmp(e->data, data) == 0) + return e; + e = e->next; + } + + return NULL; +} + + +struct mlist_elem *mlist_replace(mlist_t *l, struct mlist_elem *start, void *data) +{ + struct mlist_elem *e; + if (start) + e = start; + else + e = l->list; + + struct mlist_elem * f = mlist_find(l,e,data); + if (!f) + return NULL; + + f->data = data; + return f; +} + diff --git a/src/capwap/mlist.h b/src/capwap/mlist.h new file mode 100644 index 00000000..c02dd2e3 --- /dev/null +++ b/src/capwap/mlist.h @@ -0,0 +1,24 @@ +#ifndef __MLIST_H +#define __MLIST_H + +struct mlist_elem { + void *data; + struct mlist_elem *next; +}; + +struct mlist { + void *data; + int (*cmp) (void *d1, void *d2); + struct mlist_elem *list; +}; + +typedef struct mlist mlist_t; + + +extern mlist_t *mlist_create(int (*cmp) (void *v1, void *v2)); +extern struct mlist_elem *mlist_append(mlist_t * l, void *data); +extern struct mlist_elem *mlist_find(mlist_t * l, struct mlist_elem *start, void *data); +extern struct mlist_elem *mlist_replace(mlist_t *l, struct mlist_elem *start, void *data); + + +#endif diff --git a/src/mod/capwap/capwap_actions_ac.c b/src/mod/capwap/capwap_actions_ac.c index 1a14a42e..3e1527fe 100644 --- a/src/mod/capwap/capwap_actions_ac.c +++ b/src/mod/capwap/capwap_actions_ac.c @@ -26,7 +26,7 @@ #include "mod_capwap.h" -cw_action_in_t _capwap_actions_ac_in[] = { +static cw_action_in_t actions_in[] = { /* ------------------------------------------------------------------------------- */ @@ -128,6 +128,34 @@ cw_action_in_t _capwap_actions_ac_in[] = { {0, 0} }; +static cw_action_out_t actions_out[]={ + + /* Message Discovery Response */ + + /* Discovery Response AC Descriptor */ + { + .msg_id = CW_MSG_DISCOVERY_RESPONSE, + .item_id = CW_ITEM_AC_DESCRIPTOR, + .elem_id = CW_ELEM_AC_DESCRIPTOR, + .out = cw_out_ac_descriptor, + .mand = 1 + } + , + + + /* Discovery Response Elem AC_NAME */ + { + .msg_id = CW_MSG_DISCOVERY_RESPONSE, + .elem_id = CW_ELEM_AC_NAME, + .item_id = CW_ITEM_AC_NAME, + .out = cw_out_generic, + .get = cw_out_get_local, + .mand = 1 + } + , + {0,0} +}; + #include "capwap/item.h" @@ -153,8 +181,8 @@ int capwap_register_actions_ac(struct cw_actiondef *def) def->radioitems = cw_itemdefheap_create(); int rc; - rc = cw_actionlist_in_register_actions(def->in, _capwap_actions_ac_in); -// rc += cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out); + rc = cw_actionlist_in_register_actions(def->in, actions_in); + rc += cw_actionlist_out_register_actions(def->out, actions_out); rc += cw_strheap_register_strings(def->strmsg, capwap_strings_msg); rc += cw_strheap_register_strings(def->strelem, capwap_strings_elem); diff --git a/src/mod/capwap/capwap_in_wtp_descriptor.c b/src/mod/capwap/capwap_in_wtp_descriptor.c index c8da48b2..5fdb7905 100644 --- a/src/mod/capwap/capwap_in_wtp_descriptor.c +++ b/src/mod/capwap/capwap_in_wtp_descriptor.c @@ -21,9 +21,6 @@ #include "capwap/sock.h" #include "capwap/cw.h" - - - int capwap_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, struct sockaddr *from) {