diff --git a/src/ac/Makefile b/src/ac/Makefile index 682cdd83..50f01eb8 100644 --- a/src/ac/Makefile +++ b/src/ac/Makefile @@ -50,6 +50,7 @@ AC_OBJS = wtplist.o wtpman.o conf.o ac_main.o \ ac_interface.o \ socklist.o \ db.o \ + ac_global.o AC_SRCS = $(AC_OBJS:.o=.c) AC_DEPS := $(AC_OBJS:.o=.d) @@ -61,6 +62,11 @@ AC_NAME = actube # top-level rule, to compile everything. all: $(AC_NAME) +%.o:%.c + @echo " CC "$< + @$(CC) -c $(CFLAGS) $< -o $@ + + $(AC_NAME): $(AC_OBJS) $(CC) $(AC_OBJS) -o $(AC_NAME) $(LDFLAGS) $(LIBS) diff --git a/src/ac/ac_interface.c b/src/ac/ac_interface.c index 993d5988..ad6a0dc0 100644 --- a/src/ac/ac_interface.c +++ b/src/ac/ac_interface.c @@ -12,42 +12,7 @@ #include "capwap.h" #include "capwap_80211.h" - -ACIPLIST * get_aciplist() -{ - int i=0; - - ACIPLIST * aciplist = aciplist_create(); - if(!aciplist) - return 0; - - - for (i=0; iip,(struct sockaddr*)&sa); - acip->wtp_count=0; - -// printf ("Adding IP %s\n",sock_addr2str(&acip->ip)); - - aciplist_add(aciplist,acip); - - - } - return aciplist; -} +#include "aciplist.h" @@ -91,7 +56,7 @@ struct ac_info * get_acinfo() acinfo->security|=AC_SECURITY_X; - acinfo->dtls_policy = AC_DTLS_POLICY_C | AC_DTLS_POLICY_D ; +// acinfo->dtls_policy = AC_DTLS_POLICY_C | AC_DTLS_POLICY_D ; // acinfo->ac_ips = conf_ac_ips; // acinfo->ac_ips_len=conf_ac_ips_len; @@ -101,11 +66,11 @@ struct ac_info * get_acinfo() // acinfo->salist = conf_ac_ips; // acinfo->salist_len = conf_ac_ips_len; - acinfo->aciplist=get_aciplist(); - + //acinfo->aciplist=get_aciplist(); +/* aciplist_foreach(acinfo->aciplist,pr,NULL); - +*/ int i; for (i=1; i<=4; i++){ acinfo->radioinfos[i].type= diff --git a/src/ac/ac_main.c b/src/ac/ac_main.c index 7ba4d994..dafcb3f5 100644 --- a/src/ac/ac_main.c +++ b/src/ac/ac_main.c @@ -38,7 +38,7 @@ #include "capwap_items.h" #include "capwap_cisco.h" - +#include "ac.h" int ac_run(); @@ -50,23 +50,8 @@ void alive_thread(void *data) } } -#include "cw_action.h" +#include "action.h" -cw_actionlist_t the_tree; - -int dstart(struct conn *conn,struct cw_action_t * a,uint8_t *data,int len) -{ - printf("DISCO STart Action!!\n"); - - uint8_t * rmac = cw_get_hdr_rmac(data); - printf ("This msg is for %s\n",sock_hwaddr2str(bstr_data(rmac), bstr_len(rmac))); -} - -int readelem_discovery_type(struct conn *conn,struct cw_action * a,uint8_t *data,int len) -{ - printf("Discovery Type = %d\n",*data); - cw_itemstore_set_byte(conn->itemstore,CW_ITEM_DISCOVERY_TYPE,*data); -} /* int readelem_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len) @@ -99,6 +84,7 @@ int readelem_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint */ +/* int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len) { printf("Here is the rad name reader\n"); @@ -109,7 +95,7 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data } printf("\n"); } - +*/ @@ -117,116 +103,32 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data int main (int argc, const char * argv[]) { - -cw_actionlist_t t = cw_actionlist_create(); -the_tree=t; - - -cw_action_t discovery_actions[] = { -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1, - dstart,0 }, - -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE, - readelem_discovery_type,0 }, - -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, - cw_in_vendor_specific_payload,0 }, - -{ CW_VENDOR_ID_CISCO,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME, - cw_in_wtp_name,0 }, - - -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA, - cw_in_wtp_board_data,0 }, - -/* -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, -{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE}, - -*/ - -{ 0,0,0} -}; - - - -cw_action_t join_actions[] = { - -{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,0,0}, -{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE}, -{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA}, -{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, -{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, -{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_MAC_TYPE}, -{0} - - -}; - - -cw_register_actions(t,discovery_actions); -cw_register_actions(t,join_actions); - - -#define CW_NAME_DISCOVER_REQUEST "Discovery Request" - -/* -int i; -for(i=0; discovery[i].capwap_state!=CW_STATE_MAX; i++){ - printf("State: %d MSG_ID: %d ELEM_ID: %d\n",discovery[i].capwap_state,discovery[i].msg_id,discovery[i].elem_id); - void * rc = msgtree_add(t,&(discovery[i])); - - printf("Added to tree %p\n",rc); - -} -*/ - - -/* -e.capwap_state=0; -e.msg_id = CW_MSG_DISCOVERY_REQUEST; -e.elem_id = CW_ELEM_AC_NAME; -e.name = "AC Name"; - -msgtree_add(t,&e); -*/ - - - - -// send_image_file(0,"/home/tube/Downloads/c1130-rcvk9w8-tar.124-25e.JAP.tar"); + cw_log_name="AC-Tube"; read_config("ac.conf"); -// cw_log_debug_level=conf_debug_level; + + cw_log(LOG_INFO,"Starting AC-Tube, Name=%s, ID=%s",conf_acname,conf_acid); -// cw_dbg_opt_level= DBG_CW_MSGELEM_DMP | -// DBG_CW_MSGELEM | DBG_CW_PKT| DBG_CW_RFC | DBG_ERR | DBG_CW_MSG | DBG_DTLS ; //| DBG_ALL; - - cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP; -// cw_log_dbg(DBG_CW_MSG,"Hello %s","World"); - - + cw_register_actions_capwap_ac(&capwap_actions); + ac_global_init(); +/* db_init(); db_start(); db_ping(); - pthread_t alth; pthread_create (&alth, NULL, alive_thread, (void *)0); - - -#ifdef WITH_DTLS +*/ + int rc=0; dtls_init(); -#endif if (!socklist_init()) goto errX; @@ -234,13 +136,19 @@ msgtree_add(t,&e); goto errX; - int rc = ac_run(); + rc = ac_run(); errX: wtplist_destroy(); socklist_destroy(); return rc; } + + + + + + void process_ctrl_packet(int index, struct sockaddr * addr, uint8_t * buffer, int len); #define AC_PROTO_CAPWAP 0 #define AC_PROTO_LWAPP 1 @@ -300,7 +208,7 @@ int ac_run() - get_acinfo(); + //get_acinfo(); while(1){ @@ -359,7 +267,7 @@ int ac_run() void process_cw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len) { - int sock = socklist[index].reply_sockfd; +// int sock = socklist[index].reply_sockfd; char hdrstr[1024]; hdr_print(hdrstr,buffer,len); @@ -411,7 +319,7 @@ void process_cw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, void process_lw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len) { - int sock = socklist[index].reply_sockfd; + //int sock = socklist[index].reply_sockfd; uint8_t * m = buffer+6; uint32_t val = ntohl(*((uint32_t*)(m))); @@ -457,10 +365,10 @@ void process_lw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, return; }; - wtpman_lw_start(wtpman); + //wtpman_lw_start(wtpman); } - wtpman_lw_addpacket(wtpman,buffer,len); + //wtpman_lw_addpacket(wtpman,buffer,len); wtplist_unlock(); } diff --git a/src/ac/conf.c b/src/ac/conf.c index ce05351a..36aa1e35 100644 --- a/src/ac/conf.c +++ b/src/ac/conf.c @@ -164,7 +164,7 @@ static int init_acid() static int init_dtls() { if (conf_dtls_psk!=NULL){ - conf_security=CWACSECURITY_FLAGS_S; +// conf_security=CW_SECURITY_FLAGS_S; } return 1; @@ -456,7 +456,7 @@ int init_bcast_addrs() conf_bcast_addrs=malloc(t->count*sizeof(char*)); - stravltree_foreach(t,add_bcast_addr,0,1); + stravltree_foreach_asc(t,add_bcast_addr,0); stravltree_destroy(t); freeifaddrs(ifa0); diff --git a/src/ac/wtpman.c b/src/ac/wtpman.c index 2c519426..4cf5899b 100644 --- a/src/ac/wtpman.c +++ b/src/ac/wtpman.c @@ -34,6 +34,12 @@ #include "cw_util.h" +#include "capwap_items.h" +#include "ac.h" + + +extern struct cw_actiondef capwap_actions; + /* macro to convert our client ip to a string */ //#define CLIENT_IP (sock_addrtostr((struct sockaddr*)&wtpman->conn->addr, (char[64]){0},64)) @@ -352,7 +358,6 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti static void wtpman_run_discovery(void *arg) { - struct wtpman * wtpman = (struct wtpman *)arg; struct cwrmsg * cwrmsg; @@ -360,19 +365,20 @@ static void wtpman_run_discovery(void *arg) time_t timer = cw_timer_start(10); -extern cw_actionlist_t the_tree; -wtpman->conn->capwap_state=CW_STATE_DISCOVERY; -wtpman->conn->msgtr=the_tree; +extern cw_actionlist_in_t the_tree; -wtpman->conn->itemstore = cw_itemstore_create(); + 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(); while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_DISCOVERY){ conn_msg_processor(wtpman->conn); } -// cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo); wtpman_remove(wtpman); return; @@ -460,7 +466,7 @@ static void wtpman_run_run(void *arg) printf("Update now?\n"); - +/* conn_prepare_request(conn,CW_MSG_CONFIGURATION_UPDATE_REQUEST); cwmsg_addelem(&conn->req_msg,CW_ELEM_WTP_NAME,(uint8_t*)"Tube7u83",strlen("Tube7u83")+1); cwmsg_addelem(&conn->req_msg,CWMSGELEM_LOCATION_DATA,(uint8_t*)"Berlin",strlen("Berlin")+1); @@ -475,7 +481,7 @@ static void wtpman_run_run(void *arg) printf("Wait...\n"); conn_wait_for_message(conn,t); } - +*/ printf("Adding WLAN\n"); @@ -581,10 +587,40 @@ static int wtpman_join(void *arg,time_t timer) { struct wtpman * wtpman = (struct wtpman *)arg; -extern cw_actionlist_t the_tree; -wtpman->conn->msgtr=the_tree; +extern cw_actionlist_in_t the_tree; +wtpman->conn->actions=&capwap_actions; 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->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); + } + + + exit(0); + + + + + + + + + + + + + + + + /* timer = cw_timer_start(wtpman->conn->wait_join); */ int join_msgs[] = { CW_MSG_JOIN_REQUEST, -1 }; @@ -1055,7 +1091,7 @@ void wtpman_lw_addpacket(struct wtpman *wtpman, uint8_t *packet, int len) void wtpman_start(struct wtpman * wtpman,int dtlsmode) { if ( dtlsmode ){ - cw_dbg(DBG_CW_INFO,"Starting wtpman in dtls mode"); + cw_dbg(DBG_CW_INFO,"Starting wtpman in DTLS mode"); pthread_create (&wtpman->thread, NULL, (void *) &wtpman_run, (void *) wtpman); } else{ diff --git a/src/capwap/Makefile b/src/capwap/Makefile index 35ba93bc..ab059514 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -38,7 +38,10 @@ LOGOBJS=cw_log.o \ cw_log_debug.o \ cw_log_tofile.o \ cw_log_tosyslog.o \ - cw_log_str2dbglevel.o + cw_log_str2dbglevel.o \ + cw_dbg_elem.o + + WTPINFOOBJS = wtpinfo_set_location.o \ @@ -50,12 +53,15 @@ UTILOBJS= \ cw_rand.o \ cw_foreach_msgelem.o \ avltree.o \ - avltree_get.o \ + avltree_get_node.o \ avltree_del_all.o \ - avltree_foreach.o \ + avltree_foreach_lr.o \ + avltree_foreach_rl.o \ + avltree_foreach_from_lr.o \ stravltree.o \ cw_util.o \ - cw_format_version.o + cw_format_version.o \ + cw_msg_init.o @@ -70,7 +76,8 @@ LWAPPOBJS = \ lw_vendor_id_to_str.o \ lw_elem_id_to_str.o \ lw_msg_id_to_str.o \ - lw_cisco_id_to_str.o + lw_cisco_id_to_str.o \ + lw_put_sockaddr.o \ @@ -90,7 +97,6 @@ CAPWAPOBJS= \ cwmsg_vaddelem.o \ cwmsg_addelem_ac_descriptor.o \ cwmsg_addelem_wtp_descriptor.o \ - cwmsg_addelem_ctrl_ip_addrs.o \ cwmsg_addelem_wtp_radio_infos.o \ cwmsg_addelem_wtp_board_data.o \ cwmsg_addelem_cw_local_ip_addr.o \ @@ -108,8 +114,6 @@ CAPWAPOBJS= \ cw_read_image_data_request.o \ cw_send_image_data_response.o \ cw_send_configuration_update_response.o \ - cwsend_join_request.o \ - cwsend_join_response.o \ cwread_join_response.o \ cwsend_echo_request.o \ cw_send_echo_response.o \ @@ -121,7 +125,6 @@ CAPWAPOBJS= \ cwread_change_state_event_request.o\ cwread_wtp_event_request.o \ process_conf_status_request.o \ - process_join_request.o \ wtpinfo_readelem_wtp_board_data.o \ wtpinfo_readelem_wtp_mac_type.o \ wtpinfo_readelem_wtp_radio_info.o \ @@ -139,8 +142,6 @@ CAPWAPOBJS= \ acinfo_print.o \ lwmsg_init.o \ wtpinfo_lwreadelem_wtp_descriptor.o \ - cw_msgelemtostr.o \ - cw_msgtostr.o \ hdr_print.o \ cw_readelem_ecn_support.o \ cw_readelem_maximum_message_length.o \ @@ -165,11 +166,19 @@ CAPWAPOBJS= \ capwap_strings_msg.o \ capwap_strings_state.o \ capwap_strings_vendor.o \ + capwap_strings_elem.o \ itemstore.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_ac_descriptor.o \ + cw_out_capwap_control_ip_addrs.o + #cw_msgtostr.o \ + #cw_msgelemtostr.o \ + #cwmsg_addelem_ctrl_ip_addrs.o \ + #process_join_request.o \ #cw_ianavendoridtostr.o \ #cwmsg_addelem_result_code.o \ @@ -180,10 +189,12 @@ CAPWAPOBJS= \ #cwmsg_addelem_session_id.o # process_msgelems_discovery_request.o \ - + # cwsend_join_request.o \ +# # cwsend_image_data_request.o # cwmsg_set_control_header.o # process_msgelems.o \ +# cwsend_join_response.o \ # # SSL objects @@ -235,7 +246,8 @@ CONNOBJS= conn_create.o \ conn_send_request.o \ conn_wait_for_message.o \ conn_wait_for_request.o \ - conn_init.o + conn_init.o \ + conn_send_msg.o @@ -247,8 +259,12 @@ BSTROBJS= bstr_create.o \ FRAGOBJS=fragman.o -CWACTION=cw_action.o \ - cw_process_msg.o +CWACTION=action.o \ + cw_process_msg.o \ + capwap_actions_ac.o \ + cw_in_generic.o \ + cw_in_wtp_descriptor.o + OBJS=$(CONNOBJS) $(FRAGOBJS) $(SOCKOBJS) $(CAPWAPOBJS) $(WTPINFOOBJS) \ @@ -281,7 +297,7 @@ $(ARCH)/%.o:%.c @mkdir -p $(ARCH) @echo " CC "$< @$(CC) -c $(CFLAGS) $< -o $@ - @$(CC) -MM $(CFLAGS) $< > $*.d +# @$(CC) -MM $(CFLAGS) $< > $*.d $(ARCH)/$(NAME) : $(OBJS) @echo " AR $(ARCH)/$(NAME)" diff --git a/src/capwap/acinfo.c b/src/capwap/acinfo.c index 7b36e881..056036d6 100644 --- a/src/capwap/acinfo.c +++ b/src/capwap/acinfo.c @@ -117,8 +117,10 @@ printf("sublen type = %d\n",subtype); int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msgelem,int len) { + +/* switch (type){ - case CWMSGELEM_CONTROL_IPV4_ADDRESS: + case CW_ELEM_CONTROL_IPV4_ADDRESS: { if (len!=6) return -1; @@ -147,7 +149,7 @@ int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msge return 1; } - case CWMSGELEM_CONTROL_IPV6_ADDRESS: + case CW_ELEM_CONTROL_IPV6_ADDRESS: { if (len!=18) return -1; @@ -176,6 +178,8 @@ int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msge } return 0; +*/ + } diff --git a/src/capwap/acinfo.h b/src/capwap/acinfo.h index 2417a1fc..f5dd3bc9 100644 --- a/src/capwap/acinfo.h +++ b/src/capwap/acinfo.h @@ -14,6 +14,7 @@ #include "radioinfo.h" +/* struct acip{ struct sockaddr_storage ip; int wtp_count; @@ -25,7 +26,9 @@ typedef struct avltree ACIPLIST; ACIPLIST * aciplist_create(); #define aciplist_destroy(l) avltree_destroy(l) #define aciplist_add(l,elem) avltree_add(l,elem) -#define aciplist_foreach(l,callback,cbpriv) avltree_foreach(l,callback,cbpriv,1) +#define aciplist_foreach(l,callback,cbpriv) avltree_foreach_asc(l,callback,cbpriv) +*/ + /** @@ -58,7 +61,7 @@ struct ac_info{ struct sockaddr * salist; int salist_len; - ACIPLIST * aciplist; + //ACIPLIST * aciplist; uint8_t ecn_support; struct sockaddr_storage local_ip; diff --git a/src/capwap/acinfo_print.c b/src/capwap/acinfo_print.c index 61105015..5dbebf36 100644 --- a/src/capwap/acinfo_print.c +++ b/src/capwap/acinfo_print.c @@ -57,7 +57,7 @@ int acinfo_print(char *str,const struct ac_info *acinfo) s+=sprintf(s,"\tSecurity: %s\n",help); help[0]=0; - if (acinfo->dtls_policy & AC_DTLS_POLICY_D){ +/* if (acinfo->dtls_policy & AC_DTLS_POLICY_D){ strcpy(help,"dtls"); } if (acinfo->dtls_policy & AC_DTLS_POLICY_C){ @@ -65,7 +65,7 @@ int acinfo_print(char *str,const struct ac_info *acinfo) strcat(help,"/"); strcat(help,"clear"); } - if (!strlen(help)) +*/ if (!strlen(help)) strcpy(help,"Not set"); s+=sprintf(s,"\tDTLS policy: %s\n",help); diff --git a/src/capwap/aciplist.c b/src/capwap/aciplist.c index dd0d3d2e..1fdf6f52 100644 --- a/src/capwap/aciplist.c +++ b/src/capwap/aciplist.c @@ -1,53 +1,73 @@ +/* + This file is part of libcapwap. + + libcapwap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libcapwap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + +*/ + + #include #include #include #include -#include "acinfo.h" +#include "aciplist.h" #include "avltree.h" #include "sock.h" static int acip_cmp(const void *x1, const void *x2) { - struct acip * ip1 = (struct acip*)x1; - struct acip * ip2 = (struct acip*)x2; + struct cw_acip *ip1 = (struct cw_acip *) x1; + struct cw_acip *ip2 = (struct cw_acip *) x2; - if (ip1->ip.ss_family != ip2->ip.ss_family){ + if (ip1->ip.ss_family != ip2->ip.ss_family) { if (ip1->ip.ss_family == AF_INET) return -1; else return 1; } - if (ip1->ip.ss_family == AF_INET){ - struct sockaddr_in * s2=(struct sockaddr_in*)&ip2->ip; - struct sockaddr_in * s1=(struct sockaddr_in*)&ip1->ip; + if (ip1->ip.ss_family == AF_INET) { + struct sockaddr_in *s2 = (struct sockaddr_in *) &ip2->ip; + struct sockaddr_in *s1 = (struct sockaddr_in *) &ip1->ip; - return memcmp(&s1->sin_addr,&s2->sin_addr,sock_addrlen((struct sockaddr*)s1)); + return memcmp(&s1->sin_addr, &s2->sin_addr, + sock_addrlen((struct sockaddr *) s1)); } - if (ip1->ip.ss_family == AF_INET6){ - struct sockaddr_in6 * s2=(struct sockaddr_in6*)&ip2->ip; - struct sockaddr_in6 * s1=(struct sockaddr_in6*)&ip1->ip; + if (ip1->ip.ss_family == AF_INET6) { + struct sockaddr_in6 *s2 = (struct sockaddr_in6 *) &ip2->ip; + struct sockaddr_in6 *s1 = (struct sockaddr_in6 *) &ip1->ip; - return memcmp(&s1->sin6_addr.s6_addr,&s2->sin6_addr.s6_addr,sock_addrlen((struct sockaddr*)s1)); + return memcmp(&s1->sin6_addr.s6_addr, &s2->sin6_addr.s6_addr, + sock_addrlen((struct sockaddr *) s1)); } return -1; } -static void acip_del(void*d) +static void acip_del(void *d) { free(d); } -ACIPLIST * aciplist_create() +cw_aciplist_t cw_aciplist_create() { - struct avltree *t = avltree_create(acip_cmp,acip_del); - return t; + return avltree_create(acip_cmp, acip_del); } - + diff --git a/src/capwap/avltree.h b/src/capwap/avltree.h index 8edbe532..b7b17262 100644 --- a/src/capwap/avltree.h +++ b/src/capwap/avltree.h @@ -23,6 +23,8 @@ #ifndef __AVLTREE_H #define __AVLTREE_H +#include + struct avlnode{ void * data; struct avlnode * left; @@ -46,17 +48,33 @@ 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_get(struct avltree *t ,void *data); +//void * avltree_get(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); -extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir); +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); + if (!n) + return NULL; + return n->data; + + +} #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) +//#define avltree_walk(t,dir) avltree_foreach(t,dir) + +#define avltree_foreach_asc(t,cb,priv) avltree_foreach_lr((t)->root,cb,priv) +#define avltree_foreach_desc(t,cb,priv) avltree_foreach_rl((t)->root,cb,priv) + +#define avltree_foreach_from_asc(t,d,cb,priv) avltree_foreach_from_lr(t,(t)->root,d,cb,priv); #endif diff --git a/src/capwap/avltree_foreach.c b/src/capwap/avltree_foreach.c index d9889d99..795e7b77 100644 --- a/src/capwap/avltree_foreach.c +++ b/src/capwap/avltree_foreach.c @@ -18,18 +18,6 @@ #include "avltree.h" -int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv) -{ - if (!n) - return 1; - if (!avltree_foreach_lr(n->left,callback,cbpriv)) - return 0; - if (!callback(cbpriv,n->data)) - return 0; - return avltree_foreach_lr(n->right,callback,cbpriv); - -} - int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv) { if (!n) diff --git a/src/capwap/bstr.h b/src/capwap/bstr.h index 43b6985d..8198bb82 100644 --- a/src/capwap/bstr.h +++ b/src/capwap/bstr.h @@ -24,7 +24,7 @@ #ifndef __BSTR_H #define __BSTR_H - +#include #include /** @@ -42,6 +42,7 @@ extern uint8_t * bstr_replace( bstr_t * dst, uint8_t * bstr); extern int bstr_to_str(char *dst, bstr_t str,char * def); + /** * Return the length of a bstr_t string. */ @@ -50,7 +51,7 @@ extern int bstr_to_str(char *dst, bstr_t str,char * def); /** * Return the data of a bstr_t string. */ -#define bstr_data(s) (s+1) +#define bstr_data(s) ((s)+1) /** * Return the actual size in memory a bstr_t string needs. @@ -63,5 +64,19 @@ extern int bstr_to_str(char *dst, bstr_t str,char * def); #define BSTR_MAX_LEN 254 +typedef uint8_t *bstr16_t; +#define bstr16_len(s) ( *((uint16_t*)(s)) ) +#define bstr16_data(s) ((s)+2) +#define bstr16_size(l) (l+2) +#define BSTR16_MAX_LEN (0xffff-2) + +static inline int bstr16_ncpy(uint8_t *dst,uint8_t*src,uint16_t len) +{ + *((uint16_t*)dst)=len; + memcpy(dst+2,src,len); + return len+2; +} + + #endif diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index aa96a022..def42901 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -58,9 +58,9 @@ enum capwapmodes { /** * CAWAP States - */ + */ enum capwap_states { - CW_STATE_NONE=0, + CW_STATE_NONE = 0, CW_STATE_DISCOVERY, CW_STATE_JOIN, CW_STATE_CONFIGURE, @@ -83,6 +83,18 @@ enum capwap_states { #define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */ +#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 */ +#define CW_FLAG_HDR_K 0x08 /* bit 3 Keep alive flag */ +#define CW_FLAG_HDR_M 0x10 /* bit 4 MAC Adress field present */ +#define CW_FLAG_HDR_W 0x20 /* bit 5 wireless info present */ +#define CW_FLAG_HDR_L 0x40 /* bit 6 last fragment */ +#define CW_FLAG_HDR_F 0x80 /* bit 7 fragment */ +#define CW_FLAG_HDR_T 0x100 /* bit 8 type of payload frame */ + + + /* wireless binding ids */ #define CWTH_WBID_RESERVED1 0 #define CWTH_WBID_IEEE80211 1 @@ -113,44 +125,45 @@ struct capwap_ctrlhdr /* CAPWAP message types as defined in RFC 5416 */ -#define CW_MSG_DISCOVERY_REQUEST 1 -#define CW_MSG_DISCOVERY_RESPONSE 2 -#define CW_MSG_JOIN_REQUEST 3 -#define CW_MSG_JOIN_RESPONSE 4 +#define CW_MSG_DISCOVERY_REQUEST 1 +#define CW_MSG_DISCOVERY_RESPONSE 2 +#define CW_MSG_JOIN_REQUEST 3 +#define CW_MSG_JOIN_RESPONSE 4 -#define CW_MSG_CONFIGURATION_STATUS_REQUEST 5 -#define CW_MSG_CONFIGURATION_STATUS_RESPONSE 6 +#define CW_MSG_CONFIGURATION_STATUS_REQUEST 5 +#define CW_MSG_CONFIGURATION_STATUS_RESPONSE 6 -#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7 -#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8 +#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7 +#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8 #define CW_MSG_WTP_EVENT_REQUEST 9 -#define CW_MSG_WTP_EVENT_RESPONSE 10 +#define CW_MSG_WTP_EVENT_RESPONSE 10 -#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11 -#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12 +#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11 +#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12 -#define CW_MSG_ECHO_REQUEST 13 -#define CW_MSG_ECHO_RESPONSE 14 +#define CW_MSG_ECHO_REQUEST 13 +#define CW_MSG_ECHO_RESPONSE 14 -#define CW_MSG_IMAGE_DATA_REQUEST 15 -#define CW_MSG_IMAGE_DATA_RESPONSE 16 +#define CW_MSG_IMAGE_DATA_REQUEST 15 +#define CW_MSG_IMAGE_DATA_RESPONSE 16 -#define CW_MSG_RESET_REQUEST 17 -#define CW_MSG_RESET_RESPONSE 18 +#define CW_MSG_RESET_REQUEST 17 +#define CW_MSG_RESET_RESPONSE 18 -#define CW_MSG_PRIMARY_DISCOVERY_REQUEST 19 -#define CW_MSG_PRIMARY_DISCOVERY_RESPONSE 20 +#define CW_MSG_PRIMARY_DISCOVERY_REQUEST 19 +#define CW_MSG_PRIMARY_DISCOVERY_RESPONSE 20 -/* Data Transfer Request 21 - Data Transfer Response 22 - Clear Configuration Request 23 - Clear Configuration Response 24 - Station Configuration Request 25 - Station Configuration Response 26 -*/ +#define CW_MSG_DATA_TRANSFER_REQUEST 21 +#define CW_MSG_DATA_TRANSFER_RESPONSE 22 -#define CWMSG_MAXMSG 26 +#define CW_MSG_CLEAR_CONFIGURATION_REQUEST 23 +#define CW_MSG_CLEAR_CONFIGURATION_RESPONSE 24 + +#define CW_STATION_CONFIGURATION_REQUEST 25 +#define CW_STATION_CONFIGURATION_RESPONSE 26 + +#define CW_MSG_MAXMSG 26 /* @@ -168,10 +181,10 @@ struct capwap_ctrlhdr #define CW_ELEM_ADD_MAC_ACL_ENTRY 7 #define CW_ELEM_ADD_STATION 8 #define CW_ELEM_RESERVED_9 9 -#define CWMSGELEM_CONTROL_IPV4_ADDRESS 10 -#define CWMSGELEM_CONTROL_IPV6_ADDRESS 11 -#define CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS 30 -#define CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS 50 +#define CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS 10 +#define CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS 11 +#define CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS 30 +#define CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS 50 #define CW_ELEM_CAPWAP_TIMERS 12 #define CW_ELEM_CAPWAP_TRANSPORT_PROTOCOL 51 /* not in draft 7 */ #define CW_ELEM_DATA_TRANSFER_DATA 13 @@ -180,7 +193,7 @@ struct capwap_ctrlhdr #define CW_ELEM_DECRYPTION_ERROR_REPORT_PERIOD 16 #define CW_ELEM_DELETE_MAC_ACL_ENTRY 17 #define CW_ELEM_DELETE_STATION 18 -#define CW_ELEM_RESEERVED_19 19 +#define CW_ELEM_RESERVED_19 19 #define CW_ELEM_DISCOVERY_TYPE 20 #define CW_ELEM_DUPLICATE_IPV4_ADDRESS 21 #define CW_ELEM_DUPLICATE_IPV6_ADRESS 22 @@ -190,7 +203,7 @@ struct capwap_ctrlhdr #define CW_ELEM_IMAGE_IDENTIFIER 25 #define CW_ELEM_IMAGE_INFORMATION 26 #define CW_ELEM_INITIATE_DOWNLOAD 27 -#define CWMSGELEM_LOCATION_DATA 28 +#define CW_ELEM_LOCATION_DATA 28 #define CWMSGELEM_MAXIMUM_MESSAGE_LENGTH 29 #define CWMSGELEM_MTU_DISCOVERY_PADDING 52 #define CWMSGELEM_RADIO_ADMINISTRATIVE_STATE 31 @@ -237,16 +250,25 @@ struct capwap_ctrlhdr #define CWBOARDDATA_MACADDRESS 4 -/* */ -#define CWACSECURITY_FLAGS_R 1 /* Reserved */ -#define CWACSECURITY_FLAGS_X 2 /* X.509 */ -#define CWACSECURITY_FLAGS_S 4 /* DTLS psk */ +/* AC Security flags for authentication */ +#define CW_FLAG_AC_SECURITY_R 1 /* Reserved */ +#define CW_FLAG_AC_SECURITY_X 2 /* X.509 */ +#define CW_FLAG_AC_SECURITY_S 4 /* DTLS psk */ -#define CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION 0 -#define CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION 1 -#define CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION 2 -#define CWMSGSUBELEM_WTP_DESCRIPTOR_OTHERSOFTWARE_VERSION 3 +#define CW_FLAG_RMAC_RESERVED 0 +#define CW_FLAG_RMAC_SUPPORTED 1 +#define CW_FLAG_RMAC_NOT_SUPPORTED 2 + + +#define CW_SUBELEM_WTP_HARDWARE_VERSION 0 +#define CW_SUBELEM_WTP_SOFTWARE_VERSION 1 +#define CW_SUBELEM_WTP_BOOTLOADER_VERSION 2 +#define CW_SUBELEM_WTP_OTHERSOFTWARE_VERSION 3 + +#define CW_SUBELEM_AC_HARDWARE_VERSION 4 +#define CW_SUBELEM_AC_SOFTWARE_VERSION 5 + #include "wtpinfo.h" #include "acinfo.h" @@ -315,8 +337,9 @@ extern int wtpinfo_set_radioinfo(struct wtpinfo *wtpinfo, uint8_t * msgelem, int #define AC_SECURITY_S 4 /* PSK support */ /* AC dtls policy flags */ -#define AC_DTLS_POLICY_C 2 /* Clear data channel support */ -#define AC_DTLS_POLICY_D 4 /* DTLS Data channel support */ +#define CW_FLAG_DTLS_POLICY_R 1 /* Clear data channel support */ +#define CW_FLAG_DTLS_POLICY_C 2 /* Clear data channel support */ +#define CW_FLAG_DTLS_POLICY_D 4 /* DTLS Data channel support */ @@ -344,11 +367,12 @@ extern void cwmsg_addelem_wtp_board_data(struct cwmsg *cwmsg, struct wtpinfo *wt extern void cwmsg_addelem_cw_local_ip_addr(struct cwmsg *msg, struct conn *conn); //extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg * cwmsg,struct wtpinfo * wtpinfo); -extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg *msg, struct radioinfo *radioinfos); +extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg *msg, + struct radioinfo *radioinfos); //extern void cwmsg_addelem_result_code(struct cwmsg *msg, int rc); -extern void cwmsg_addelem_vendor_specific_payload(struct cwmsg *msg, int vendor_id, int type, - uint8_t * payload, int len); +extern void cwmsg_addelem_vendor_specific_payload(struct cwmsg *msg, int vendor_id, + int type, uint8_t * payload, int len); //extern void cwsend_discovery_reponse(struct conn * conn, struct ac_info * acinfo); //extern int process_msgelems(uint8_t * msgelems, int len, @@ -359,12 +383,14 @@ extern void cwmsg_addelem_vendor_specific_payload(struct cwmsg *msg, int vendor_ //void cwsend_discovery_response(struct conn * conn,int seqnum, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo); // -extern void cwsend_discovery_response(struct conn *conn, int seqnum, struct radioinfo *radioinfo, - struct ac_info *acinfo, struct wtpinfo *wtpinfo); +extern void cwsend_discovery_response(struct conn *conn, int seqnum, + struct radioinfo *radioinfo, struct ac_info *acinfo, + struct wtpinfo *wtpinfo); extern int cwsend_discovery_request(struct conn *conn, struct radioinfo *radioinfo, struct wtpinfo *wtpinfo); -extern void cwsend_join_response(struct conn *conn, int seqnum, int rc, struct radioinfo *radioinfo, - struct ac_info *acinfo, struct wtpinfo *wtpinfo); +extern void cwsend_join_response(struct conn *conn, int seqnum, int rc, + struct radioinfo *radioinfo, struct ac_info *acinfo, + struct wtpinfo *wtpinfo); extern void cwread_discovery_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len); @@ -375,14 +401,16 @@ extern void cwread_discovery_response(struct ac_info *acinfo, uint8_t * msg, int extern void cwsend_image_data_response(struct conn *conn, int seqnum, int rc); extern int cwsend_image_data_request(struct conn *conn, struct cwimage_data *data, struct image_identifier *id); -extern int cwread_change_state_event_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len); +extern int cwread_change_state_event_request(struct wtpinfo *wtpinfo, uint8_t * msg, + int len); extern void cwsend_change_state_event_response(struct conn *conn, int seqnum, struct radioinfo *radioinfo); extern int cwread_wtp_event_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len); -extern void cwread_configuration_status_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len); +extern void cwread_configuration_status_request(struct wtpinfo *wtpinfo, uint8_t * msg, + int len); extern void cwsend_conf_status_response(struct conn *conn, int seqnum, int rc, - struct radioinfo *radioinfo, struct ac_info *acinfo, - struct wtpinfo *wtpinfo); + struct radioinfo *radioinfo, + struct ac_info *acinfo, struct wtpinfo *wtpinfo); extern void cwsend_unknown_response(struct conn *conn, int seqnum, int unknow_request); @@ -390,20 +418,24 @@ extern void cwsend_unknown_response(struct conn *conn, int seqnum, int unknow_re extern int hdr_print(char *str, uint8_t * packet, int len); -extern int cw_readelem_ecn_support(uint8_t * ecn_support, int type, uint8_t * msgelem, int len); -extern int cw_readelem_maximum_message_length(uint16_t * dst, int type, uint8_t * msgelem, int len); +extern int cw_readelem_ecn_support(uint8_t * ecn_support, int type, uint8_t * msgelem, + int len); +extern int cw_readelem_maximum_message_length(uint16_t * dst, int type, uint8_t * msgelem, + int len); extern int cw_readelem_ac_name(uint8_t ** dst, int type, uint8_t * msgelem, int len); extern int cw_readelem_wtp_reboot_statistics(struct wtp_reboot_statistics *s, int type, uint8_t * msgelem, int len); -extern int cw_readelem_cw_local_ip_addr(struct sockaddr *local_ip, int type, uint8_t * msgelem, - int len); +extern int cw_readelem_cw_local_ip_addr(struct sockaddr *local_ip, int type, + uint8_t * msgelem, int len); extern int cw_readelem_radio_administrative_state(struct radioinfo *radioinfo, int type, uint8_t * msgelem, int len); extern int cw_readelem_radio_operational_state(struct radioinfo *radioinfo, int type, uint8_t * msgelem, int len); -extern int cw_readelem_statistics_timer(uint16_t * timer, int type, uint8_t * msgelem, int len); -extern int cw_readelem_result_code(uint32_t * result_code, int type, uint8_t * msgelem, int len); +extern int cw_readelem_statistics_timer(uint16_t * timer, int type, uint8_t * msgelem, + int len); +extern int cw_readelem_result_code(uint32_t * result_code, int type, uint8_t * msgelem, + int len); extern int cw_readelem_mtu_discovery_padding(int type, uint8_t * msgelem, int len); extern int cw_readelem_vendor_specific_payload(void *data, int msgtype, int elemtype, uint8_t * msgelem, int len); @@ -424,14 +456,14 @@ extern int cw_readelem_vendor_specific_payload(void *data, int msgtype, int elem #define CW_RESULT_JOIN_RESOURCE_DEPLETION 4 #define CW_RESULT_JOIN_UNKNOWN_SOURCE 5 #define CW_RESULT_JOIN_FAILURE_INCORRECT_DATA 6 -#define CW_RESULT_JOIN_FAILURE_SESSION_ALREADY_IN_USE 7 -#define CW_RESULT_JOIN_FAILURE_WTP_HARDWARE_NOT_SUPPORTED 8 -#define CW_RESULT_JOIN_FAILURE_BINDING_NOT_SUPPORTED 9 -#define CW_RESULT_RESET_FAILURE_UNABLE_TO_RESET 10 +#define CW_RESULT_JOIN_FAILURE_SESSION_ALREADY_IN_USE 7 +#define CW_RESULT_JOIN_FAILURE_WTP_HARDWARE_NOT_SUPPORTED 8 +#define CW_RESULT_JOIN_FAILURE_BINDING_NOT_SUPPORTED 9 +#define CW_RESULT_RESET_FAILURE_UNABLE_TO_RESET 10 -#define CW_RESULT_RESET_FAILURE_FIRMWARE_WRITE_ERROR 11 +#define CW_RESULT_RESET_FAILURE_FIRMWARE_WRITE_ERROR 11 -#define CW_RESULT_CONFIGURATION_FAILURE 12 //Configuration Failure (Unable to Apply Requested Configuration +#define CW_RESULT_CONFIGURATION_FAILURE 12 //Configuration Failure (Unable to Apply Requested Configuration // - Service Provided Anyhow) /* @@ -464,18 +496,20 @@ extern int cw_readelem_vendor_specific_payload(void *data, int msgtype, int elem extern void cw_read_image_data_request(struct cwimage_data *, uint8_t * msg, int len); -extern int cw_readelem_ac_descriptor(struct ac_info *acinfo, int type, uint8_t * msgelem, int len); -extern int cw_readelem_capwap_local_ip_addr(struct sockaddr *local_ip, int type, uint8_t * msgelem, - int len); +extern int cw_readelem_ac_descriptor(struct ac_info *acinfo, int type, uint8_t * msgelem, + int len); +extern int cw_readelem_capwap_local_ip_addr(struct sockaddr *local_ip, int type, + uint8_t * msgelem, int len); -extern int cw_send_echo_response(struct conn *conn, int seqnum, struct radioinfo *radioinfo); +extern int cw_send_echo_response(struct conn *conn, int seqnum, + struct radioinfo *radioinfo); extern int cw_handle_echo_request(void *d); extern void cw_send_image_file(struct conn *conn, FILE * infile); extern int cw_readmsg_configuration_status_response(uint8_t * elems, int elems_len); -extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len); +extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_len); @@ -521,6 +555,7 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len) #define cw_get_hdr_flag_t(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_T ) ? 1:0) #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_msg_id(msgptr) (cw_get_dword(msgptr)) #define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr) @@ -529,8 +564,33 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len) #define cw_get_msg_elems_len(msgptr) ( cw_get_word( (msgptr) +5 )-3) #define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8) -static inline uint8_t * cw_get_hdr_msg_elems_ptr(uint8_t *m){ - return cw_get_msg_elems_ptr( m+cw_get_hdr_msg_offset(m) ); + +#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); +#define cw_set_msg_elems_len(msgptr,n) (cw_put_word((msgptr)+5,(n+3))) + +#define cw_set_msg_flags(msgptr,f) (cw_put_byte( (msgptr)+7,f)) + +static inline uint8_t *cw_get_hdr_msg_elems_ptr(uint8_t * m) +{ + return cw_get_msg_elems_ptr(m + cw_get_hdr_msg_offset(m)); +} + +static inline int cw_get_hdr_msg_total_len(uint8_t * rawmsg) +{ + + int offset = cw_get_hdr_msg_offset(rawmsg); + return offset + cw_get_msg_elems_len(rawmsg + offset)+8 ; } /** @@ -593,8 +653,8 @@ static inline uint8_t * cw_get_hdr_msg_elems_ptr(uint8_t *m){ * @len length of vendor specific data * @return the number of bytes put (always 10) */ -static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid, uint16_t elemid, - uint16_t len) +static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid, + uint16_t elemid, uint16_t len) { cw_put_elem_hdr(dst, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, len + 6); @@ -604,6 +664,11 @@ static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid, uint1 } + +#define cw_put_sockaddr lw_put_sockaddr + + + /** * Add a message element to a buffer * @param dst pointer to buffer @@ -625,19 +690,19 @@ static inline int cw_addelem_bstr(uint8_t * dst, uint16_t type, const bstr_t bst } -static inline int cw_addelem_result_code(uint8_t *dst,uint32_t code) +static inline int cw_addelem_result_code(uint8_t * dst, uint32_t code) { - cw_put_dword(dst+4,code); - return 4+ cw_put_elem_hdr(dst, CW_ELEM_RESULT_CODE, 4); + cw_put_dword(dst + 4, code); + return 4 + cw_put_elem_hdr(dst, CW_ELEM_RESULT_CODE, 4); } -static inline int cw_addelem_radio_operational_state(uint8_t *dst, struct radioinfo * ri) +static inline int cw_addelem_radio_operational_state(uint8_t * dst, struct radioinfo *ri) { - cw_put_byte(dst+4+0,ri->rid); - cw_put_byte(dst+4+1,ri->state); - cw_put_byte(dst+4+2,ri->cause); - return 3+ cw_put_elem_hdr(dst, CW_ELEM_RADIO_OPERATIONAL_STATE, 3); + cw_put_byte(dst + 4 + 0, ri->rid); + cw_put_byte(dst + 4 + 1, ri->state); + cw_put_byte(dst + 4 + 2, ri->cause); + return 3 + cw_put_elem_hdr(dst, CW_ELEM_RADIO_OPERATIONAL_STATE, 3); } @@ -660,16 +725,20 @@ static inline int cw_addelem_radio_operational_state(uint8_t *dst, struct radioi cw_put_data(dst+10,data,len)) */ -extern int cw_addelem_vendor_specific_payload(uint8_t * dst, uint32_t vendorid, uint16_t elemid, - uint8_t * data, uint16_t len); +extern int cw_addelem_vendor_specific_payload(uint8_t * dst, uint32_t vendorid, + uint16_t elemid, uint8_t * data, + uint16_t len); -extern void cw_prepare_configuration_status_request(struct conn *conn, struct radioinfo *radioinfo, +extern void cw_prepare_configuration_status_request(struct conn *conn, + struct radioinfo *radioinfo, struct wtpinfo *wtpinfo); -extern void cw_prepare_change_state_event_request(struct conn *conn, struct radioinfo *radioinfo, +extern void cw_prepare_change_state_event_request(struct conn *conn, + struct radioinfo *radioinfo, struct wtpinfo *wtpinfo); -extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,struct radioinfo * radioinfo); +extern int cw_send_configuration_update_response(struct conn *conn, int seqnum, + struct radioinfo *radioinfo); #define cw_addelem_ac_name(dst,name) \ @@ -701,31 +770,62 @@ extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,s /* Message to text stuff */ -struct cw_strlist { +struct cw_strlist { uint32_t id; - const char * str; + const char *str; }; -extern const char * cw_strlist_get_str(struct cw_strlist *s,int id); +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[]; #define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id) +#define cw_strelem(id) cw_strlist_get_str(capwap_strings_elem,id) #define cw_strstate(id) cw_strlist_get_str(capwap_strings_state,id) #define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,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); -extern int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len); -extern int cw_in_wtp_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len); -extern int cw_in_wtp_board_data(struct conn *conn, struct cw_action *a, uint8_t * data, int len); +extern int cw_in_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len); +extern int cw_in_vendor_specific_payload(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len); +extern int cw_in_wtp_name(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len); +extern int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len); +extern int cw_in_wtp_descriptor(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, + 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); + + + +struct cw_ac_status { + int stations; + int limit; + int active_wtps; + int max_wtps; + int security; + int rmac_field; + int dtls_policy; +}; + +int cw_register_actions_capwap_ac(struct cw_actiondef *def); #endif diff --git a/src/capwap/capwap_items.h b/src/capwap/capwap_items.h index 31dad855..c85ac995 100644 --- a/src/capwap/capwap_items.h +++ b/src/capwap/capwap_items.h @@ -1,3 +1,5 @@ +#ifndef __CAPWAP_ITEMS_H +#define __CAPWAP_ITEMS_H enum capwap_items { CW_ITEM_NONE=0, @@ -8,6 +10,37 @@ enum capwap_items { CW_ITEM_WTP_BOARD_MACADDRESS, CW_ITEM_WTP_BOARD_ID, CW_ITEM_WTP_BOARD_REVISION, - CW_ITEM_WTP_BOARD_SERIALNO + CW_ITEM_WTP_BOARD_SERIALNO, + CW_ITEM_WTP_MAC_TYPE, + CW_ITEM_WTP_FRAME_TUNNEL_MODE, + CW_ITEM_WTP_RADIOS_IN_USE, + CW_ITEM_WTP_MAX_RADIOS, + CW_ITEM_WTP_HARDWARE_VENDOR, + CW_ITEM_WTP_HARDWARE_VERSION, + CW_ITEM_WTP_SOFTWARE_VENDOR, + CW_ITEM_WTP_SOFTWARE_VERSION, + CW_ITEM_WTP_BOOTLOADER_VENDOR, + CW_ITEM_WTP_BOOTLOADER_VERSION, + CW_ITEM_WTP_OTHERSOFTWARE_VENDOR, + CW_ITEM_WTP_OTHERSOFTWARE_VERSION, + + CW_ITEM_AC_NAME, + CW_ITEM_AC_DESCRIPTOR, + CW_ITEM_RESULT_CODE, + CW_ITEM_AC_STATUS, + + CW_ITEM_AC_HARDWARE_VERSION, + CW_ITEM_AC_SOFTWARE_VERSION, + + CW_ITEM_AC_IP_LIST, + CW_ITEM_CAPWAP_CONTROL_IP_LIST, + + CW_ITEM_LOCATION_DATA, + CW_ITEM_SESSION_ID, + + }; + + +#endif diff --git a/src/capwap/capwap_strings_elem.c b/src/capwap/capwap_strings_elem.c index 108df66c..8f7a37f6 100644 --- a/src/capwap/capwap_strings_elem.c +++ b/src/capwap/capwap_strings_elem.c @@ -12,8 +12,8 @@ struct cw_strlist capwap_strings_elem[] = { {CW_ELEM_ADD_MAC_ACL_ENTRY, "Add MAC ACL Entry"}, {CW_ELEM_ADD_STATION, "Add Station"}, {CW_ELEM_RESERVED_9, "Reserved 9"}, - {CW_ELEM_CONTROL_IPV4_ADDRESS, "Control IPv4 Address"}, - {CW_ELEM_CONTROL_IPV6_ADDRESS, "Controll IPv6 Address"}, + {CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS, "Control IPv4 Address"}, + {CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS, "Controll IPv6 Address"}, {CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS, "CAWPAP Local IPv4 Address"}, {CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS, "CAPWAP Local IPv6 Address"}, {CW_ELEM_CAPWAP_TIMERS, "CAPWAP Timers"}, @@ -34,7 +34,7 @@ struct cw_strlist capwap_strings_elem[] = { {CW_ELEM_IMAGE_IDENTIFIER, "Image Identifier"}, {CW_ELEM_IMAGE_INFORMATION, "Image Information"}, {CW_ELEM_INITIATE_DOWNLOAD, "Initiate Download"}, - {CWMSGELEM_LOCATION_DATA, "Location Data"}, + {CW_ELEM_LOCATION_DATA, "Location Data"}, {CWMSGELEM_MAXIMUM_MESSAGE_LENGTH, "Maximum Message Length"}, {CWMSGELEM_MTU_DISCOVERY_PADDING, "MTU Discovery Padding"}, {CWMSGELEM_RADIO_ADMINISTRATIVE_STATE, "Radio Administrative State"}, diff --git a/src/capwap/conn.h b/src/capwap/conn.h index 2898cb40..e4581fde 100644 --- a/src/capwap/conn.h +++ b/src/capwap/conn.h @@ -31,7 +31,7 @@ #include "wtpinfo.h" -#include "cw_action.h" +#include "action.h" #include "itemstore.h" @@ -42,8 +42,13 @@ struct conn { cw_itemstore_t itemstore; + cw_itemstore_t local; + cw_itemstore_t remote; - struct avltree *msgtr; + + struct cw_actiondef *actions; + +// struct avltree *msgtr; uint8_t capwap_state; @@ -72,8 +77,11 @@ struct conn { struct cwmsg req_msg; struct cwmsg resp_msg; uint8_t req_buffer[65536]; - uint8_t resp_buffer[65536]; + /** Buffer for outgoing response messages */ + uint8_t resp_buffer[65536]; + + int mtu; /* max mtu, could be changed during discovery */ int mtu_discovery; /* 0 mtu discovery turned off, 1 discovery tuned on */ diff --git a/src/capwap/conn_process_packet.c b/src/capwap/conn_process_packet.c index 826156a1..bfe9f2af 100644 --- a/src/capwap/conn_process_packet.c +++ b/src/capwap/conn_process_packet.c @@ -203,7 +203,7 @@ void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)( cwrmsg.rid=(val>>14) & 0x1f; */ -printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet)); +//printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet)); /* Check Radio MAC if preset */ if (cw_get_hdr_flag_m(packet)){ @@ -229,8 +229,8 @@ printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet)); cw_dbg_packet(conn,f+4,*(uint32_t*)f); - extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); - cw_process_msg(conn,f+4,*(uint32_t*)f); + // extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); + // cw_process_msg(conn,f+4,*(uint32_t*)f); printf("Received a fragmented packetm should process it"); exit(0); @@ -247,8 +247,8 @@ exit(0); return; } -extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); -cw_process_msg(conn,packet,len); +//extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); +//cw_process_msg(conn,packet,len); //if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,packet+hlen,len-hlen) ){ @@ -256,7 +256,6 @@ cw_process_msg(conn,packet,len); // return; //} -printf("Next big thing\n"); //msg_4*((val >> 19) & 0x1f); process_message(conn,packet,len,cb,cbarg); return; diff --git a/src/capwap/cw_action.c b/src/capwap/cw_action.c deleted file mode 100644 index 049c900c..00000000 --- a/src/capwap/cw_action.c +++ /dev/null @@ -1,80 +0,0 @@ - -#include -#include - -#include "cw_action.h" - -static inline int cw_action_cmp(const void *elem1,const void *elem2) -{ - struct cw_action * e1 = (struct cw_action*)elem1; - struct cw_action * e2 = (struct cw_action*)elem2; - int r; - - r = e1->elem_id - e2->elem_id; - if (r!=0) - return r; - - r = e1->msg_id - e2->msg_id; - if (r!=0) - return r; - - r = e1->capwap_state - e2->capwap_state; - if (r!=0) - return r; - - r = e1->vendor_id - e2->vendor_id; - if (r!=0) - return r; - - - return 0; -} - -/* -static void cw_action_del(void*d) -{ - free(d); -} -*/ - -cw_action_t * cw_actionlist_add(cw_actionlist_t t, struct cw_action * a) -{ - struct cw_action *an = malloc(sizeof(struct cw_action)); - if (!an) - return NULL; - - memcpy(an,a,sizeof(struct cw_action)); - return avltree_add(t,an); -} - - -struct cw_action * cw_actionlist_get(cw_actionlist_t t,struct cw_action *a) -{ - return avltree_get(t,a); -} - - -cw_actionlist_t cw_actionlist_create() -{ - return avltree_create(cw_action_cmp,free); //cw_action_del); -} - - -int cw_register_actions(cw_actionlist_t t,cw_action_t * actions) -{ - while(actions->capwap_state){ -// cw_action_t *a = actions; -// printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id); - cw_action_t * rc = cw_actionlist_add(t,actions); - if (rc==0) - return 0; - actions++; - } - return 1; -} - - - - - - diff --git a/src/capwap/cw_action.h b/src/capwap/cw_action.h deleted file mode 100644 index 0516a2b8..00000000 --- a/src/capwap/cw_action.h +++ /dev/null @@ -1,45 +0,0 @@ - -#ifndef __MSGTREE_H -#define __MSGTREE_H - - -#include - -#include "avltree.h" -#include "conn.h" - -struct cw_action{ - uint32_t vendor_id; - uint8_t proto; - uint8_t capwap_state; - uint32_t msg_id; - uint16_t elem_id; - - int (*start)(struct conn *conn,struct cw_action *a,uint8_t*data,int len); - int (*end)(struct conn *conn,struct cw_action *a,uint8_t*elem,int len); - - uint16_t min_len; - uint16_t max_len; - - uint8_t capwap_state_next; - - - const char *name; -}; -typedef struct cw_action cw_action_t; - - -typedef struct avltree * cw_actionlist_t; - - -extern cw_actionlist_t cw_actionlist_create(); -extern cw_action_t * cw_actionlist_get(cw_actionlist_t t,cw_action_t *a); -extern cw_action_t * cw_actionlist_add(cw_actionlist_t t,cw_action_t *a); -extern int cw_register_actions(cw_actionlist_t t,cw_action_t * actions); - -int check(uint8_t *elem,int len); - - -#endif - - diff --git a/src/capwap/cw_in_vendor_specific_payload.c b/src/capwap/cw_in_vendor_specific_payload.c index a72c7814..777edb15 100644 --- a/src/capwap/cw_in_vendor_specific_payload.c +++ b/src/capwap/cw_in_vendor_specific_payload.c @@ -9,16 +9,16 @@ /** * Default handler for Vendor Specific Payload message elements. */ -int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len) +int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) { - cw_action_t as,*af; + cw_action_in_t as,*af; as = *a; 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); +// printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id); - af = cw_actionlist_get(conn->msgtr,&as); + af = cw_actionlist_in_get(conn->actions->in,&as); if (!af) { cw_log(DBG_ELEM,"Can't handle Vendor Specific Payload %s/%d, in msg %d (%s) in %s state.", diff --git a/src/capwap/cw_in_wtp_name.c b/src/capwap/cw_in_wtp_name.c index 63e7742d..67d80de6 100644 --- a/src/capwap/cw_in_wtp_name.c +++ b/src/capwap/cw_in_wtp_name.c @@ -4,7 +4,7 @@ #include "itemstore.h" -int cw_in_wtp_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len) +int cw_in_wtp_name(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) { if (len > 512){ cw_dbg(DBG_CW_RFC, "WTP Name too long, must not exceed 512, len is %d",len); diff --git a/src/capwap/cw_log_debug.c b/src/capwap/cw_log_debug.c index 4e8eed29..091a2c1f 100644 --- a/src/capwap/cw_log_debug.c +++ b/src/capwap/cw_log_debug.c @@ -307,25 +307,25 @@ void cw_dbg_msgelem_(int msg, int msgelem, const uint8_t * msgbuf, int len) uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf)); int type = ntohs(*((uint16_t *) (msgbuf + 4))); sprintf(vendorname, "%s/%s/%d", - (char *) cw_msgelemtostr(msgelem), + (char *) cw_strelem(msgelem), (char *) lw_vendor_id_to_str(vendor_id), type); elemname = vendorname; cw_format_vendor(vendor_details, vendor_id, type, msgbuf); } else { - elemname = cw_msgelemtostr(msgelem); + elemname = cw_strelem(msgelem); } if (!cw_dbg_is_level(DBG_ELEM_DMP)) cw_dbg(DBG_ELEM, "%s, CAWPAP element: type=%d (%s), len=%d%s", - cw_msgtostr(msg), msgelem, elemname, len, vendor_details); + cw_strmsg(msg), msgelem, elemname, len, vendor_details); else cw_dbg_dmp(DBG_ELEM, msgbuf, len, "%s, CAPWAP element: type=%d (%s), len=%d%s\n\tDump ...", - cw_msgtostr(msg), msgelem, elemname, len, vendor_details); + cw_strmsg(msg), msgelem, elemname, len, vendor_details); } @@ -369,6 +369,6 @@ void cw_dbg_missing_mand_elems_(struct conn *conn, int msgtype, int *mand) if (cw_is_missing_mand_elems(mand)) { char str[512]; cw_get_missing_mand_elems(str, mand); - cw_dbg(DBG_CW_RFC, "Missing msgelems in %s: %s", cw_msgtostr(msgtype), str); + cw_dbg(DBG_CW_RFC, "Missing msgelems in %s: %s", cw_strmsg(msgtype), str); } } diff --git a/src/capwap/cw_log_str2dbglevel.c b/src/capwap/cw_log_str2dbglevel.c index abd31438..f230f2ed 100644 --- a/src/capwap/cw_log_str2dbglevel.c +++ b/src/capwap/cw_log_str2dbglevel.c @@ -26,8 +26,8 @@ struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = { {"info",DBG_CW_INFO}, {"msg",DBG_MSG}, - {"msgelem",DBG_ELEM}, - {"msgelem_dmp",DBG_ELEM_DMP}, + {"elem",DBG_ELEM}, + {"elem_dmp",DBG_ELEM_DMP}, {"rfc",DBG_CW_RFC}, {"pkt_in",DBG_CW_PKT_IN}, {"pkt_out",DBG_CW_PKT_OUT}, diff --git a/src/capwap/cw_process_msg.c b/src/capwap/cw_process_msg.c index 76df698b..321e0e12 100644 --- a/src/capwap/cw_process_msg.c +++ b/src/capwap/cw_process_msg.c @@ -4,19 +4,190 @@ #include "conn.h" #include "capwap.h" +#include "capwap_items.h" + #include "sock.h" -#include "cw_action.h" +#include "action.h" #include "cw_log.h" +#include "dbg.h" - -int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) +int snd_cb(void *c, void *d) { - struct cw_action as,*af; + 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 cw_send_response(struct conn *conn, uint8_t * rawmsg, int len) +{ + struct priv priv; + + cw_init_response(conn, 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)); + + + 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); + + conn_send_msg(conn, conn->resp_buffer); + + 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"); +*/ +} + + +int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len) +{ + struct cw_action_in as, *af,*afm; + + uint8_t *msg_ptr = rawmsg + cw_get_hdr_msg_offset(rawmsg); int elems_len = cw_get_msg_elems_len(msg_ptr); /* @@ -44,62 +215,64 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) */ - + /* prepare struct for search operation */ - as.elem_id=-1; - as.capwap_state=conn->capwap_state; + as.capwap_state = conn->capwap_state; as.msg_id = cw_get_msg_id(msg_ptr); - as.vendor_id=0; + as.vendor_id = 0; + as.elem_id = -1; + as.proto=0; /* Search for state/message combination */ - af = cw_actionlist_get(conn->msgtr,&as); + afm = cw_actionlist_in_get(conn->actions->in, &as); - /* Check if message is comes in right state */ - if ( !af ){ - cw_dbg(DBG_MSG_ERR,"Message type %d (%s) not allowed in %s State.", - as.msg_id,cw_strmsg(as.msg_id),cw_strstate(as.capwap_state)); + /* Check if message comes in right state */ + if (!afm) { + cw_dbg(DBG_MSG_ERR, "Message type %d (%s) not allowed in %s State.", + as.msg_id, cw_strmsg(as.msg_id), cw_strstate(as.capwap_state)); return 0; } - if (af->start){ - af->start(conn,af,rawmsg,len); + /* Execute start processor for message */ + if (afm->start) { + afm->start(conn, afm, rawmsg, len); } - uint8_t * elems_ptr = cw_get_msg_elems_ptr(msg_ptr); - - - + uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr); uint8_t *elem; - cw_foreach_elem(elem,elems_ptr,elems_len) { + cw_foreach_elem(elem, elems_ptr, elems_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); - af = cw_actionlist_get(conn->msgtr,&as); - + af = cw_actionlist_in_get(conn->actions->in, &as); + if (!af) { - cw_dbg(DBG_ELEM_ERR,"Element %d not aallowed in msg %d (%s)",as.elem_id,as.msg_id,cw_strmsg(as.msg_id)); + cw_dbg(DBG_ELEM_ERR, "Element %d not allowed in msg %d (%s)", + as.elem_id, as.msg_id, cw_strmsg(as.msg_id)); continue; } - printf("Elem OK: %d, %d\n",as.elem_id,elem_len); if (af->start) { - af->start(conn,af,cw_get_elem_data(elem),elem_len); + af->start(conn, af, cw_get_elem_data(elem), elem_len); } } + cw_send_response(conn, rawmsg, len); + + if (afm->end) { + afm->end(conn, afm, rawmsg, len); + } + + return 0; } - - - - - diff --git a/src/capwap/cw_read_image_data_request.c b/src/capwap/cw_read_image_data_request.c index 45f6288f..c6cfd8c9 100644 --- a/src/capwap/cw_read_image_data_request.c +++ b/src/capwap/cw_read_image_data_request.c @@ -54,7 +54,7 @@ static int imgdata_request(void * ptr,int type,uint8_t* msgelem,int len) cw_dbg_msgelem(CW_MSG_IMAGE_DATA_REQUEST, type, msgelem, len); - cw_dbg(DBG_ALL,"Reading image data req msgelem, type=%d - %s ,len=%d\n",type,cw_msgelemtostr(type),len); + cw_dbg(DBG_ALL,"Reading image data req msgelem, type=%d - %s ,len=%d\n",type,cw_strelem(type),len); if (cw_readelem_image_identifier(ptr,type,msgelem,len)) return 1; diff --git a/src/capwap/cw_readelem_capwap_local_ip_addr.c b/src/capwap/cw_readelem_capwap_local_ip_addr.c index 43e57695..7a703d8e 100644 --- a/src/capwap/cw_readelem_capwap_local_ip_addr.c +++ b/src/capwap/cw_readelem_capwap_local_ip_addr.c @@ -8,7 +8,7 @@ int cw_readelem_capwap_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t * msgelem, int len) { switch (type){ - case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS: + case CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS: case CW_ELEM_WTP_IPV4_IP_ADDRESS: { if (len!=4) @@ -23,7 +23,7 @@ int cw_readelem_capwap_local_ip_addr(struct sockaddr * local_ip, int type, uint8 return 1; } #ifdef WITH_IPV6 - case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS: + case CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS: case CW_ELEM_WTP_IPV6_IP_ADDRESS: { if (len!=16) diff --git a/src/capwap/cw_util.c b/src/capwap/cw_util.c index 19bb44a5..321714e9 100644 --- a/src/capwap/cw_util.c +++ b/src/capwap/cw_util.c @@ -48,7 +48,7 @@ void cw_get_missing_mand_elems(char *dst, int *l) const char * k = ""; for (i=0; l[i]!=-1; i++){ if(l[i]){ - s += sprintf(s,"%s[%s]",k,cw_msgelemtostr(l[i])); + s += sprintf(s,"%s[%s]",k,cw_strelem(l[i])); k=","; } diff --git a/src/capwap/cw_util.h b/src/capwap/cw_util.h index 9f78849d..3c6d5c2b 100644 --- a/src/capwap/cw_util.h +++ b/src/capwap/cw_util.h @@ -61,7 +61,6 @@ void cw_get_missing_mand_elems(char *dst, int *l); -extern const char * cw_msgelemtostr(int elem); extern const char * cw_msgtostr(int type); #endif diff --git a/src/capwap/cwmsg_addelem_ctrl_ip_addrs.c b/src/capwap/cwmsg_addelem_ctrl_ip_addrs.c index bab62b48..ae7e506c 100644 --- a/src/capwap/cwmsg_addelem_ctrl_ip_addrs.c +++ b/src/capwap/cwmsg_addelem_ctrl_ip_addrs.c @@ -26,34 +26,34 @@ #include "sock.h" //static int cwmsg_addelem_acip(struct cwmsg * msg,ACIP *ip,int ctr) -static int cwmsg_addelem_acip(void * priv,void *data) //,int ctr) +static int cwmsg_addelem_acip(void *priv, void *data) //,int ctr) { -// cw_log_debug2("Adding Ctrl IP %s",sock_addr2str((struct sockaddr*)data)); +// cw_log_debug2("Adding Ctrl IP %s",sock_addr2str((struct sockaddr*)data)); - struct cwmsg * msg = (struct cwmsg*)priv; - ACIP * acip = (ACIP*)data; + struct cwmsg *msg = (struct cwmsg *) priv; + ACIP *acip = (ACIP *) data; - uint8_t ipmsg [18]; + uint8_t ipmsg[18]; - switch (acip->ip.ss_family){ + switch (acip->ip.ss_family) { case AF_INET: - { - struct sockaddr_in * sain = (struct sockaddr_in*)&acip->ip; - memcpy(ipmsg,&sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr)); - *((uint16_t*)(ipmsg+4))= htons(acip->wtp_count); /* number of wtps */ - cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV4_ADDRESS,ipmsg,6); - } - break; -#ifdef WITH_IPV6 + { + struct sockaddr_in *sain = (struct sockaddr_in *) &acip->ip; + memcpy(ipmsg, &sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr)); + *((uint16_t *) (ipmsg + 4)) = htons(acip->wtp_count); /* number of wtps */ + cwmsg_addelem(msg, CW_ELEM_CONTROL_IPV4_ADDRESS, ipmsg, 6); + } + break; +#ifdef WITH_IPV6 case AF_INET6: - { - struct sockaddr_in6 * sain = (struct sockaddr_in6*)&acip->ip; - memcpy(ipmsg,&sain->sin6_addr.s6_addr, sizeof(sain->sin6_addr.s6_addr)); - *((uint16_t*)(ipmsg+16))= htons(acip->wtp_count); /* number of wtps */ - cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV6_ADDRESS,ipmsg,18); - } - break; -#endif + { + struct sockaddr_in6 *sain = (struct sockaddr_in6 *) &acip->ip; + memcpy(ipmsg, &sain->sin6_addr.s6_addr, sizeof(sain->sin6_addr.s6_addr)); + *((uint16_t *) (ipmsg + 16)) = htons(acip->wtp_count); /* number of wtps */ + cwmsg_addelem(msg, CW_ELEM_CONTROL_IPV6_ADDRESS, ipmsg, 18); + } + break; +#endif } return 1; } @@ -61,8 +61,8 @@ static int cwmsg_addelem_acip(void * priv,void *data) //,int ctr) void cwmsg_addelem_ctrl_ip_addrs(struct cwmsg *msg, struct ac_info *acinfo) { -// printf("Counter in the list: %i\n",acinfo->aciplist->count); - aciplist_foreach(acinfo->aciplist,cwmsg_addelem_acip,msg); +// printf("Counter in the list: %i\n",acinfo->aciplist->count); + aciplist_foreach(acinfo->aciplist, cwmsg_addelem_acip, msg); } diff --git a/src/capwap/cwmsg_addelem_cw_local_ip_addr.c b/src/capwap/cwmsg_addelem_cw_local_ip_addr.c index 37899579..980abe0b 100644 --- a/src/capwap/cwmsg_addelem_cw_local_ip_addr.c +++ b/src/capwap/cwmsg_addelem_cw_local_ip_addr.c @@ -48,7 +48,7 @@ cw_mode = CWMODE_CISCO; if (cw_mode == CWMODE_CISCO) id = CW_ELEM_WTP_IPV4_IP_ADDRESS; else - id = CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS; + id = CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS; printf("Sending local ip %s\n",sock_addr2str(sain)); @@ -63,7 +63,7 @@ printf("Sending local ip %s\n",sock_addr2str(sain)); if (cw_mode == CWMODE_CISCO) id = CW_ELEM_WTP_IPV6_IP_ADDRESS; else - id = CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS; + id = CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS; struct sockaddr_in6 * sain = (struct sockaddr_in6*)&a; return cwmsg_addelem(msg,id,(uint8_t*)&sain->sin6_addr,16); } diff --git a/src/capwap/cwmsg_addelem_wtp_descriptor.c b/src/capwap/cwmsg_addelem_wtp_descriptor.c index 408ef270..ba6bb9fc 100644 --- a/src/capwap/cwmsg_addelem_wtp_descriptor.c +++ b/src/capwap/cwmsg_addelem_wtp_descriptor.c @@ -50,15 +50,15 @@ void cwmsg_addelem_wtp_descriptor(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo /* hardware version subelem*/ - len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION, + len+=wtpdesc_addsubelem(d+len,CW_SUBELEM_WTP_HARDWARE_VERSION, wtpinfo->hardware_vendor_id,wtpinfo->hardware_version); /* software version subelem*/ - len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION, + len+=wtpdesc_addsubelem(d+len,CW_SUBELEM_WTP_SOFTWARE_VERSION, wtpinfo->software_vendor_id,wtpinfo->software_version); /* bootloader version subelem*/ - len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION, + len+=wtpdesc_addsubelem(d+len,CW_SUBELEM_WTP_BOOTLOADER_VERSION, wtpinfo->bootloader_vendor_id,wtpinfo->bootloader_version); cwmsg_addelem(cwmsg,CW_ELEM_WTP_DESCRIPTOR,d,len); diff --git a/src/capwap/cwsend_join_response.c b/src/capwap/cwsend_join_response.c index c7e10323..b3758a3d 100644 --- a/src/capwap/cwsend_join_response.c +++ b/src/capwap/cwsend_join_response.c @@ -19,7 +19,7 @@ void cwsend_join_response(struct conn *conn, int seqnum, int rc, struct radioinf cwmsg_addelem_ac_descriptor(cwmsg, acinfo,wtpinfo); cwmsg_addelem(cwmsg, CW_ELEM_AC_NAME, acinfo->ac_name, strlen((char *) acinfo->ac_name)); cwmsg_addelem(cwmsg, CWMSGELEM_ECN_SUPPORT, &acinfo->ecn_support, sizeof(uint8_t)); - cwmsg_addelem_ctrl_ip_addrs(cwmsg, acinfo); +// cwmsg_addelem_ctrl_ip_addrs(cwmsg, acinfo); // cwmsg_addelem_cw_local_ip_addr(cwmsg,conn); diff --git a/src/capwap/itemstore.c b/src/capwap/itemstore.c index c9edfa51..70aed18f 100644 --- a/src/capwap/itemstore.c +++ b/src/capwap/itemstore.c @@ -8,38 +8,48 @@ static inline void cw_itemstore_del_data(void *e) { - struct cw_item * item = (struct cw_item*)e; - if (item->type==CW_ITEMTYPE_DATA) - free (item->data); - + struct cw_item *item = (struct cw_item *) e; + switch (item->type) { + case CW_ITEMTYPE_DATA: + case CW_ITEMTYPE_STR: + case CW_ITEMTYPE_BSTR: + case CW_ITEMTYPE_VERSION: + case CW_ITEMTYPE_FUN: + free(item->data); + break; + case CW_ITEMTYPE_AVLTREE: + avltree_destroy(item->data); + + + } } -static void cw_itemstore_del(void * e) +static void cw_itemstore_del(void *e) { cw_itemstore_del_data(e); - free(e); + free(e); } -static int cw_itemstore_cmp(const void *x1,const void*x2) +static int cw_itemstore_cmp(const void *x1, const void *x2) { - return ((struct cw_item*)x1)->id - ((struct cw_item*)x2)->id; + return ((struct cw_item *) x1)->id - ((struct cw_item *) x2)->id; } cw_itemstore_t cw_itemstore_create() { - return avltree_create(cw_itemstore_cmp,cw_itemstore_del); + return avltree_create(cw_itemstore_cmp, cw_itemstore_del); } -struct cw_item * cw_item_create(cw_itemstore_t s,uint32_t id) +struct cw_item *cw_item_create(cw_itemstore_t s, uint32_t id) { struct cw_item is; - is.id=id; + is.id = id; - struct cw_item *i=avltree_get(s,&is); + struct cw_item *i = avltree_get(s, &is); if (i) { cw_itemstore_del_data(i); return i; @@ -48,118 +58,184 @@ struct cw_item * cw_item_create(cw_itemstore_t s,uint32_t id) i = malloc(sizeof(struct cw_item)); if (!i) return 0; - i->id=id; - return avltree_add(s,i); + i->id = id; + return avltree_add(s, i); } -int cw_itemstore_set_byte(cw_itemstore_t s,uint32_t id,uint8_t byte) +int cw_itemstore_set_byte(cw_itemstore_t s, uint32_t id, uint8_t byte) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->byte=byte; - i->type=CW_ITEMTYPE_BYTE; + i->byte = byte; + i->type = CW_ITEMTYPE_BYTE; return 1; } -int cw_itemstore_set_word(cw_itemstore_t s,uint32_t id,uint32_t word) +int cw_itemstore_set_word(cw_itemstore_t s, uint32_t id, uint32_t word) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->word=word; - i->type=CW_ITEMTYPE_WORD; + i->word = word; + i->type = CW_ITEMTYPE_WORD; return 1; } -int cw_itemstore_set_dword(cw_itemstore_t s,uint32_t id,uint32_t dword) +int cw_itemstore_set_dword(cw_itemstore_t s, uint32_t id, uint32_t dword) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->dword=dword; - i->type=CW_ITEMTYPE_DWORD; + i->dword = dword; + i->type = CW_ITEMTYPE_DWORD; return 1; } -int cw_itemstore_set_str(cw_itemstore_t s,uint32_t id,char *str) +int cw_itemstore_set_str(cw_itemstore_t s, uint32_t id, const char *str) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->type=CW_ITEMTYPE_DATA; - i->data=strdup(str); + i->type = CW_ITEMTYPE_STR; + i->data = strdup(str); return 1; } -int cw_itemstore_set_strn(cw_itemstore_t s,uint32_t id,const char *str,int n) +int cw_itemstore_set_strn(cw_itemstore_t s, uint32_t id, const char *str, int n) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->type=CW_ITEMTYPE_DATA; - i->data=strndup(str,n); + i->type = CW_ITEMTYPE_DATA; + i->data = strndup(str, n); return 1; } -int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void*ptr) +int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void *ptr) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->type=CW_ITEMTYPE_DATA; - i->data=ptr; + i->type = CW_ITEMTYPE_DATA; + i->data = ptr; return 1; } -int cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t *data,int len) +int cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t * data, int len) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->type=CW_ITEMTYPE_DATA; - i->data=bstr_create(data,len); + i->type = CW_ITEMTYPE_BSTR; + i->data = bstr_create(data, len); return 1; } - -int cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void*ptr) + +int cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr) { - struct cw_item *i = cw_item_create(s,id); + struct cw_item *i = cw_item_create(s, id); if (!i) return 0; - i->type=CW_ITEMTYPE_CONST_DATA; - i->data=ptr; + i->type = CW_ITEMTYPE_CONST_DATA; + i->data = ptr; return 1; } - -/* - struct cw_item * i = malloc(sizeof(struct cw_item)); - if ( !i) + +int cw_itemstore_set_version(cw_itemstore_t s, uint32_t id, uint32_t vendor_id, + uint8_t * versionstr, int len) +{ + struct cw_item *i = cw_item_create(s, id); + if (!i) return 0; - i->id=id; - i->type=CW_ITEMTYPE_BYTE; - i->byte=byte; - struct cw_item * r = avltree_add(s,i); - if (r!=i) { - r->byte=byte; - free(i); + i->type = CW_ITEMTYPE_VERSION; + + uint8_t *ptr = malloc(bstr16_size(len) + 4); + i->data = ptr; + + if (!ptr) + return 1; + + *((uint32_t *) ptr) = vendor_id; + bstr16_ncpy(ptr + 4, versionstr, len); + + return 1; +} + +int cw_itemstore_set_avltree(cw_itemstore_t s, uint32_t id, struct avltree *t) +{ + struct cw_item *i = cw_item_create(s, id); + if (!i) + return 0; + i->type = CW_ITEMTYPE_AVLTREE; + i->data = t; + return 1; +} + + + +struct cw_item_fundef { + void *(*get) (void *arg); + void (*free) (void *arg, void *data); + void *arg; +}; + +int cw_itemstore_set_fun(cw_itemstore_t s, uint32_t id, + void *(*funget) (void *arg), + void (*funfree) (void *arg, void *data), void *arg) +{ + struct cw_item *i = cw_item_create(s, id); + if (!i) + return 0; + + struct cw_item_fundef *fundef = malloc(sizeof(struct cw_item_fundef)); + i->data = fundef; + if (!fundef) + return 0; + + fundef->get = funget; + fundef->free = funfree; + fundef->arg = arg; + i->type=CW_ITEMTYPE_FUN; + + return 1; +} + +void *cw_item_get_data_ptr(struct cw_item *item) +{ + switch (item->type) { + case CW_ITEMTYPE_FUN: + { + struct cw_item_fundef *fundef = + (struct cw_item_fundef *) item->data; + if (!fundef) + return NULL; + return fundef->get(fundef->arg); + } + } - return 1; -*/ - - -/* -char * cw_itemstore_get_str(cw_itemstore_t s,uint32_t id) -{ -// struct cw_item * item = avltree_get(s,id); + return item->data; } -*/ -//cw_itemstore_set_str( -// cw_item_t item = (cw_item_t) avltree_get(t,a); +void cw_item_release_data_ptr(struct cw_item *item, void *data) +{ + switch (item->type) { + case CW_ITEMTYPE_FUN: + { + struct cw_item_fundef *fundef = + (struct cw_item_fundef *) item->data; + if (!fundef) + return; + if (!fundef->free) + return; + return fundef->free(fundef->arg, data); + } + + } +} diff --git a/src/capwap/itemstore.h b/src/capwap/itemstore.h index 60c97aca..007c7065 100644 --- a/src/capwap/itemstore.h +++ b/src/capwap/itemstore.h @@ -32,7 +32,13 @@ enum cw_cfgtem_types{ CW_ITEMTYPE_WORD, CW_ITEMTYPE_DWORD, CW_ITEMTYPE_DATA, - CW_ITEMTYPE_CONST_DATA + CW_ITEMTYPE_CONST_DATA, + CW_ITEMTYPE_STR, + CW_ITEMTYPE_BSTR, + CW_ITEMTYPE_VERSION, + CW_ITEMTYPE_AVLTREE, + CW_ITEMTYPE_FUN, + }; struct cw_item { @@ -59,9 +65,20 @@ static inline struct cw_item * cw_itemstore_get(cw_itemstore_t s, uint32_t id) extern cw_itemstore_t cw_itemstore_create(); extern int cw_itemstore_set_strn(cw_itemstore_t s,uint32_t id,const char *str,int n); +extern int cw_itemstore_set_str(cw_itemstore_t s,uint32_t id,const char *str); extern int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void*ptr); extern int cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t *data,int len); extern int cw_itemstore_set_dword(cw_itemstore_t s,uint32_t id,uint32_t dword); +extern int cw_itemstore_set_byte(cw_itemstore_t s,uint32_t id,uint8_t byte); +extern int cw_itemstore_set_version(cw_itemstore_t s, uint32_t id, uint32_t vendor_id, uint8_t * versionstr, int len); + +extern void *cw_item_get_data_ptr(struct cw_item *item); +extern void cw_item_release_data_ptr(struct cw_item *item, void *data); + + +int cw_itemstore_set_fun(cw_itemstore_t s, uint32_t id, + void *(*funget) (void *arg), + void (*funfree) (void *arg, void *data), void *arg); #endif diff --git a/src/capwap/lw_checksum.c b/src/capwap/lw_checksum.c index 427b603d..bba05ae3 100644 --- a/src/capwap/lw_checksum.c +++ b/src/capwap/lw_checksum.c @@ -24,8 +24,9 @@ #include "lwapp.h" /** - * Calculate the 16-bit checksum for LWAPP image data message - * elements with opcode 3 - also used by Cisco in CAPWAP + * Calculate the 16-bit checksum for LWAPP Image Data message + * elements with opcode 3 (see RFC5412) + * This is also used by Cisco in CAPWAP * @param d pointer to data to calulate the checksum for * @param len length of data * @return the calculated checksum. @@ -48,3 +49,4 @@ uint16_t lw_checksum(uint8_t * d, int len) return (~sum) & 0xffff; } + diff --git a/src/capwap/lwapp.h b/src/capwap/lwapp.h index d378199f..42813bdd 100644 --- a/src/capwap/lwapp.h +++ b/src/capwap/lwapp.h @@ -167,6 +167,15 @@ #define lw_put_dword(dst,dw)\ (*((uint32_t*)(dst)) = htonl(dw),4) +#define lw_set_byte(dst,b) \ + (*(dst)=b); + +#define lw_set_word(dst,b) \ + (*((uint16_t*)(dst)) = htons(w)) + +#define lw_set_dword(dst,dw)\ + (*((uint32_t*)(dst)) = htonl(dw)) + #define lw_get_byte(src)\ (*(uint8_t*)(src)) @@ -204,6 +213,9 @@ static inline int lw_put_elem_hdr(uint8_t *dst,uint8_t type,uint16_t len) return 3; } +extern int lw_put_sockaddr(uint8_t *dst, struct sockaddr_storage *addr); + + extern int lw_put_cisco_path_mtu(uint8_t *dst, uint16_t max, uint16_t padding); #define lw_put_certificate(dst,cert,len) lw_put_data(dst,cert,len) extern int lw_put_ac_descriptor(uint8_t * dst, struct ac_info * acinfo); diff --git a/src/capwap/sock.h b/src/capwap/sock.h index 4228a24a..4289b0b9 100644 --- a/src/capwap/sock.h +++ b/src/capwap/sock.h @@ -61,6 +61,7 @@ extern char * sock_get_primary_if(int family); #define sock_hwaddr2idstr(s,l) ( sock_hwaddrtostr( s,l, (char[64]){0}, "" ) ) +#define sock_addrfamily(addr) ( ((struct sockaddr_storage*)(addr))->ss_family ) #endif /* __SOCK_H */ diff --git a/src/capwap/stravltree.h b/src/capwap/stravltree.h index 3844b53d..81e81074 100644 --- a/src/capwap/stravltree.h +++ b/src/capwap/stravltree.h @@ -6,7 +6,8 @@ extern struct avltree * stravltree_create(); const char * stravltree_add(struct avltree * t, const char * str); #define stravltree_destroy(t) avltree_destroy(t) -#define stravltree_foreach(t,f,p,d) avltree_foreach(t,f,p,d) +#define stravltree_foreach_asc(t,f,p) avltree_foreach_asc(t,f,p) +#define stravltree_foreach_desc(t,f,p) avltree_foreach_desc(t,f,p) #endif diff --git a/src/capwap/wtpinfo.c b/src/capwap/wtpinfo.c index 7c256902..2c3c052b 100644 --- a/src/capwap/wtpinfo.c +++ b/src/capwap/wtpinfo.c @@ -28,7 +28,7 @@ int wtpinfo_readelem_ecn_support(struct wtpinfo * wtpinfo, int type, uint8_t * m int cw_readelem_cw_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t * msgelem, int len) { switch (type){ - case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS: + case CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS: { if (len!=4) return -1; @@ -42,7 +42,7 @@ int cw_readelem_cw_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t * return 1; } #ifdef WITH_IPV6 - case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS: + case CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS: { if (len!=16) return -1; @@ -69,7 +69,7 @@ int wtpinfo_readelem_cw_local_ip_addr(struct wtpinfo * wtpinfo, int type, uint8_ { switch (type){ - case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS: + case CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS: { if (len!=4) return -1; @@ -83,7 +83,7 @@ int wtpinfo_readelem_cw_local_ip_addr(struct wtpinfo * wtpinfo, int type, uint8_ return 1; } #ifdef WITH_IPV6 - case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS: + case CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS: { if (len!=16) return -1; diff --git a/src/capwap/wtpinfo_readelem_location_data.c b/src/capwap/wtpinfo_readelem_location_data.c index 6ed54234..689d3906 100644 --- a/src/capwap/wtpinfo_readelem_location_data.c +++ b/src/capwap/wtpinfo_readelem_location_data.c @@ -8,7 +8,7 @@ int wtpinfo_readelem_location_data(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len) { - if (type != CWMSGELEM_LOCATION_DATA) + if (type != CW_ELEM_LOCATION_DATA) return 0; cw_setstr(&wtpinfo->location,msgelem,len); diff --git a/src/capwap/wtpinfo_readelem_wtp_descriptor.c b/src/capwap/wtpinfo_readelem_wtp_descriptor.c index a452773d..fe2f9f1c 100644 --- a/src/capwap/wtpinfo_readelem_wtp_descriptor.c +++ b/src/capwap/wtpinfo_readelem_wtp_descriptor.c @@ -85,18 +85,18 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, cw_dbg(DBG_MSG,"Reading WTP descriptor subelement, type=%d,len=%d",subtype,sublen); switch(subtype){ - case CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION: + case CW_SUBELEM_WTP_HARDWARE_VERSION: wtpinfo->hardware_vendor_id=vendor_id; cw_setstr(&wtpinfo->hardware_version,msgelem+i,sublen); wtpinfo->hardware_version_len=sublen; break; - case CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION: + case CW_SUBELEM_WTP_SOFTWARE_VERSION: wtpinfo->software_vendor_id=vendor_id; bstr_replace(&wtpinfo->software_version,bstr_create(msgelem+i,sublen)); wtpinfo->software_version_len=sublen; break; - case CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION: + case CW_SUBELEM_WTP_BOOTLOADER_VERSION: wtpinfo->bootloader_vendor_id=vendor_id; cw_setstr(&wtpinfo->bootloader_version,msgelem+i,sublen); wtpinfo->bootloader_version_len=sublen;