diff --git a/doc/capwap_cisco.txt b/doc/capwap_cisco.txt index 5a6ad60c..a0a0a0de 100644 --- a/doc/capwap_cisco.txt +++ b/doc/capwap_cisco.txt @@ -273,7 +273,7 @@ AP = RAD = WTP | Counter Type | Set | Value | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -Type: 207 +Type: 240 Length: 4 Counter Type: @@ -287,6 +287,20 @@ Length: 4 Value: Value to set. +249. Cisco AP Venue Settings + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved(?) | Venue Group | Venue Type | Language ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ... Language | Venue Name ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + 254. Cisco SPAM AP LED Flash Config @@ -296,7 +310,7 @@ Length: 4 LWAPP ===== In this section Cisco vendor specific message elements used in LWAPP -are listed. +are listed. (See RFC5412, message element type 104). Some of these elements are used by Cisco in CAPWAP where the vendor specific LWAPP message element is encapsulated in a vendor diff --git a/src/capwap/Makefile b/src/capwap/Makefile index d7594156..982960bf 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -140,6 +140,7 @@ CAPWAPOBJS= \ cw_in_cisco_image_identifier.o\ cw_out_capwap_control_ip_addr_list.o \ cw_in_capwap_control_ipv4_address.o\ + cw_in_radio_administrative_state.o \ strheap.o \ cw_check_missing_mand.o \ md5sum.o \ diff --git a/src/capwap/acpriolist.c b/src/capwap/acpriolist.c index 6a7934ef..a54405a7 100644 --- a/src/capwap/acpriolist.c +++ b/src/capwap/acpriolist.c @@ -44,7 +44,7 @@ static void acprio_del(void *d) cw_acpriolist_t cw_acpriolist_create() { - return avltree_create(acprio_cmp, acprio_del); + return mavl_create(acprio_cmp, acprio_del); } cw_acprio_t * cw_acpriolist_add(cw_acpriolist_t l, const char *name,int name_len, uint8_t prio) @@ -57,7 +57,7 @@ cw_acprio_t * cw_acpriolist_add(cw_acpriolist_t l, const char *name,int name_len s->prio=prio; cw_acpriolist_del(l,s); - return avltree_add(l,s); + return mavl_add(l,s); } diff --git a/src/capwap/acpriolist.h b/src/capwap/acpriolist.h index 60a95068..af8e34a4 100644 --- a/src/capwap/acpriolist.h +++ b/src/capwap/acpriolist.h @@ -1,8 +1,8 @@ #ifndef __ACIPRIORITYLIST_H #define __ACIPRIORITYLIST_H - -#include "avltree.h" +#include "mavl.h" +//#include "mavl.h" struct cw_acprio{ char *name; @@ -10,7 +10,7 @@ struct cw_acprio{ }; typedef struct cw_acprio cw_acprio_t; -typedef struct avltree * cw_acpriolist_t; +typedef struct mavl * cw_acpriolist_t; extern cw_acpriolist_t cw_acpriolist_create(); cw_acprio_t * cw_acpriolist_add(cw_acpriolist_t l, const char *name,int name_len, uint8_t prio); @@ -19,13 +19,13 @@ static inline int cw_acpriolist_get(cw_acpriolist_t l, char * acname){ cw_acprio_t ps,*pf; ps.name=acname; - pf=avltree_get(l,&ps); + pf=mavl_get(l,&ps); if (!pf) return 256; return pf->prio; } -#define cw_acpriolist_del(l,s) avltree_del(l,s) +#define cw_acpriolist_del(l,s) mavl_del(l,s) #define cw_acpriolist_set(l,n,nl,p) cw_acpriolist_add(l,n,nl,p) #endif diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index f6d70836..4938287e 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -1098,6 +1098,8 @@ struct mbag_item *cw_out_get_session_id(struct conn *conn, struct cw_action_out struct mbag_item *cw_out_get_config(struct conn *conn, struct cw_action_out *a); +extern int cw_in_radio_administrative_state(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, + struct sockaddr *from); int cw_send_request(struct conn *conn, int msg_id); diff --git a/src/capwap/capwap_80211_actions_wtp.c b/src/capwap/capwap_80211_actions_wtp.c index 57c97915..3d73fcab 100644 --- a/src/capwap/capwap_80211_actions_wtp.c +++ b/src/capwap/capwap_80211_actions_wtp.c @@ -12,11 +12,16 @@ cw_action_in_t capwap_80211_actions_wtp_in[] = { - + /* Discovery Response */ {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_RESPONSE, CW_ACTION_IN_80211_WTP_RADIO_INFORMATION, 1} , + /* Join Response */ + {0, 0, CW_STATE_JOIN, CW_MSG_JOIN_RESPONSE, + CW_ACTION_IN_80211_WTP_RADIO_INFORMATION, 1} + , + {0, 0, 0} }; diff --git a/src/capwap/capwap_actions.h b/src/capwap/capwap_actions.h index 7f97f5e9..8b429b08 100644 --- a/src/capwap/capwap_actions.h +++ b/src/capwap/capwap_actions.h @@ -157,6 +157,13 @@ CW_ITEM_IDLE_TIMEOUT, /* ID to use store */ \ 4, 4 /* min/max length */ +#define CW_ACTION_IN_RADIO_ADMINISTRATIVE_STATE \ + CW_ELEM_RADIO_ADMINISTRATIVE_STATE, /* Element ID*/ \ + cw_in_radio_administrative_state, 0, /* start/end callback */ \ + MBAG_DWORD, /* Type of element */ \ + 0, /* ID to use store */ \ + 4, 4 /* min/max length */ + diff --git a/src/capwap/capwap_actions_wtp.c b/src/capwap/capwap_actions_wtp.c index 914af649..7ade1b21 100644 --- a/src/capwap/capwap_actions_wtp.c +++ b/src/capwap/capwap_actions_wtp.c @@ -68,6 +68,15 @@ cw_action_in_t capwap_actions_wtp_in[] = { CW_ACTION_IN_RESULT_CODE, 1} , + /* Element: AC Name */ + {0, 0, CW_STATE_JOIN, CW_MSG_JOIN_RESPONSE, + CW_ACTION_IN_AC_NAME, 1} + , + + + + + /* ------------------------------------------------------------------------------- */ /* Message Image Data Response */ diff --git a/src/capwap/capwap_cisco.h b/src/capwap/capwap_cisco.h index 8fbd6ba8..a71fa385 100644 --- a/src/capwap/capwap_cisco.h +++ b/src/capwap/capwap_cisco.h @@ -88,6 +88,7 @@ #define CW_CISCO_BOARD_DATA_OPTIONS 207 #define CW_CISCO_MWAR_TYPE 208 #define CW_CISCO_AP_RETRANSMIT_PARAM 240 +#define CW_CISCO_AP_VENUE_SETTINGS 249 diff --git a/src/capwap/cw_cisco_id_to_str.c b/src/capwap/cw_cisco_id_to_str.c index 35fd639b..02c8b462 100644 --- a/src/capwap/cw_cisco_id_to_str.c +++ b/src/capwap/cw_cisco_id_to_str.c @@ -112,6 +112,9 @@ const char * cw_cisco_id_to_str(int elem_id) return "SPAM AP LED State"; case CW_CISCO_AP_RETRANSMIT_PARAM: return "AP Retransmit Param"; + case CW_CISCO_AP_VENUE_SETTINGS: + return "AP Venue Settings"; + default: return "Unknown"; diff --git a/src/capwap/mbag.h b/src/capwap/mbag.h index 069f244f..5353c054 100644 --- a/src/capwap/mbag.h +++ b/src/capwap/mbag.h @@ -279,6 +279,16 @@ static inline int mbag_set_avltree(mbag_t s, uint32_t id, struct avltree *t) return 1; } +static inline int mbag_set_mavl(mbag_t s, uint32_t id, mavl_t t) +{ + struct mbag_item *i = mbag_item_create(s, id); + if (!i) + return 0; + i->type = MBAG_AVLTREE; + i->data = t; + return 1; +} + static inline struct avltree *mbag_get_avltree_c(mbag_t s, uint32_t id, struct avltree *(creator) ()) @@ -296,6 +306,22 @@ static inline struct avltree *mbag_get_avltree_c(mbag_t s, uint32_t id, } +static inline mavl_t mbag_get_mavl(mbag_t s, uint32_t id, + mavl_t (creator) ()) +{ + struct mbag_item *i = mbag_get(s, id); + if (i) + return i->data; + + if (!creator) + return NULL; + mavl_t avltree = creator(); + if (!avltree) + return NULL; + mbag_set_mavl(s, id, avltree); + return avltree; +} + diff --git a/src/capwap/sock.h b/src/capwap/sock.h index 4289b0b9..6b7dceb6 100644 --- a/src/capwap/sock.h +++ b/src/capwap/sock.h @@ -56,7 +56,11 @@ extern int sock_set_dontfrag(int sock,int val); extern char * sock_get_primary_if(int family); -#define sock_addr2str(s) ( sock_addrtostr( (struct sockaddr*)s, (char[64]){0}, 64 ) ) + +char *sock_strsockaddr(const struct sockaddr *sa, char *s, size_t maxlen,int addport); + + +#define sock_addr2str(s) ( sock_strsockaddr( (struct sockaddr*)s, (char[64]){0}, 64,0 ) ) #define sock_hwaddr2str(s,l) ( sock_hwaddrtostr( s,l, (char[64]){0}, ":" ) ) #define sock_hwaddr2idstr(s,l) ( sock_hwaddrtostr( s,l, (char[64]){0}, "" ) ) diff --git a/src/capwap/sock_addrtostr.c b/src/capwap/sock_addrtostr.c index e0b04910..f4972c43 100644 --- a/src/capwap/sock_addrtostr.c +++ b/src/capwap/sock_addrtostr.c @@ -45,7 +45,10 @@ void sock_hwaddrtostr(const uint8_t *haddr,int len,char *dst) } */ -char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen) + + + +char *sock_strsockaddr(const struct sockaddr *sa, char *s, size_t maxlen,int addport) { int port; @@ -54,7 +57,10 @@ char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen) case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen); port = ((struct sockaddr_in *)sa)->sin_port; - sprintf(s,"%s:%i",s,ntohs(port)); + if (addport) + sprintf(s,"%s:%i",s,ntohs(port)); + else + sprintf(s,"%s",s); break; case AF_INET6: diff --git a/src/wtp/cfg.c b/src/wtp/cfg.c index c3ba3ffd..306b18f8 100644 --- a/src/wtp/cfg.c +++ b/src/wtp/cfg.c @@ -15,6 +15,8 @@ #include "capwap/format.h" #include "capwap/file.h" +#include "capwap/aciplist.h" +#include "capwap/sock.h" /* json putters */ @@ -22,6 +24,8 @@ int cfg_json_put_bstr16(char *dst,const char * name, mbag_item_t *i,int n); int cfg_json_put_vendorstr(char *dst,const char * name, mbag_item_t *i,int n); int cfg_json_put_dword(char *dst,const char * name, mbag_item_t *i,int n); int cfg_json_put_word(char *dst,const char * name, mbag_item_t *i,int n); +int cfg_json_put_ac_ip_list(char *dst,const char * name, mbag_item_t *i,int n); + //static int scn_obj(char *js, jsmntok_t *t, int (vcb)(char*js,jsmntok_t*t,struct mbag_itemdef *defs,mbag_t mbag), struct mbag_itemdef *defs,mbag_t mbag); @@ -90,7 +94,90 @@ static int skip(jsmntok_t *t) } } +int cfg_json_put_ac_ip_list(char *dst,const char * name, mbag_item_t *i,int n) +{ + char *d = dst; + + cw_aciplist_t aciplist = i->data; + + MAVLITER_DEFINE(it,aciplist); + + memset(d,'\t',n); + d+=n; + d+=sprintf(d,"\"%s\":",name); + + d+=sprintf(d,"[\n"); + const char * comma = ""; + mavliter_foreach(&it){ + cw_acip_t * acip = mavliter_get(&it); + + d+=sprintf(d,"%s",comma); + memset(d,'\t',n+1); + d+=n+1; + + d+=sprintf(d,"\"%s\"",sock_addr2str(&acip->ip)); + comma=",\n"; + + + } + d+=sprintf(d,"\n"); + memset(d,'\t',n); + d+=n; + + d+=sprintf(d,"]"); + + return d-dst; +} + +int cfg_json_get_ac_ip_list(struct mbag_itemdef *idef,char *js, jsmntok_t *t,mbag_t mbag) +{ + + printf("Get AC IP List len = %d\n",t->size); + if (t->type != JSMN_ARRAY ) { + printf("ac_ip_list is not a list\n"); + exit(0); + + } + int size = t->size; + t++; + + int i; + + for (i=0; iend]=0; + + int rc; + + cw_acip_t * acip; + acip = malloc(sizeof(cw_acip_t)); + if (!acip) + continue; + + /* convert IPv4 adddress */ + rc = inet_pton(AF_INET, js+t->start, &(((struct sockaddr_in *)(&acip->ip))->sin_addr) ); + ((struct sockaddr *)(&acip->ip))->sa_family=AF_INET; + if (!rc) { + /* If it's not an IPv4 adress, try IPv6 */ + rc = inet_pton(AF_INET6, js+t->start, &(((struct sockaddr_in6 *)(&acip->ip))->sin6_addr) ); + ((struct sockaddr *)(&acip->ip))->sa_family=AF_INET6; + } + + if ( !rc ) { + + printf("Not an IP adress: %s\n",js+t->start); + exit(0); + } + + cw_aciplist_t aciplist= mbag_get_mavl(mbag,CW_ITEM_AC_IP_LIST,cw_aciplist_create ); + mavl_replace(aciplist,acip); + + + } + + + +} @@ -237,6 +324,7 @@ int bstr_local(struct mbag_itemdef *idef,char *js, jsmntok_t *t) +int cfg_json_get_ac_ip_list(struct mbag_itemdef *idef,char *js, jsmntok_t *t,mbag_t mbag); int wtp_board_data_local(struct mbag_itemdef *idef,char *js, jsmntok_t *t,mbag_t mbag); int cfg_json_put_obj(char *dst,const char * name, mbag_item_t *i,int n); @@ -254,6 +342,7 @@ struct mbag_itemdef general_cfg[] = { {CW_RADIO_BSSID, "bssid",cfg_json_get_bstr16,cfg_json_put_bstr16}, {CW_ITEM_CAPWAP_TIMERS, "capwap_timers",cfg_json_get_word,cfg_json_put_word}, {CW_ITEM_IDLE_TIMEOUT, "idle_timeout",cfg_json_get_dword,cfg_json_put_dword}, + {CW_ITEM_AC_IP_LIST,"ac_ip_list",cfg_json_get_ac_ip_list,cfg_json_put_ac_ip_list}, @@ -372,9 +461,6 @@ int cfg_json_put_obj(char *dst,const char * name, mbag_item_t *i,int n) memset(d,'\t',n); d+=n; d+=sprintf(d,"\"%s\":",name); - - printf("here we are %s\n",dst); - d+=mbag_tojson(d,i->data,board_data_cfg,n); return d-dst; @@ -436,7 +522,8 @@ int cfg_json_save() int n = mbag_tojson(dst,conn->config,general_cfg,0); -//printf("Json: %s\n",dst); + + cw_save_file("cfg.json",dst,n); @@ -506,7 +593,6 @@ int wtp_board_data_local(struct mbag_itemdef *idef,char *js, jsmntok_t *t,mbag_t printf("Size: %d\n",t->size); return 0; } -printf("BOARD DATA SCANER\n"); struct conn * conn = get_conn(); mbag_t bd = mbag_get_mbag(conn->config,CW_ITEM_WTP_BOARD_DATA,NULL); @@ -561,29 +647,6 @@ static int set_cfg(char *js,jsmntok_t *t,struct mbag_itemdef *defs,mbag_t mbag){ int setup_conf(struct conn *conn) { - -/* - FILE * infile = fopen("cfg.json","rb"); - if ( !infile ){ - perror("Can't open cfg.json"); - return 0; - } - - fseek(infile,0,SEEK_END); - int size = ftell(infile); - - - char *jstr = malloc(size); - if ( jstr==NULL){ - perror("Can't allocate memory"); - return 0; - - } - - fseek(infile,0,SEEK_SET); - fread(jstr,1,size,infile); -*/ - size_t size; char *jstr = cw_load_file("cfg.json",&size); if (!jstr) { diff --git a/src/wtp/cfg.json b/src/wtp/cfg.json index 04ecd3df..6765e48c 100644 --- a/src/wtp/cfg.json +++ b/src/wtp/cfg.json @@ -9,6 +9,12 @@ "serial_no":"2045" }, "capwap_timers":"2590", + "ac_ip_list":[ + "192.168.0.1", + "192.168.0.13", + "192.168.0.15", + "fe80::219:dbff:fee0:9327" + ], "location_data":"Germany", "bssid":"" } \ No newline at end of file diff --git a/src/wtp/wtp_conf.c b/src/wtp/wtp_conf.c index fd3a6445..de509453 100644 --- a/src/wtp/wtp_conf.c +++ b/src/wtp/wtp_conf.c @@ -182,10 +182,12 @@ int wtpconf_ac_list() } if (bcrc){ - char bcstr[100]; - sock_addrtostr((struct sockaddr*)&bcaddr,bcstr,100); - char * c = strchr(bcstr,':'); - *c=0; +// char bcstr[100]; + char *bcstr; +// sock_addrtostr((struct sockaddr*)&bcaddr,bcstr,100); + bcstr = sock_addr2str((struct sockaddr*)&bcaddr); +// char * c = strchr(bcstr,':'); +// *c=0; conf_ac_list[i]=strdup(bcstr); } diff --git a/src/wtp/wtp_main.c b/src/wtp/wtp_main.c index da522589..4138f203 100644 --- a/src/wtp/wtp_main.c +++ b/src/wtp/wtp_main.c @@ -138,7 +138,7 @@ mavl_destroy(b); conn->config=mbag_create(); setup_conf(conn); - + cfg_json_save(); mbag_t board_data = mbag_create(); mbag_set_dword(board_data, CW_ITEM_WTP_BOARD_VENDOR, conf_vendor_id); @@ -172,7 +172,7 @@ cw_set_msg_end_callback(conn,CW_STATE_CONFIGURE,CW_MSG_CONFIGURATION_STATUS_RESP - the_conn->strict_capwap=0; + the_conn->strict_capwap=1; discovery(); join(); mavl_destroy(conn->incomming);