diff --git a/Makefile b/Makefile index 6c17d42f..3e80d147 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,30 @@ +TARGETS=\ + src/contrib/jsmn \ + src/cw + + +#src/cw src/mod src/ac + + + + all: + +#$(foreach i,$(TARGETS),$(call $(MAKE) -c, $i)) + $(MAKE) -C src/contrib/jsmn $(MAKE) -C src/cw $(MAKE) -C src/mod $(MAKE) -C src/ac +clean: + +#$(foreach i,$(TARGETS),$(call $(MAKE) -c, $i)) + + $(MAKE) -C src/contrib/jsmn clean + $(MAKE) -C src/cw clean + $(MAKE) -C src/mod clean + $(MAKE) -C src/ac clean + + diff --git a/doc/capwap_cisco.txt b/doc/capwap_cisco.txt index 981bad39..80bfea91 100644 --- a/doc/capwap_cisco.txt +++ b/doc/capwap_cisco.txt @@ -499,7 +499,7 @@ Vendor spec CAPWAP | Vedor spec LWAPP | Vendor specific LWAPP data +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Username: - 0-terminated username, the field has to fillid up with zeros. + 0-terminated username, the field has to filled up with zeros. Password 1: Password @@ -626,6 +626,17 @@ Length: 2 0: DTLS Data disabled 1: DTLS Data enabled +85. Cisco Primed Join Timeout (LWAPP) + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Tiemout | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Type: 85 + + Timeout: Timeout in seconds + + 132. Cisco MM MWAR Hash Config diff --git a/src/cw/Makefile b/src/cw/Makefile index 0c8fcd1b..9728b78a 100644 --- a/src/cw/Makefile +++ b/src/cw/Makefile @@ -151,7 +151,9 @@ CAPWAPOBJS= \ cw_out_wtp_reboot_statistics.o \ cw_in_wtp_reboot_statistics.o\ cw_in_cisco_image_identifier.o\ - cw_out_radio_operational_state.o\ + cw_out_radio_operational_states.o\ + cw_out_radio_operational_states_7.o\ + cw_put_radio_operational_states.o \ cw_in_ac_descriptor.o\ cw_read_ac_descriptor.o\ cw_out_capwap_local_ip_address.o\ diff --git a/src/cw/action.c b/src/cw/action.c index b8a178fa..24bdde11 100644 --- a/src/cw/action.c +++ b/src/cw/action.c @@ -60,9 +60,9 @@ static inline int cw_action_in_cmp(const void *elem1, const void *elem2) return 0; } +//typedef int(*cw_action_fun_t)(struct conn *,struct cw_action_in *,uint8_t*,int,struct sockaddr *); + - -/* cw_action_fun_t cw_set_msg_end_callback(struct conn *conn, int capwap_state,int msg_id, cw_action_fun_t callback) { @@ -83,11 +83,10 @@ cw_action_fun_t cw_set_msg_end_callback(struct conn *conn, cw_action_fun_t old = af->end; af->end =callback; return old; - } -*/ + cw_action_in_t *cw_actionlist_in_add(cw_actionlist_in_t t, struct cw_action_in * a) diff --git a/src/cw/action.h b/src/cw/action.h index 41d3e15c..b3108e56 100644 --- a/src/cw/action.h +++ b/src/cw/action.h @@ -173,6 +173,11 @@ struct cw_actiondef{ extern struct outelem * cw_actionlist_out_get_mlist(cw_actionlist_out_t t, int msg_id); +typedef int(*cw_action_fun_t)(struct conn *,struct cw_action_in *,uint8_t*,int,struct sockaddr *); + + +cw_action_fun_t cw_set_msg_end_callback(struct conn *conn, + int capwap_state,int msg_id, cw_action_fun_t callback); #define cw_actionlist_get_node(t,a) avltree_get_node(t,a) diff --git a/src/cw/conn_process_packet.c b/src/cw/conn_process_packet.c index 81464eee..0ab9ce45 100644 --- a/src/cw/conn_process_packet.c +++ b/src/cw/conn_process_packet.c @@ -228,6 +228,15 @@ static struct cw_actiondef *load_mods(struct conn *conn, uint8_t * rawmsg, int l */ } +int cw_in_check_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len,struct sockaddr *from) +{ + if (cw_is_request(a->msg_id)){ + return cw_in_check_generic_req(conn,a,data,len,from); + } + return cw_in_check_generic_resp(conn,a,data,len,from); + +} @@ -393,9 +402,19 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len, by calling the "end" function for the message */ int result_code = 0; - if (afm->end) { - result_code = afm->end(conn, afm, rawmsg, len, from); + + int rct = cw_in_check_generic_req(conn, afm, rawmsg, len, from); + if (rct && conn->strict_capwap) + { + result_code = rct; + } + else { + + if (afm->end) { + result_code = afm->end(conn, afm, rawmsg, len, from); + + } } if (unrecognized) { @@ -404,7 +423,9 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len, /* set only resultcode for request messages */ if ( (!result_code) && ((afm->msg_id & 1))) { - result_code = CW_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; + if (conn->strict_capwap) { + result_code = CW_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; + } } } diff --git a/src/cw/cw.h b/src/cw/cw.h index 0d31a701..8e82f051 100644 --- a/src/cw/cw.h +++ b/src/cw/cw.h @@ -480,6 +480,10 @@ extern int cw_out_capwap_local_ip_address(struct conn *conn, struct cw_action_ou extern int cw_out_wtp_ip_address(struct conn *conn, struct cw_action_out *action, uint8_t * dst); +extern int cw_out_radio_operational_states(struct conn *conn, struct cw_action_out *a, uint8_t * dst); +extern int cw_out_radio_operational_states_7(struct conn *conn, struct cw_action_out *a, uint8_t * dst); + + /** * With this alias for #cw_out_wtp_ip_address we can * can hav more consitent naming, when implement draft 7 @@ -492,6 +496,8 @@ extern int cw_out_wtp_reboot_statistics(struct conn *conn, struct cw_action_out /* helpers */ extern int cw_put_local_ip_address(int sock, uint8_t *dst, int ipv4elem_id, int ipv6elem_id); +extern int cw_put_radio_operational_states(mbag_t radios, uint8_t * dst, int *nerror, int d7mode); + /** * @} diff --git a/src/cw/cw_in_check_generic_req.c b/src/cw/cw_in_check_generic_req.c index 509b6758..7eed56e8 100644 --- a/src/cw/cw_in_check_generic_req.c +++ b/src/cw/cw_in_check_generic_req.c @@ -10,7 +10,6 @@ int cw_in_check_generic_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,struct sockaddr *from) { - cw_action_in_t * mlist[60]; /* Check for mandatory elements */ diff --git a/src/cw/cw_in_check_join_resp.c b/src/cw/cw_in_check_join_resp.c index ff9b4b3e..13d7278e 100644 --- a/src/cw/cw_in_check_join_resp.c +++ b/src/cw/cw_in_check_join_resp.c @@ -18,8 +18,6 @@ int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * d if (!cw_rcok(jresult->dword)){ return jresult->dword; } - - } diff --git a/src/cw/cw_out_radio_operational_states.c b/src/cw/cw_out_radio_operational_states.c index 7d03864e..e7e8258d 100644 --- a/src/cw/cw_out_radio_operational_states.c +++ b/src/cw/cw_out_radio_operational_states.c @@ -1,3 +1,20 @@ +/* + This file is part of actube. + + actube 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 "cw.h" #include "capwap_items.h" @@ -6,7 +23,8 @@ #include "log.h" #include "radio.h" -int cw_out_radio_operational_states(struct conn *conn, struct cw_action_out *a, uint8_t * dst) + +int iiicw_put_radio_operational_states(struct conn *conn, uint8_t * dst, int *nerrors, int d7mode) { uint8_t *d=dst; @@ -33,7 +51,7 @@ int cw_out_radio_operational_states(struct conn *conn, struct cw_action_out *a, /* Get the operational state and cause */ uint16_t os = ositem->word; - if ( conn->capwap_mode==CW_MODE_CISCO ){ + if ( d7mode ){ /* Isolate Oper Sate from cause */ uint8_t o=os>>8; @@ -55,6 +73,23 @@ int cw_out_radio_operational_states(struct conn *conn, struct cw_action_out *a, } + +/* if (nerror) { + if (a->mand) { + cw_log(LOG_ERROR,"Could not send Radio Operational State for all radios. Sent %d out of %d.", + conn->radios->count-nerror,conn->radios->count); + + } + } +*/ + return d-dst; +} + + +int cw_out_radio_operational_states(struct conn *conn, struct cw_action_out *a, uint8_t * dst) +{ + int nerror=0; + int l = cw_put_radio_operational_states(conn->radios,dst,&nerror,0); if (nerror) { if (a->mand) { cw_log(LOG_ERROR,"Could not send Radio Operational State for all radios. Sent %d out of %d.", @@ -62,7 +97,6 @@ int cw_out_radio_operational_states(struct conn *conn, struct cw_action_out *a, } } - - return d-dst; + return l; } diff --git a/src/cw/lw_cisco_id_to_str.c b/src/cw/lw_cisco_id_to_str.c index b5850760..1470d752 100644 --- a/src/cw/lw_cisco_id_to_str.c +++ b/src/cw/lw_cisco_id_to_str.c @@ -33,6 +33,9 @@ const char * lw_cisco_id_to_str(int elem_id) case LW_CISCO_AP_DTLS_DATA_CFG: return "AP DTLS Data Config"; + case LW_CISCO_PRIMED_JOIN_TIMEOUT: + return "Primed Join Timeout"; + default: return "Unknown"; diff --git a/src/mod/capwap/capwap_actions_wtp.c b/src/mod/capwap/capwap_actions_wtp.c index ce610d0f..c192e004 100644 --- a/src/mod/capwap/capwap_actions_wtp.c +++ b/src/mod/capwap/capwap_actions_wtp.c @@ -189,6 +189,20 @@ static cw_action_in_t actions_in[] = { .end = cw_in_check_generic_resp } , + /* Capwap Timers - Config Status Resp */ + { + .capwap_state = CW_STATE_CONFIGURE, + .msg_id = CW_MSG_CONFIGURATION_STATUS_RESPONSE, + .elem_id = CW_ELEM_CAPWAP_TIMERS, + .item_id = CW_ITEM_CAPWAP_TIMERS, + .start = cw_in_generic2, + .min_len = 2, + .max_len = 2, + .mand = 1 + } + , + + /* Idle Timeout - Config Status Resp */ { @@ -203,19 +217,6 @@ static cw_action_in_t actions_in[] = { } , - /* Capwap Timers - Config Status Resp */ - { - .capwap_state = CW_STATE_CONFIGURE, - .msg_id = CW_MSG_CONFIGURATION_STATUS_RESPONSE, - .elem_id = CW_ELEM_CAPWAP_TIMERS, - .item_id = CW_ITEM_CAPWAP_TIMERS, - .start = cw_in_generic2, - .min_len = 2, - .max_len = 2, - .mand = 1 - } - , - @@ -233,6 +234,18 @@ static cw_action_in_t actions_in[] = { , + /* Vendor Specific Payload - Cponfig Status Resp */ + { + .capwap_state = CW_STATE_CONFIGURE, + .msg_id = CW_MSG_CONFIGURATION_STATUS_RESPONSE, + .elem_id = CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, + .start = cw_in_vendor_specific_payload + } + , + + /* ---------------------------------------------------------------- + * Change State Event Response - IN + */ { .capwap_state = CW_STATE_CONFIGURE, @@ -285,7 +298,50 @@ static cw_action_in_t actions_in[] = { } , - /* Vendor Specific Payload - Echo Response */ + + /* WTP Name - Config Update Req */ + { + .capwap_state = CW_STATE_RUN, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_ELEM_WTP_NAME, + .item_id = CW_ITEM_WTP_NAME, + .start = cw_in_generic2, + .min_len = 1, + .max_len = 1024, + .mand = 0 + } + , + + + + + /* Location Data - Config Update Req */ + { + .capwap_state = CW_STATE_RUN, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_ELEM_LOCATION_DATA, + .item_id = CW_ITEM_LOCATION_DATA, + .start = cw_in_generic2, + .min_len = 1, + .max_len = 1024, + .mand = 0 + } + , + + + /* Radio Admin State - Config Status Request */ + { + .capwap_state = CW_STATE_RUN, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_ELEM_RADIO_ADMINISTRATIVE_STATE, + .item_id = CW_ITEM_RADIO_ADMINISTRATIVE_STATE, + .start = cw_in_radio_administrative_state, + .mand = 1 + } + , + + + /* Vendor Specific Payload - Config Update Req */ { .capwap_state = CW_STATE_RUN, .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, diff --git a/src/mod/cisco/Makefile b/src/mod/cisco/Makefile index 601c7fca..f959d2ca 100644 --- a/src/mod/cisco/Makefile +++ b/src/mod/cisco/Makefile @@ -9,7 +9,9 @@ OBJS=\ cisco_out_ac_descriptor.o \ cisco_out_wtp_descriptor.o \ cisco_in_ac_descriptor.o\ - cisco80211.o + cisco80211.o \ + cisco_in_radio_administrative_state.o + NAME=libcisco.a diff --git a/src/mod/cisco/cisco.h b/src/mod/cisco/cisco.h index 736fcdb5..5b461abe 100644 --- a/src/mod/cisco/cisco.h +++ b/src/mod/cisco/cisco.h @@ -4,14 +4,21 @@ #include "cw/conn.h" #include "cw/action.h" -extern int cisco_out_ap_timesync(struct conn *conn,struct cw_action_out * a,uint8_t *dst); -extern int cisco_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len, struct sockaddr *from); -extern int cisco_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) ; -extern int cisco_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, uint8_t * dst); +extern int cisco_out_ap_timesync(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); +extern int cisco_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len, struct sockaddr *from); +extern int cisco_out_ac_descriptor(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); +extern int cisco_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); -extern int cisco_in_ac_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len, struct sockaddr *from); +extern int cisco_in_ac_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len, struct sockaddr *from); + +extern int cisco_in_radio_administrative_state_wtp(struct conn *conn, + struct cw_action_in *a, uint8_t * data, + int len, struct sockaddr *from); #endif diff --git a/src/mod/cisco/cisco_actions_wtp.c b/src/mod/cisco/cisco_actions_wtp.c index 7b9c6920..4a10fa37 100644 --- a/src/mod/cisco/cisco_actions_wtp.c +++ b/src/mod/cisco/cisco_actions_wtp.c @@ -34,6 +34,11 @@ static cw_action_in_t actions_in[] = { + /* ---------------------------------------------------------------- + * Discovery Response + */ + + /* AC Descriptor - Discovery Response */ { .capwap_state = CW_STATE_DISCOVERY, @@ -48,9 +53,14 @@ static cw_action_in_t actions_in[] = { , + /* ---------------------------------------------------------------- + * Join Response + */ + /* ECN Support - Join Response */ { + /* Make ECN Support non-mand */ .capwap_state = CW_STATE_JOIN, .msg_id = CW_MSG_JOIN_RESPONSE, .elem_id = CW_ELEM_ECN_SUPPORT, @@ -64,6 +74,7 @@ static cw_action_in_t actions_in[] = { /* AC Descriptor - Join Response */ { + /* Cisco's AC Descriptor */ .capwap_state = CW_STATE_JOIN, .msg_id = CW_MSG_JOIN_RESPONSE, .elem_id = CW_ELEM_AC_DESCRIPTOR, @@ -76,15 +87,50 @@ static cw_action_in_t actions_in[] = { , - /* Vendor Specific Payload - Cponfiguration Status Response */ + /* ---------------------------------------------------------------- + * Configuration Update Request + */ + + /* Location Data - Conf Update Req */ { - .capwap_state = CW_STATE_CONFIGURE, - .msg_id = CW_MSG_CONFIGURATION_STATUS_RESPONSE, - .elem_id = CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, - .start = cw_in_vendor_specific_payload + .capwap_state = CW_STATE_RUN, + .vendor_id = CW_VENDOR_ID_CISCO, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = LW_ELEM_LOCATION_DATA, + .item_id = CW_ITEM_LOCATION_DATA, + .start = cw_in_generic2, + .min_len = 0, + .max_len = 1024, + .mand = 0 } , - + + /* WTP Name - Conf Update Req */ + { + .capwap_state = CW_STATE_RUN, + .vendor_id = CW_VENDOR_ID_CISCO, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_CISCO_RAD_NAME, + .item_id = CW_ITEM_WTP_NAME, + .start = cw_in_generic2, + .min_len = 0, + .max_len = 1024, + .mand = 0 + } + , + + /* Radio Admin State - Config Status Request */ + { + .capwap_state = CW_STATE_RUN, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_ELEM_RADIO_ADMINISTRATIVE_STATE, + .item_id = CW_ITEM_RADIO_ADMINISTRATIVE_STATE, + .start = cisco_in_radio_administrative_state_wtp, + .mand = 1 + } + , + + /* End of list */ {0, 0} diff --git a/src/wtp/configure.c b/src/wtp/configure.c index b3e51ced..e6e1d9af 100644 --- a/src/wtp/configure.c +++ b/src/wtp/configure.c @@ -13,7 +13,9 @@ int configure() struct conn *conn = get_conn(); - mbag_del_all(conn->incomming); +// mbag_del_all(conn->incomming); + conn->incomming=conn->config; + mbag_del(conn->incomming,CW_ITEM_RESULT_CODE); mbag_set_str(conn->local,CW_ITEM_AC_NAME,"abc"); diff --git a/src/wtp/join.c b/src/wtp/join.c index 804e71df..1ddce098 100644 --- a/src/wtp/join.c +++ b/src/wtp/join.c @@ -183,6 +183,9 @@ int run_join(struct conn *conn) mbag_del_all(conn->incomming); + + //mbag_del (conn->incomming,CW_ITEM_RESULT_CODE); + int rc = cw_send_request(conn, CW_MSG_JOIN_REQUEST); if (!cw_rcok(rc)) { diff --git a/src/wtp/wtp_main.c b/src/wtp/wtp_main.c index d587ec0f..f82bf69f 100644 --- a/src/wtp/wtp_main.c +++ b/src/wtp/wtp_main.c @@ -45,14 +45,17 @@ int handle_update_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, mavliter_foreach(&it) { mbag_item_t *item = mavliter_get(&it); -// printf("MBAG ITEM GOT: %d\n",item->id); - if (item->id == CW_ITEM_WTP_NAME) { - +// printf("MBAG ITEM GOT: %s\n",item->id); + if (item->id == CW_ITEM_LOCATION_DATA) { + printf("Location Data %s\n",mbag_get_str(conn->incomming,CW_ITEM_LOCATION_DATA,"ups")); + } } cw_dbg(DBG_INFO, "Saving configuration ..."); cfg_to_json(); + +// exit(0); return 0; } @@ -243,7 +246,7 @@ int main() -//cw_set_msg_end_callback(conn,CW_STATE_RUN,CW_MSG_CONFIGURATION_UPDATE_REQUEST,handle_update_req); +cw_set_msg_end_callback(conn,CW_STATE_RUN,CW_MSG_CONFIGURATION_UPDATE_REQUEST,handle_update_req); //cw_set_msg_end_callback(conn,CW_STATE_CONFIGURE,CW_MSG_CONFIGURATION_STATUS_RESPONSE,handle_update_req); @@ -257,6 +260,10 @@ int main() // conn->incomming = conn->config; if (!configure()) return -1; + + + cfg_to_json(); + changestate();