diff --git a/doc/capwap_cisco.txt b/doc/capwap_cisco.txt index 0d869e68..5d25f59e 100644 --- a/doc/capwap_cisco.txt +++ b/doc/capwap_cisco.txt @@ -33,12 +33,86 @@ AP = RAD = WTP of AP is stored in the Address field. (See RFC 5412 - Message type 2: AC Address) +8. Cisco WTP Radio Configuration + + See RFC 5412 - LWAPP 80211 WTP WLAN Radio Configuration. This Cisco + CAPWAP element is slightly different. + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Radio ID | CFG Type | Occupancy Limit | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | CFP Per | CFP Maximum Duration | BSS ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | BSS ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | BSS ID | Beacon Period | Country Str1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Country Str1 | Country String 2 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Countr Str2 | gPeriod | Reg(?) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reg(?) | ? | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type: 8 + Length: 28 + + Radio ID: An 8-bit value representing the radio to configure. + + Config Type: + 0 = Automatic + + Occupancy Limit: This attribute indicates the maximum amount of + time, in Time Units (TUs), that a point coordinator MAY control + the usage of the wireless medium without relinquishing control for + long enough to allow at least one instance of Distributed + Coordination Function (DCF) access to the medium. The default + value of this attribute SHOULD be 100, and the maximum value + SHOULD be 1000. + + CFP Period: The attribute describes the number of DTIM intervals + between the start of Contention-Free Periods (CFPs). + + CFP Maximum Duration: The attribute describes the maximum duration + of the CFP in TU that MAY be generated by the Point Coordination + Function (PCF). + + BSSID: The WLAN Radio's base MAC address. For WTPs that support + more than a single WLAN, the value of the WLAN Identifier is added + to the last octet of the BSSID. Therefore, a WTP that supports 16 + WLANs MUST have 16 MAC addresses reserved for it, and the last + nibble is used to represent the WLAN ID. + + Beacon Period: This attribute specifies the number of TUs that a + station uses for scheduling Beacon transmissions. This value is + transmitted in Beacon and Probe Response frames. + + Country Code: This attribute identifies the country in which the + station is operating. The first two octets of this string is the + two-character country code as described in document ISO/IEC 3166- + 1. The third octet MUST be one of the following: + + 1. an ASCII space character, if the regulations under which the + station is operating encompass all environments in the country, + + 2. an ASCII 'O' character, if the regulations under which the station + is operating are for an outdoor environment only, or + + +/* DTIM Period: This attribute specifies the number of Beacon + intervals that elapses between transmission of Beacons frames + containing a TIM element whose DTIM Count field is 0. This value + is transmitted in the DTIM Period field of Beacon frames. +*/ + 83. Cisco AP IP Address The IPv4 configuration of the WTP - 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 + 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | IP Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -63,6 +137,40 @@ AP = RAD = WTP Reserved: (?) +91. AC Name with Index + + Same as AC Name with Priority, defined in CAPWAP RFC 5415. + + + The AC Name with Priority message element is sent by the AC to the + WTP to configure preferred ACs. The number of instances of this + message element is equal to the number of ACs configured on the WTP. + The WTP also uses this message element to send its configuration to + the AC. + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Index | AC Name... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type: 91 for AC Name with Index + + Length: >= 2 + + Priority: A value between 1 and 255 specifying the priority order + of the preferred AC. For instance, the value of one (1) is used + to set the primary AC, the value of two (2) is used to set the + secondary, etc. + + + AC Name: A variable-length UTF-8 encoded string [RFC3629] + containing the AC name, whose maximum size MUST NOT exceed 512 + bytes. + + + + 126. Cisco AP Regulatory Domain //bandId[0], regDomainSet[1], regDomainSlotId[0], regDomainCode0:[0], regDomainCode1:[1] diff --git a/src/Config.mak b/src/Config.mak index f98690b6..d2b03275 100644 --- a/src/Config.mak +++ b/src/Config.mak @@ -14,6 +14,7 @@ USE_CONTRIB_GNUTLS=1 # Compiler to use CC=clang +#CC=gcca #CC=mips-openwrt-linux-uclibc-gcc #LD=mips-openwrt-linux-uclibc-ld #AR=mips-openwrt-linux-uclibc-ar diff --git a/src/ac/wtpman.c b/src/ac/wtpman.c index b95b4a5c..65418663 100644 --- a/src/ac/wtpman.c +++ b/src/ac/wtpman.c @@ -116,7 +116,7 @@ printf("Param %p\n",param); return 1; } -static struct cwrmsg * conn_wait_for_request(struct conn * conn, int *msglist, time_t timer) +static struct cwrmsg * zconn_wait_for_request(struct conn * conn, int *msglist, time_t timer) { int (*request_handler_save) (void*); void * request_handler_param_save; @@ -178,7 +178,7 @@ printf("Current Seqnum = %d\n",conn->seqnum); time_t r_timer = cw_timer_start(conn->retransmit_interval); if (i!=0) - cw_dbg(DBG_CW_MSG_ERR,"Retransmitting message, type=%d,seq=%d",cwmsg->type,cwmsg->seqnum); + cw_dbg(DBG_MSG_ERR,"Retransmitting message, type=%d,seq=%d",cwmsg->type,cwmsg->seqnum); conn_send_cwmsg(conn,&conn->req_msg); cwrmsg = conn_wait_for_message(conn,r_timer); @@ -194,7 +194,7 @@ printf("Current Seqnum = %d\n",conn->seqnum); } } - cw_dbg(DBG_CW_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum); + cw_dbg(DBG_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum); return 0; } @@ -205,10 +205,10 @@ int wtpman_handle_request(void *p) struct conn * conn = wtpman->conn; struct cwrmsg * cwrmsg = &conn->cwrmsg; switch(conn->cwrmsg.type){ - case CWMSG_ECHO_REQUEST: + case CW_MSG_ECHO_REQUEST: cw_handle_echo_request(conn); break; - case CWMSG_CHANGE_STATE_EVENT_REQUEST: + case CW_MSG_CHANGE_STATE_EVENT_REQUEST: cwread_change_state_event_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len); cwsend_change_state_event_response(wtpman->conn,cwrmsg->seqnum,wtpman->wtpinfo.radioinfo); break; @@ -341,7 +341,7 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti }while(!cwrmsg); - cw_dbg(DBG_CW_MSG,"Received message from %s, type=%d - %s" + cw_dbg(DBG_MSG,"Received message from %s, type=%d - %s" ,CLIENT_IP,cwrmsg->type,cw_msgtostr(cwrmsg->type)); return cwrmsg; @@ -362,14 +362,14 @@ static void wtpman_run_discovery(void *arg) if ( !cwrmsg ) { - cw_dbg(DBG_CW_MSG_ERR,"No complete message from %s received after %d seconds",CLIENT_IP,10); + cw_dbg(DBG_MSG_ERR,"No complete message from %s received after %d seconds",CLIENT_IP,10); wtpman_remove(wtpman); return; } if (cwrmsg->type!=CWMSG_DISCOVERY_REQUEST){ - cw_dbg(DBG_CW_MSG_ERR,"Invalid message in discovery state from %s, type=%s - %s ", + cw_dbg(DBG_MSG_ERR,"Invalid message in discovery state from %s, type=%s - %s ", CLIENT_IP,cwrmsg->type,cw_msgtostr(cwrmsg->type)); wtpman_remove(wtpman); return; @@ -439,7 +439,7 @@ static void wtpman_run_run(void *arg) - conn_prepare_request(conn,CWMSG_CONFIGURATION_UPDATE_REQUEST); + conn_prepare_request(conn,CW_MSG_CONFIGURATION_UPDATE_REQUEST); cwmsg_addelem(&conn->req_msg,CWMSGELEM_WTP_NAME,(uint8_t*)"Tube7u83",strlen("Tube7u83")+1); cwmsg_addelem(&conn->req_msg,CWMSGELEM_LOCATION_DATA,(uint8_t*)"Berlin",strlen("Berlin")+1); @@ -567,11 +567,11 @@ static int wtpman_join(void *arg,time_t timer) if (!cwrmsg){ if (conn_is_error(wtpman->conn)){ - cw_dbg(DBG_CW_MSG_ERR,"DTLS connection closed while waiting for join request from %s.",CLIENT_IP); + cw_dbg(DBG_MSG_ERR,"DTLS connection closed while waiting for join request from %s.",CLIENT_IP); return 0; } - cw_dbg(DBG_CW_MSG_ERR,"No join request from %s after %d seconds, WTP died.", + cw_dbg(DBG_MSG_ERR,"No join request from %s after %d seconds, WTP died.", sock_addr2str(&wtpman->conn->addr),wtpman->conn->wait_dtls); return 0; @@ -595,7 +595,7 @@ static int wtpman_join(void *arg,time_t timer) int result_code = 0; - cw_dbg(DBG_CW_MSG,"Sending join response to %s",CLIENT_IP); + cw_dbg(DBG_MSG,"Sending join response to %s",CLIENT_IP); printf("SLeep befor join resp\n"); printf("Slept befor join resp\n"); @@ -622,7 +622,7 @@ static int wtpman_send_image_file(struct wtpman * wtpman,struct cwrmsg * cwrmsg) cw_read_image_data_request(&data,cwrmsg->msgelems,cwrmsg->msgelems_len); if (!strlen(id)){ - cw_dbg(DBG_CW_MSG_ERR, "No image identifier in image data request"); + cw_dbg(DBG_MSG_ERR, "No image identifier in image data request"); cw_send_image_data_response(wtpman->conn,cwrmsg->seqnum,CW_RESULT_FAILURE); return 0; } @@ -684,18 +684,18 @@ static void wtpman_run(void *arg) */ do { - int cfg_status_msgs[] = { CWMSG_IMAGE_DATA_REQUEST, CW_MSG_CONFIGURATION_STATUS_REQUEST, -1 }; + int cfg_status_msgs[] = { CW_MSG_IMAGE_DATA_REQUEST, CW_MSG_CONFIGURATION_STATUS_REQUEST, -1 }; cwrmsg = conn_wait_for_request(wtpman->conn, cfg_status_msgs, timer); if (!cwrmsg){ - cw_dbg(DBG_CW_MSG_ERR,"No conf status or img data request from %s after %d seconds, WTP died.", + cw_dbg(DBG_MSG_ERR,"No conf status or img data request from %s after %d seconds, WTP died.", sock_addr2str(&wtpman->conn->addr),wtpman->conn->wait_join); wtpman_remove(wtpman); return; } /* Image data request, the WTP wants an update */ - if (cwrmsg->type==CWMSG_IMAGE_DATA_REQUEST){ + if (cwrmsg->type==CW_MSG_IMAGE_DATA_REQUEST){ int rc = wtpman_send_image_file(wtpman,cwrmsg); if (rc ){ wtpman_remove(wtpman); @@ -718,7 +718,7 @@ printf("Send the respi but sleep\n"); printf("Next thoing\n"); - int change_status_msgs[] = { CWMSG_IMAGE_DATA_REQUEST,CWMSG_CHANGE_STATE_EVENT_REQUEST, -1 }; + int change_status_msgs[] = { CW_MSG_IMAGE_DATA_REQUEST,CW_MSG_CHANGE_STATE_EVENT_REQUEST, -1 }; cwrmsg = conn_wait_for_request(wtpman->conn, change_status_msgs, timer); printf("Done\n"); @@ -730,14 +730,14 @@ printf("Done\n"); switch (cwrmsg->type){ - case CWMSG_CHANGE_STATE_EVENT_REQUEST: + case CW_MSG_CHANGE_STATE_EVENT_REQUEST: { printf("Change state event\n!"); struct radioinfo ri; cwsend_change_state_event_response(wtpman->conn,cwrmsg->seqnum,&ri); } break; - case CWMSG_IMAGE_DATA_REQUEST: + case CW_MSG_IMAGE_DATA_REQUEST: printf("Image update\n!"); //cwread_image_data_request(0,cwrmsg->msgelems,cwrmsg->msgelems_len); @@ -805,7 +805,7 @@ for (ii=0; ii<3; ii++){ exit(0); - if (cwrmsg->type==CWMSG_IMAGE_DATA_REQUEST){ + if (cwrmsg->type==CW_MSG_IMAGE_DATA_REQUEST){ cwread_image_data_request(0,cwrmsg->msgelems,cwrmsg->msgelems_len); cwsend_image_data_response(wtpman->conn,cwrmsg->seqnum,CW_RESULT_FAILURE); } @@ -829,7 +829,7 @@ exit(0); if (cwrmsg) printf("I have got a message of type %d\n",cwrmsg->type); - if (cwrmsg->type==CWMSG_IMAGE_DATA_REQUEST){ + if (cwrmsg->type==CW_MSG_IMAGE_DATA_REQUEST){ cwread_image_data_request(0,cwrmsg->msgelems,cwrmsg->msgelems_len); cwsend_image_data_response(wtpman->conn,cwrmsg->seqnum,CW_RESULT_FAILURE); } @@ -884,7 +884,7 @@ if (cwrmsg->type == CWMSG_CONFIGURATION_STATUS_REQUEST){ msg_counter=0; - if (cwrmsg->type == CWMSG_ECHO_REQUEST){ + if (cwrmsg->type == CW_MSG_ECHO_REQUEST){ cwsend_echo_response(wtpman->conn,cwrmsg->seqnum,wtpman->wtpinfo.radioinfo); } // printf("Got msg: %i\n",cwrmsg->type); diff --git a/src/capwap/Makefile b/src/capwap/Makefile index d2f77984..bf781a96 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -31,8 +31,8 @@ SOCKOBJS=sock_create.o sock_copyaddr.o sock_strtoaddr.o sock_cmpaddr.o sock_addr sock_getbroadcastaddr.o \ sock_addrinit.o \ sock_set_dontfrag.o \ - sock_get_primary_if.o - #sock_receive.o + sock_get_primary_if.o \ + sock_receive.o \ LOGOBJS=cw_log.o \ cw_log_debug.o \ @@ -95,12 +95,10 @@ CAPWAPOBJS= \ cwmsg_addelem_wtp_board_data.o \ cwmsg_addelem_cw_local_ip_addr.o \ cwmsg_addelem_mtu_discovery_padding.o \ - cwmsg_addelem_result_code.o \ cwmsg_addelem_ac_timestamp.o \ cw_addelem_vendor_specific_payload.o \ cwmsg_addelem_maximum_message_length.o \ cwmsg_addelem_image_identifier.o \ - cwmsg_addelem_radio_operational_state.o \ cwmsg_send.o \ cwsend_change_state_event_response.o \ cwsend_unknow_response.o \ @@ -109,6 +107,7 @@ CAPWAPOBJS= \ cwsend_discovery_request.o \ 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 \ @@ -158,10 +157,15 @@ CAPWAPOBJS= \ cwmsg_addelem_vendor_cisco_mwar_addr.o \ lw_readelem_wtp_board_data.o \ cw_readmsg_configuration_status_response.o \ + cw_readmsg_configuration_status_request.o \ cw_cisco_id_to_str.o\ + cw_readelem_cisco_wtp_radio_cfg.o \ + cw_addelem_cisco_wtp_radio_cfg.o #cw_ianavendoridtostr.o \ + #cwmsg_addelem_result_code.o \ +# cwmsg_addelem_radio_operational_state.o \ # cwmsg_addelem_vendor_cisco_ap_timesync.o \ # cwmsg_addelem_vendor_specific_payload.o \ @@ -217,10 +221,12 @@ CONNOBJS= conn_create.o \ conn_get_response.o \ conn_prepare_configuration_update_request.o \ cw_prepare_configuration_status_request.o \ + cw_prepare_change_state_event_request.o \ conn_prepare_request.o \ conn_prepare_image_data_request.o \ conn_send_request.o \ conn_wait_for_message.o \ + conn_wait_for_request.o \ conn_init.o diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index 909d7f18..ff23a4b8 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -108,23 +108,23 @@ struct capwap_ctrlhdr #define CW_MSG_CONFIGURATION_STATUS_REQUEST 5 #define CW_MSG_CONFIGURATION_STATUS_RESPONSE 6 -#define CWMSG_CONFIGURATION_UPDATE_REQUEST 7 -#define CWMSG_CONFIGURATION_UPDATE_RESPONSE 8 +#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7 +#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8 #define CWMSG_WTP_EVENT_REQUEST 9 #define CWMSG_WTP_EVENT_RESPONSE 10 -#define CWMSG_CHANGE_STATE_EVENT_REQUEST 11 -#define CWMSG_CHANGE_STATE_EVENT_RESPONSE 12 +#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11 +#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12 -#define CWMSG_ECHO_REQUEST 13 -#define CWMSG_ECHO_RESPONSE 14 +#define CW_MSG_ECHO_REQUEST 13 +#define CW_MSG_ECHO_RESPONSE 14 -#define CWMSG_IMAGE_DATA_REQUEST 15 -#define CWMSG_IMAGE_DATA_RESPONSE 16 +#define CW_MSG_IMAGE_DATA_REQUEST 15 +#define CW_MSG_IMAGE_DATA_RESPONSE 16 -#define CWMSG_RESET_REQUEST 17 + CWIANA_ENTERPRISE_NUMBER*256 -#define CWMSG_RESET_RESPONSE 18 + CWIANA_ENTERPRISE_NUMBER*256 +#define CW_MSG_RESET_REQUEST 17 + CWIANA_ENTERPRISE_NUMBER*256 +#define CW_MSG_RESET_RESPONSE 18 + CWIANA_ENTERPRISE_NUMBER*256 #define CWMSG_PRIMARY_DISCOVERY_REQUEST 19 + CWIANA_ENTERPRISE_NUMBER*256 #define CWMSG_PRIMARY_DISCOVERY_RESPONSE 20 + CWIANA_ENTERPRISE_NUMBER*256 @@ -150,6 +150,7 @@ struct capwap_ctrlhdr #define CW_ELEM_AC_IPV6_LIST 3 #define CW_ELEM_AC_NAME 4 #define CW_ELEM_AC_NAME_WITH_PRIORITY 5 +#define CW_ELEM_AC_NAME_WITH_INDEX 5 /* Draft 7 */ #define CW_ELEM_AC_TIMESTAMP 6 /* Add MAC ACL Entry 7 @@ -198,14 +199,14 @@ struct capwap_ctrlhdr #define CWMSGELEM_MTU_DISCOVERY_PADDING 52 #define CWMSGELEM_RADIO_ADMINISTRATIVE_STATE 31 -#define CWMSGELEM_RADIO_OPERATIONAL_STATE 32 +#define CW_ELEM_RADIO_OPERATIONAL_STATE 32 -#define CWMSGELEM_RESULT_CODE 33 +#define CW_ELEM_RESULT_CODE 33 /* Returned Message Element 34 */ #define CW_ELEM_SESSION_ID 35 -#define CWMSGELEM_STATISTICS_TIMER 36 +#define CW_ELEM_STATISTICS_TIMER 36 #define CW_ELEM_VENDOR_SPECIFIC_PAYLOAD 37 @@ -365,7 +366,7 @@ 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_result_code(struct cwmsg *msg, int rc); +//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); @@ -497,7 +498,8 @@ extern int cw_send_echo_response(struct conn *conn, int seqnum, struct 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_status_response(uint8_t * elems, int elems_len); +extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len); @@ -507,6 +509,7 @@ extern int cw_readmsg_configuration_status_response(uint8_t *elems,int elems_len #define cw_put_word lw_put_word #define cw_put_dword lw_put_dword #define cw_put_data lw_put_data +#define cw_put_bstr lw_put_bstr #define cw_get_byte lw_get_byte #define cw_get_word lw_get_word @@ -575,7 +578,7 @@ extern int cw_readmsg_configuration_status_response(uint8_t *elems,int elems_len * print_message(i); * ... * } - */ + */ #define cw_foreach_elem(i,elems,len) for(i=elems; irid); + 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); +} + + /* #define cw_put_elem_vendor_hdr(dst,vendorid,elemid,len)\ (cw_put_elem_hdr(dst,CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, \ @@ -651,7 +673,12 @@ extern int cw_addelem_vendor_specific_payload(uint8_t * dst, uint32_t vendorid, uint8_t * data, uint16_t len); -extern void cw_prepare_configuration_status_request(struct conn * conn, struct radioinfo * radioinfo, struct wtpinfo *wtpinfo); +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, + struct wtpinfo *wtpinfo); + +extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,struct radioinfo * radioinfo); #define cw_addelem_ac_name(dst,name) \ @@ -673,4 +700,10 @@ extern void cw_prepare_configuration_status_request(struct conn * conn, struct r #define cwmsg_addelem_session_id(cwmsg,sessid) \ (cwmsg)->pos+=cw_addelem_session_id((cwmsg)->msgelems+(cwmsg)->pos,sessid) +#define cwmsg_addelem_result_code(cwmsg,code) \ + (cwmsg)->pos+=cw_addelem_result_code((cwmsg)->msgelems+(cwmsg)->pos,code) + +#define cwmsg_addelem_radio_operational_state(cwmsg,ri) \ + (cwmsg)->pos+=cw_addelem_radio_operational_state((cwmsg)->msgelems+(cwmsg)->pos,ri) + #endif diff --git a/src/capwap/capwap_cisco.h b/src/capwap/capwap_cisco.h index 4f17eea4..811664e8 100644 --- a/src/capwap/capwap_cisco.h +++ b/src/capwap/capwap_cisco.h @@ -35,15 +35,22 @@ #define CW_CISCO_RAD_SLOT 4 #define CW_CISCO_RAD_NAME LW_ELEM_WTP_NAME /* 5 */ #define CW_CISCO_MWAR LW_ELEM_AC_DESCRIPTOR /* 6 */ -#define CW_CISCO_STATION_CFG 8 +#define CW_CISCO_WTP_RADIO_CFG 8 #define CW_CISCO_MULTI_DOMAIN_CAPAB LW_ELEM_80211_MULTI_DOMAIN_CAPABILITY /* 10 */ +#define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */ +#define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */ #define CW_CISCO_CERTIFICATE LW_ELEM_CERTIFICATE /* 44 */ #define CW_CISCO_WTP_BOARD_DATA LW_ELEM_WTP_BOARD_DATA /* 50 */ #define CW_CISCO_AP_MODE_AND_TYPE LW_ELEM_80211_WTP_MODE_AND_TYPE /* 54 */ -#define CW_CISCO_AP_IP_ADDR 83 +#define CW_CISCO_AC_IPV4_LIST LW_ELEM_AC_IPV4_LIST /* 59 */ + + +#define CW_CISCO_AP_STATIC_IP_ADDR 83 + +#define CW_CISCO_AC_NAME_WITH_INDEX 91 #define CW_CISCO_SPAM_VENDOR_SPECIFIC 104 @@ -56,6 +63,9 @@ #define CW_CISCO_AP_POWER_INJECTOR_CONFIG 138 #define CW_CISCO_AP_TIMESYNC 151 +#define CW_CISCO_AP_DOMAIN 169 +#define CW_CISCO_AP_DNS 170 + #define CW_CISCO_BOARD_DATA_OPTIONS 207 #define CW_CISCO_MWAR_TYPE 208 @@ -140,11 +150,13 @@ static inline int cw_addelem_cisco_certificate(uint8_t*dst,uint8_t*src,int len){ } - -static inline int cw_addelem_cisco_station_cfg(uint8_t * dst,struct radioinfo *ri){ +/* +static inline int cw_addelem_cisco_wtp_radio_cfg(uint8_t * dst,struct radioinfo *ri){ int l = lw_put_80211_wtp_wlan_radio_configuration(dst+10,ri); return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_STATION_CFG,l); } +*/ + static inline int cw_readelem_cisco_station_cfg(uint8_t *src,int len){ @@ -152,7 +164,10 @@ static inline int cw_readelem_cisco_station_cfg(uint8_t *src,int len){ return 0; } -const char * cw_cisco_id_to_str(int elem_id); +extern const char * cw_cisco_id_to_str(int elem_id); + +int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct radioinfo *ri); +int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri); @@ -183,8 +198,8 @@ const char * cw_cisco_id_to_str(int elem_id); #define cwmsg_addelem_cisco_ap_regulatory_domain(cwmsg,radioinfo)\ (cwmsg)->pos+=cw_addelem_cisco_ap_regulatory_domain(((cwmsg)->msgelems+(cwmsg)->pos),radioinfo) -#define cwmsg_addelem_cisco_station_cfg(cwmsg,radioinfo)\ - (cwmsg)->pos+=cw_addelem_cisco_station_cfg(((cwmsg)->msgelems+(cwmsg)->pos),radioinfo) +#define cwmsg_addelem_cisco_wtp_radio_cfg(cwmsg,radioinfo)\ + (cwmsg)->pos+=cw_addelem_cisco_wtp_radio_cfg(((cwmsg)->msgelems+(cwmsg)->pos),radioinfo) #endif diff --git a/src/capwap/conn.h b/src/capwap/conn.h index 868455e8..fc7fe49e 100644 --- a/src/capwap/conn.h +++ b/src/capwap/conn.h @@ -189,6 +189,7 @@ extern void conn_detect_capwap(struct conn * conn, struct wtpinfo * wtpinfo); struct cwrmsg * conn_send_request(struct conn * conn); struct cwrmsg * conn_wait_for_message(struct conn * conn, time_t timer); +struct cwrmsg * conn_wait_for_request(struct conn * conn, int *msglist, time_t timer); #define conn_is_error(conn) (conn->dtls_error) diff --git a/src/capwap/conn_prepare_configuration_update_request.c b/src/capwap/conn_prepare_configuration_update_request.c index ac67b9e7..768b646d 100644 --- a/src/capwap/conn_prepare_configuration_update_request.c +++ b/src/capwap/conn_prepare_configuration_update_request.c @@ -8,5 +8,5 @@ void conn_prepare_configuration_update_request(struct conn * conn) { struct cwmsg * cwmsg = &conn->req_msg; uint8_t * buffer = conn->req_buffer; - cwmsg_init(cwmsg,buffer,CWMSG_CONFIGURATION_UPDATE_REQUEST,conn_get_next_seqnum(conn),0); + cwmsg_init(cwmsg,buffer,CW_MSG_CONFIGURATION_UPDATE_REQUEST,conn_get_next_seqnum(conn),0); } diff --git a/src/capwap/conn_prepare_image_data_request.c b/src/capwap/conn_prepare_image_data_request.c index c9c02c28..7c3ef3d5 100644 --- a/src/capwap/conn_prepare_image_data_request.c +++ b/src/capwap/conn_prepare_image_data_request.c @@ -25,7 +25,7 @@ int conn_prepare_image_data_request(struct conn *conn, struct cwimage_data *data struct image_identifier *id) { struct cwmsg *cwmsg = &conn->req_msg; - cwmsg_init(cwmsg, conn->req_buffer, CWMSG_IMAGE_DATA_REQUEST, conn_get_next_seqnum(conn), + cwmsg_init(cwmsg, conn->req_buffer, CW_MSG_IMAGE_DATA_REQUEST, conn_get_next_seqnum(conn), 0); if (!data) diff --git a/src/capwap/cw_cisco_id_to_str.c b/src/capwap/cw_cisco_id_to_str.c index 32ea302f..5e2028b0 100644 --- a/src/capwap/cw_cisco_id_to_str.c +++ b/src/capwap/cw_cisco_id_to_str.c @@ -46,13 +46,32 @@ const char * cw_cisco_id_to_str(int elem_id) case CW_CISCO_SPAM_VENDOR_SPECIFIC: return "LWAPP Vendor Specific"; - case CW_CISCO_STATION_CFG: - return "Station CFG"; + case CW_CISCO_WTP_RADIO_CFG: + return "WTP Radio CFG"; case CW_CISCO_AP_REGULATORY_DOMAIN: return "AP Regulatory Domain"; case CW_CISCO_WTP_BOARD_DATA: return "WTP Board Data"; + case CW_CISCO_MULTI_DOMAIN_CAPAB: + return "Multi Domain Capability"; + + case CW_CISCO_AP_STATIC_IP_ADDR: + return "AP Static IP Addr"; + case CW_CISCO_AP_DOMAIN: + return "AP Domain"; + case CW_CISCO_AP_DNS: + return "AP DNS"; + case CW_CISCO_AC_NAME_WITH_INDEX: + return "AC Name with Index"; + case CW_CISCO_AC_IPV4_LIST: + return "AC IPv4 List"; + + case CW_CISCO_LOCATION_DATA: + return "Location Data"; + case CW_CISCO_STATISTICS_TIMER: + return "Statistics Timer"; + default: return "Unknown"; diff --git a/src/capwap/cw_log.h b/src/capwap/cw_log.h index d8e11d90..76e94595 100644 --- a/src/capwap/cw_log.h +++ b/src/capwap/cw_log.h @@ -34,6 +34,8 @@ */ #define DBG_MSG 0x00000001 /* Parsed CAPWAP/LWAPP messages */ +#define DBG_MSG_ERR 0x00000001 + #define DBG_ELEM 0x00000002 /* Parsed CAPWAP/LWAPP message elements */ #define DBG_ELEM_DMP 0x00000004 /* Dump CAPWAP message elements */ @@ -102,16 +104,7 @@ extern int cw_dbg_opt_level; #endif #ifdef WITH_CW_LOG_DEBUG -/* - #define cw_log_debug0(...) cw_log_debug_cbs[0](__VA_ARGS__) - #define cw_log_debug1(...) cw_log_debug_cbs[1](__VA_ARGS__) - #define cw_log_debug2(...) cw_log_debug_cbs[2](__VA_ARGS__) - #define cw_log_debug_dump(level,str,len,...) cw_log_debug_dump_(level,str,len,__VA_ARGS__) - #define cw_log_debug0_dump(str,len,...) cw_log_debug_dump_(0,str,len,__VA_ARGS__) - #define cw_log_debug1_dump(str,len,...) cw_log_debug_dump_(1,str,len,__VA_ARGS__) - #define cw_log_debug2_dump(str,len,...) cw_log_debug_dump_(2,str,len,__VA_ARGS__) - #define cw_log_debug(level,...) cw_log_debug_cbs[level](__VA_ARGS__) -*/ + #define cw_log_dbg(type,...) cw_log_dbg_(type,__FILE__,__LINE__,__VA_ARGS__) #define cw_dbg(type,...) cw_log_dbg_(type,__FILE__,__LINE__,__VA_ARGS__) @@ -120,20 +113,12 @@ extern int cw_dbg_opt_level; #define cw_dbg_msgelem(msgtype,msgelemtype,msgbuf,msglen) cw_dbg_msgelem_(msgtype,msgelemtype,msgbuf,msglen) #define cw_dbg_missing_mand_elems(conn, msgtyoe, mand) cw_dbg_missing_mand_elems_(conn, msgtyoe, mand) + #define lw_dbg_elem(msgtype,msgelemtype,msgbuf,msglen) lw_dbg_elem_(msgtype,msgelemtype,msgbuf,msglen) + #else #define cw_log_dbg(...) #define cw_dbg(...) - -/* #define cw_log_debug0(...) - #define cw_log_debug1(...) - #define cw_log_debug2(...) - #define cw_log_debug(...) - #define cw_log_debug_dump(level,str,len) - #define cw_log_debug0_dump(level,str,len) - #define cw_log_debug1_dump(level,str,len) - #define cw_log_debug2_dump(level,str,len) -*/ #define cw_dbg_missing_mand_elems(conn, msgtyoe, mand) #endif @@ -149,10 +134,12 @@ extern void cw_log_tofile(int level,const char *format, ...); extern void cw_dbg_msgelem_(int msg, int msgelem, const uint8_t *msgbuf,int len); + + struct conn; extern void cw_dbg_missing_mand_elems_(struct conn * conn,int msgtyoe, int * mand); - +extern void lw_dbg_elem(int msg_id,int elem_id,const uint8_t*elem_data,int elem_len); extern int cw_log_debug_level; extern int cw_log_str2dbglevel(const char * str); diff --git a/src/capwap/cw_log_debug.c b/src/capwap/cw_log_debug.c index 59271000..4e8eed29 100644 --- a/src/capwap/cw_log_debug.c +++ b/src/capwap/cw_log_debug.c @@ -29,6 +29,9 @@ #include "cw_log.h" #include "capwap.h" +#include "capwap_cisco.h" +#include "lwapp_cisco.h" + #include "cw_util.h" @@ -80,8 +83,7 @@ static void cw_log_debug2_(const char *format, ...) -int cw_log_debug_dump_(int level, const uint8_t * data, int len, - const char *format, ...) +int cw_log_debug_dump_(int level, const uint8_t * data, int len, const char *format, ...) { int maxtlen = 2048; int i; @@ -129,8 +131,7 @@ int cw_log_debug_dump_(int level, const uint8_t * data, int len, } -void cw_log_dbg_(int level, const char *file, int line, const char *format, - ...) +void cw_log_dbg_(int level, const char *file, int line, const char *format, ...) { if (!(level & cw_dbg_opt_level)) @@ -152,8 +153,7 @@ void cw_log_dbg_(int level, const char *file, int line, const char *format, void cw_log_dbg_dmp_(int level, const char *file, int line, - const uint8_t * data, int len, const char *format, - ...) + const uint8_t * data, int len, const char *format, ...) { if (!(level & cw_dbg_opt_level)) @@ -254,6 +254,41 @@ cw_log_debug0_, cw_log_debug1_, cw_log_debug2_}; + + + + +int cw_format_vendor(char *dst, uint32_t vendor_id, int elem_id, const uint8_t * elem_data) +{ + switch (vendor_id) { + case CW_VENDOR_ID_CISCO: + { + sprintf(dst, "\n\t Cisco Vendor Specific: %d - %s", elem_id, + cw_cisco_id_to_str(elem_id)); + + /* dive into LWAPP vendor specific decoding */ + if (elem_id == CW_CISCO_SPAM_VENDOR_SPECIFIC) { + uint32_t lw_elem_id = lw_get_word(elem_data + 4 + 6); + char b[256]; + sprintf(b, "\n\t LWAPP Cisco Specific: %d - %s", + lw_elem_id, lw_cisco_id_to_str(lw_elem_id)); + strcat(dst, b); + + + + } + break; + } + + + + } + + return 0; +} + + + /** * print debug info for message elements */ @@ -265,13 +300,18 @@ void cw_dbg_msgelem_(int msg, int msgelem, const uint8_t * msgbuf, int len) const char *elemname; char vendorname[256]; + char vendor_details[265]; + *vendor_details = 0; + if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) { - int vendor = ntohl(*((uint32_t *) msgbuf)); + 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_ianavendoridtostr(vendor), type); + (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); } @@ -279,16 +319,47 @@ void cw_dbg_msgelem_(int msg, int msgelem, const uint8_t * msgbuf, int len) if (!cw_dbg_is_level(DBG_ELEM_DMP)) cw_dbg(DBG_ELEM, - "Reading %s msgelem, type=%d (%s), len=%d", - cw_msgtostr(msg), msgelem, elemname, len); + "%s, CAWPAP element: type=%d (%s), len=%d%s", + cw_msgtostr(msg), msgelem, elemname, len, vendor_details); else cw_dbg_dmp(DBG_ELEM, msgbuf, len, - "Reading %s msgelem, type=%d (%s), len=%d\n\t Dump ...", - cw_msgtostr(msg), msgelem, elemname, len); + "%s, CAPWAP element: type=%d (%s), len=%d%s\n\tDump ...", + cw_msgtostr(msg), msgelem, elemname, len, vendor_details); } +void lw_dbg_elem_(int msg_id, int elem_id, const uint8_t * elem_data, int elem_len) +{ + if (!cw_dbg_is_level(DBG_ELEM)) + return; + + const char *elem_name; + char vendorname[256]; + + if (elem_id == LW_ELEM_VENDOR_SPECIFIC) { + uint32_t vendor = lw_get_dword(elem_data); + int type = lw_get_word(elem_data + 4); + sprintf(vendorname, "%s/%s/%d", + (char *) lw_elem_id_to_str(elem_id), + (char *) lw_vendor_id_to_str(vendor), type); + elem_name = vendorname; + } else + elem_name = lw_elem_id_to_str(msg_id); + + + if (!cw_dbg_is_level(DBG_ELEM_DMP)) + cw_dbg(DBG_ELEM, + "%s, LWAPP element: type=%d (%s), len=%d", + lw_msg_id_to_str(msg_id), elem_id, elem_name, elem_len); + + else + cw_dbg_dmp(DBG_ELEM, elem_data, elem_len, + "%s, LWAPP element: type=%d (%s), len=%d\n\tDump ...", + lw_msg_id_to_str(msg_id), elem_id, elem_name, elem_len); + + +} void cw_dbg_missing_mand_elems_(struct conn *conn, int msgtype, int *mand) { @@ -298,13 +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_msgtostr(msgtype), str); } } - - - - - - diff --git a/src/capwap/cw_msgelemtostr.c b/src/capwap/cw_msgelemtostr.c index 1c02561e..d05e7ff3 100644 --- a/src/capwap/cw_msgelemtostr.c +++ b/src/capwap/cw_msgelemtostr.c @@ -21,9 +21,9 @@ #include "capwap_80211.h" -const char * cw_msgelemtostr(int elem) +const char * cw_msgelemtostr(int elem_id) { - switch (elem){ + switch (elem_id){ case CW_ELEM_AC_DESCRIPTOR: return "AC Descriptor"; case CW_ELEM_AC_IPV4_LIST: @@ -98,12 +98,10 @@ const char * cw_msgelemtostr(int elem) case CWMSGELEM_RADIO_ADMINISTRATIVE_STATE: return "radio administrative state"; - case CWMSGELEM_RADIO_OPERATIONAL_STATE: + case CW_ELEM_RADIO_OPERATIONAL_STATE: return "Radio Operational State"; -/* Radio Operational State 32 -*/ - case CWMSGELEM_RESULT_CODE: + case CW_ELEM_RESULT_CODE: return "Result Code"; /* Returned Message Element 34 @@ -111,7 +109,7 @@ const char * cw_msgelemtostr(int elem) case CW_ELEM_SESSION_ID: return "Session ID"; - case CWMSGELEM_STATISTICS_TIMER: + case CW_ELEM_STATISTICS_TIMER: return "Statistics Timer"; case CW_ELEM_VENDOR_SPECIFIC_PAYLOAD: diff --git a/src/capwap/cw_msgtostr.c b/src/capwap/cw_msgtostr.c index 256681cb..df570359 100644 --- a/src/capwap/cw_msgtostr.c +++ b/src/capwap/cw_msgtostr.c @@ -39,10 +39,10 @@ const char * cw_msgtostr(int type) case CW_MSG_CONFIGURATION_STATUS_RESPONSE: return "Configuration Status Response"; - case CWMSG_CONFIGURATION_UPDATE_REQUEST: + case CW_MSG_CONFIGURATION_UPDATE_REQUEST: return "configuration update request"; - case CWMSG_CONFIGURATION_UPDATE_RESPONSE: + case CW_MSG_CONFIGURATION_UPDATE_RESPONSE: return "configuration update response"; case CWMSG_WTP_EVENT_REQUEST: @@ -51,32 +51,32 @@ const char * cw_msgtostr(int type) return "wtp event response"; - case CWMSG_CHANGE_STATE_EVENT_REQUEST: + case CW_MSG_CHANGE_STATE_EVENT_REQUEST: return "change state event request"; - case CWMSG_CHANGE_STATE_EVENT_RESPONSE: + case CW_MSG_CHANGE_STATE_EVENT_RESPONSE: return "change state event response"; /* Change State Event Request 11 Change State Event Response 12 */ - case CWMSG_ECHO_REQUEST: + case CW_MSG_ECHO_REQUEST: return "echo request"; - case CWMSG_ECHO_RESPONSE: + case CW_MSG_ECHO_RESPONSE: return "echo response"; - case CWMSG_IMAGE_DATA_REQUEST: + case CW_MSG_IMAGE_DATA_REQUEST: return "image data request"; - case CWMSG_IMAGE_DATA_RESPONSE: + case CW_MSG_IMAGE_DATA_RESPONSE: return "image data response"; /* Image Data Request 15 Image Data Response 16 */ - case CWMSG_RESET_REQUEST: + case CW_MSG_RESET_REQUEST: return "reset request"; - case CWMSG_RESET_RESPONSE: + case CW_MSG_RESET_RESPONSE: return "reset response"; /* diff --git a/src/capwap/cw_prepare_configuration_status_request.c b/src/capwap/cw_prepare_configuration_status_request.c index da6aa741..036a5f04 100644 --- a/src/capwap/cw_prepare_configuration_status_request.c +++ b/src/capwap/cw_prepare_configuration_status_request.c @@ -21,8 +21,8 @@ void cw_prepare_configuration_status_request(struct conn * conn, struct radioinf cwmsg_addelem_cisco_ap_regulatory_domain(cwmsg,&wtpinfo->radioinfo[0]); cwmsg_addelem_cisco_ap_regulatory_domain(cwmsg,&wtpinfo->radioinfo[1]); - cwmsg_addelem_cisco_station_cfg(cwmsg,&wtpinfo->radioinfo[0]); - cwmsg_addelem_cisco_station_cfg(cwmsg,&wtpinfo->radioinfo[1]); + cwmsg_addelem_cisco_wtp_radio_cfg(cwmsg,&wtpinfo->radioinfo[0]); + cwmsg_addelem_cisco_wtp_radio_cfg(cwmsg,&wtpinfo->radioinfo[1]); /* uint8_t mtu[2048]; diff --git a/src/capwap/cw_read_image_data_request.c b/src/capwap/cw_read_image_data_request.c index efd9e246..80ff07a6 100644 --- a/src/capwap/cw_read_image_data_request.c +++ b/src/capwap/cw_read_image_data_request.c @@ -51,7 +51,7 @@ int cw_readelem_image_identifier(struct cwimage_data *data, int type,uint8_t *ms static int imgdata_request(void * ptr,int type,uint8_t* msgelem,int len) { - cw_dbg_msgelem(CWMSG_IMAGE_DATA_REQUEST, type, msgelem, 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); diff --git a/src/capwap/cw_readelem_radio_operational_state.c b/src/capwap/cw_readelem_radio_operational_state.c index 1bdf5303..6d5ba35b 100644 --- a/src/capwap/cw_readelem_radio_operational_state.c +++ b/src/capwap/cw_readelem_radio_operational_state.c @@ -22,7 +22,7 @@ int cw_readelem_radio_operational_state(struct radioinfo * radioinfo, int type,uint8_t *msgelem, int len) { - if (type != CWMSGELEM_RADIO_OPERATIONAL_STATE) + if (type != CW_ELEM_RADIO_OPERATIONAL_STATE) return 0; if (len<3) diff --git a/src/capwap/cw_readelem_result_code.c b/src/capwap/cw_readelem_result_code.c index 30fc69e8..d1123b80 100644 --- a/src/capwap/cw_readelem_result_code.c +++ b/src/capwap/cw_readelem_result_code.c @@ -22,7 +22,7 @@ int cw_readelem_result_code(uint32_t *result_code, int type, uint8_t * msgelem, int len) { - if (type != CWMSGELEM_RESULT_CODE) + if (type != CW_ELEM_RESULT_CODE) return 0; if (len!=4){ diff --git a/src/capwap/cw_readelem_statistics_timer.c b/src/capwap/cw_readelem_statistics_timer.c index cc62fc61..dc26c9c9 100644 --- a/src/capwap/cw_readelem_statistics_timer.c +++ b/src/capwap/cw_readelem_statistics_timer.c @@ -4,7 +4,7 @@ int cw_readelem_statistics_timer(uint16_t *timer, int type, uint8_t * msgelem, int len) { - if (type != CWMSGELEM_STATISTICS_TIMER) + if (type != CW_ELEM_STATISTICS_TIMER) return 0; if (len!=2){ diff --git a/src/capwap/cw_readelem_vendor_specific_payload.c b/src/capwap/cw_readelem_vendor_specific_payload.c index 1c1b3129..7a66b557 100644 --- a/src/capwap/cw_readelem_vendor_specific_payload.c +++ b/src/capwap/cw_readelem_vendor_specific_payload.c @@ -1,3 +1,8 @@ +/** + * @file + * @brief Implements cw_readelem_vendor_specific_payload + */ + #include @@ -31,6 +36,18 @@ int cw_readelem_cisco_payload(void *data,int msgtype,int elem_id,uint8_t *msgele } + case CW_MSG_CONFIGURATION_STATUS_RESPONSE: + { + + struct radioinfo ri; + //lw_read_elem_wtp_wlan_radio_ + //cw_read + + + } + + + default: return 0; @@ -44,6 +61,15 @@ int cw_readelem_cisco_payload(void *data,int msgtype,int elem_id,uint8_t *msgele } +/** + * Read a CAPWAP Vendor Specific Payload message element. + * @param data pointer to data where the results can be stored + * @param msgtype type of message in which the element was found + * @param elemtype element type, must be CW_ELEM_VENDOR_PECIFIC_PAYLOAD + * @param msgelem pointer to message elemenet data + * @param len length of message element data + * @return 1 = successful read\n 0 = no vendor specific payload element + */ int cw_readelem_vendor_specific_payload(void * data,int msgtype,int elemtype,uint8_t *msgelem, int len) { @@ -56,8 +82,8 @@ int cw_readelem_vendor_specific_payload(void * data,int msgtype,int elemtype,uin } - uint32_t vendor_id = ntohl( *((uint32_t*)msgelem) ); - uint16_t elem_id = ntohs( *( (uint16_t*)(msgelem+4) )); + uint32_t vendor_id = cw_get_dword(msgelem); + uint16_t elem_id = cw_get_word(msgelem+4); int elem_len = len - 6; switch (vendor_id) { diff --git a/src/capwap/cw_send_echo_response.c b/src/capwap/cw_send_echo_response.c index 64035c8d..d5a18adc 100644 --- a/src/capwap/cw_send_echo_response.c +++ b/src/capwap/cw_send_echo_response.c @@ -33,7 +33,7 @@ int cw_send_echo_response(struct conn * conn,int seqnum,struct radioinfo * radioinfo) { struct cwmsg * cwmsg = &conn->resp_msg; - cwmsg_init(cwmsg,conn->resp_buffer,CWMSG_ECHO_RESPONSE,seqnum,radioinfo); + cwmsg_init(cwmsg,conn->resp_buffer,CW_MSG_ECHO_RESPONSE,seqnum,radioinfo); conn_send_response(conn,cwmsg,seqnum); return 1; diff --git a/src/capwap/cw_send_image_data_response.c b/src/capwap/cw_send_image_data_response.c index e7483858..b180a02a 100644 --- a/src/capwap/cw_send_image_data_response.c +++ b/src/capwap/cw_send_image_data_response.c @@ -32,7 +32,7 @@ void cw_send_image_data_response(struct conn * conn,int seqnum, int rc) cw_dbg(DBG_MSG,"Sending image data response to %s, seq = %d",sock_addr2str(&conn->addr),seqnum); struct cwmsg * cwmsg = &conn->resp_msg; - cwmsg_init(cwmsg,conn->resp_buffer,CWMSG_IMAGE_DATA_RESPONSE,seqnum,NULL); + cwmsg_init(cwmsg,conn->resp_buffer,CW_MSG_IMAGE_DATA_RESPONSE,seqnum,NULL); cwmsg_addelem_result_code(cwmsg,rc); conn_send_response(conn,cwmsg,seqnum); diff --git a/src/capwap/cw_util.h b/src/capwap/cw_util.h index ed0c9795..9f78849d 100644 --- a/src/capwap/cw_util.h +++ b/src/capwap/cw_util.h @@ -31,7 +31,6 @@ extern int cw_format_version(char *s, bstr_t version, uint32_t vendor, char * def); extern int cw_is_printable(const uint8_t * s,int len); -extern const char * cw_ianavendoridtostr(int id); diff --git a/src/capwap/cwmsg.h b/src/capwap/cwmsg.h index 7452b54f..13560538 100644 --- a/src/capwap/cwmsg.h +++ b/src/capwap/cwmsg.h @@ -37,7 +37,7 @@ extern void cwmsg_init_echo_request(struct cwmsg * cwmsg,uint8_t *buffer,struct extern void cwmsg_addelem_mtu_discovery_padding(struct cwmsg * msg, struct conn* conn); extern void cwmsg_addelem_image_identifier(struct cwmsg *msg,uint32_t vendor_id,uint8_t *img, int len); -extern void cwmsg_addelem_radio_operational_state(struct cwmsg * cwmsg, struct radioinfo * ri); +//extern void cwmsg_addelem_radio_operational_state(struct cwmsg * cwmsg, struct radioinfo * ri); extern void cwmsg_addelem_vendor_cisco_mwar_addr(struct cwmsg *msg, struct conn *conn); diff --git a/src/capwap/cwmsg_addelem_radio_operational_state.c b/src/capwap/cwmsg_addelem_radio_operational_state.c index 76c16653..c91a6c2f 100644 --- a/src/capwap/cwmsg_addelem_radio_operational_state.c +++ b/src/capwap/cwmsg_addelem_radio_operational_state.c @@ -11,5 +11,5 @@ void cwmsg_addelem_radio_operational_state(struct cwmsg * cwmsg, struct radioinf s[1]=ri->state; s[2]=ri->cause; - cwmsg_addelem(cwmsg,CWMSGELEM_RADIO_OPERATIONAL_STATE,s,3); + cwmsg_addelem(cwmsg,CW_ELEM_RADIO_OPERATIONAL_STATE,s,3); } diff --git a/src/capwap/cwmsg_addelem_result_code.c b/src/capwap/cwmsg_addelem_result_code.c index 6774bdab..001687d0 100644 --- a/src/capwap/cwmsg_addelem_result_code.c +++ b/src/capwap/cwmsg_addelem_result_code.c @@ -5,6 +5,6 @@ void cwmsg_addelem_result_code(struct cwmsg *msg,int rc) { uint8_t c[4]; *((uint32_t*)c)= htonl(rc); - cwmsg_addelem(msg,CWMSGELEM_RESULT_CODE,c,4); + cwmsg_addelem(msg,CW_ELEM_RESULT_CODE,c,4); } diff --git a/src/capwap/cwmsg_addelem_vendor_cisco_mwar_addr.c b/src/capwap/cwmsg_addelem_vendor_cisco_mwar_addr.c index 8691de3c..6bacdc36 100644 --- a/src/capwap/cwmsg_addelem_vendor_cisco_mwar_addr.c +++ b/src/capwap/cwmsg_addelem_vendor_cisco_mwar_addr.c @@ -30,7 +30,7 @@ printf("Adding mwar addr %s\n",sock_addr2str(&conn->addr)); struct sockaddr_in * sain = (struct sockaddr_in*)&conn->addr; memcpy(data+1,(uint8_t*)&sain->sin_addr,4); cwmsg_addelem_vendor_specific_payload(msg, CW_VENDOR_ID_CISCO, - CWVENDOR_CISCO_MWAR_ADDR, + CW_CISCO_MWAR_ADDR, data,7); diff --git a/src/capwap/cwmsg_init_echo_request.c b/src/capwap/cwmsg_init_echo_request.c index b5293304..0c539358 100644 --- a/src/capwap/cwmsg_init_echo_request.c +++ b/src/capwap/cwmsg_init_echo_request.c @@ -22,7 +22,7 @@ void cwmsg_init_echo_request(struct cwmsg * cwmsg,uint8_t *buffer,struct conn * conn, struct radioinfo * radioinfo) { - cwmsg_init(cwmsg,buffer,CWMSG_ECHO_REQUEST,conn_get_next_seqnum(conn),radioinfo); + cwmsg_init(cwmsg,buffer,CW_MSG_ECHO_REQUEST,conn_get_next_seqnum(conn),radioinfo); } diff --git a/src/capwap/cwread_change_state_event_request.c b/src/capwap/cwread_change_state_event_request.c index 7a51f8cb..0cf1d99b 100644 --- a/src/capwap/cwread_change_state_event_request.c +++ b/src/capwap/cwread_change_state_event_request.c @@ -38,7 +38,7 @@ struct eparm { static int readelem(void * eparm,int type,uint8_t* msgelem,int len) { struct eparm * e = (struct eparm*)eparm; - cw_dbg_msgelem(CWMSG_CHANGE_STATE_EVENT_REQUEST,type,msgelem,len); + cw_dbg_msgelem(CW_MSG_CHANGE_STATE_EVENT_REQUEST,type,msgelem,len); /* mandatory elements */ if (cw_readelem_result_code(&e->result_code,type,msgelem,len)) @@ -64,8 +64,8 @@ foundX: int cwread_change_state_event_request(struct wtpinfo * wtpinfo, uint8_t * msg, int len) { int mand[] = { - CWMSGELEM_RADIO_OPERATIONAL_STATE, - CWMSGELEM_RESULT_CODE, + CW_ELEM_RADIO_OPERATIONAL_STATE, + CW_ELEM_RESULT_CODE, -1}; struct eparm eparm; diff --git a/src/capwap/cwread_configuration_status_request.c b/src/capwap/cwread_configuration_status_request.c index 1792fa90..e5273471 100644 --- a/src/capwap/cwread_configuration_status_request.c +++ b/src/capwap/cwread_configuration_status_request.c @@ -76,7 +76,7 @@ void cwread_configuration_status_request(struct wtpinfo * wtpinfo, uint8_t * msg CW_ELEM_AC_NAME, CWMSGELEM_WTP_REBOOT_STATISTICS, CWMSGELEM_RADIO_ADMINISTRATIVE_STATE, - CWMSGELEM_STATISTICS_TIMER, + CW_ELEM_STATISTICS_TIMER, -1}; struct eparm eparm; diff --git a/src/capwap/cwread_wtp_event_request.c b/src/capwap/cwread_wtp_event_request.c index de3ec3aa..358a9c85 100644 --- a/src/capwap/cwread_wtp_event_request.c +++ b/src/capwap/cwread_wtp_event_request.c @@ -14,7 +14,7 @@ struct eparm { static int readelem(void * eparm,int type,uint8_t* msgelem,int len) { struct eparm * e = (struct eparm*)eparm; - cw_dbg_msgelem(CWMSG_CHANGE_STATE_EVENT_REQUEST,type,msgelem,len); + cw_dbg_msgelem(CW_MSG_CHANGE_STATE_EVENT_REQUEST,type,msgelem,len); diff --git a/src/capwap/cwsend_change_state_event_response.c b/src/capwap/cwsend_change_state_event_response.c index d644cb59..987e341b 100644 --- a/src/capwap/cwsend_change_state_event_response.c +++ b/src/capwap/cwsend_change_state_event_response.c @@ -20,7 +20,7 @@ void cwsend_change_state_event_response(struct conn * conn,int seqnum, struct ra cw_dbg(DBG_MSG,"Sending change state response to %s, seq = %d",sock_addr2str(&conn->addr),seqnum); struct cwmsg * cwmsg = &conn->resp_msg; - cwmsg_init(cwmsg,conn->resp_buffer,CWMSG_CHANGE_STATE_EVENT_RESPONSE,seqnum,NULL); + cwmsg_init(cwmsg,conn->resp_buffer,CW_MSG_CHANGE_STATE_EVENT_RESPONSE,seqnum,NULL); cwmsg_addelem_result_code(cwmsg,0); // cwmsg_addelem_radio_operational_state(cwmsg,radioinfo); diff --git a/src/capwap/lw_cisco_id_to_str.c b/src/capwap/lw_cisco_id_to_str.c index 496ced95..266db537 100644 --- a/src/capwap/lw_cisco_id_to_str.c +++ b/src/capwap/lw_cisco_id_to_str.c @@ -12,6 +12,8 @@ const char * lw_cisco_id_to_str(int elem_id) return "MWAR Hash Value"; case LW_CISCO_AP_USERNAME_PASSWORD: return "AP Username and Password"; + case LW_CISCO_AC_IP_ADDR_WITH_INDEX: + return "AC IP Addr with Index"; default: return "Unknown"; diff --git a/src/capwap/lw_vendor_id_to_str.c b/src/capwap/lw_vendor_id_to_str.c index d0571b18..26e6490c 100644 --- a/src/capwap/lw_vendor_id_to_str.c +++ b/src/capwap/lw_vendor_id_to_str.c @@ -31,8 +31,8 @@ * Defines of only a view number of IDs. If the ID is unknown * the string "Unknown" is returned. */ -const char * cw_ianavendoridtostr(int id){ - switch(id){ +const char * lw_vendor_id_to_str(uint32_t vendor_id){ + switch(vendor_id){ case CW_VENDOR_ID_ZYXEL: return "ZyXEL Communications Corp."; case CW_VENDOR_ID_FSF: diff --git a/src/capwap/lwapp.h b/src/capwap/lwapp.h index e22e84fb..ec3e165f 100644 --- a/src/capwap/lwapp.h +++ b/src/capwap/lwapp.h @@ -71,8 +71,8 @@ -#define LWMSG_DISCOVERY_REQUEST 1 -#define LWMSG_DISCOVERY_RESPONSE 2 +#define LW_MSG_DISCOVERY_REQUEST 1 +#define LW_MSG_DISCOVERY_RESPONSE 2 #define LW_MSG_JOIN_REQUEST 3 #define LW_MSG_JOIN_RESPONSE 4 @@ -111,12 +111,16 @@ #define LW_ELEM_AC_DESCRIPTOR 6 #define LW_ELEM_AC_NAME 31 +#define LW_ELEM_LOCATION_DATA 35 +#define LW_ELEM_STATISTICS_TIMER 37 + #define LW_ELEM_SUPPORTED_RATES 16 #define LW_ELEM_TEST 18 #define LW_ELEM_CERTIFICATE 44 #define LW_ELEM_WTP_BOARD_DATA 50 +#define LW_ELEM_AC_IPV4_LIST 59 #define LW_ELEM_AP_IP_ADDR 82 #define LW_ELEM_VENDOR_SPECIFIC 104 @@ -126,6 +130,8 @@ /* LWAPP IEEE 802.11 bindings */ #define LW_ELEM_80211_WTP_WLAN_RADIO_CONFIGURATION 8 +#define LW_ELEM_80211_MULTI_DOMAIN_CAPABILITY 10 +#define LW_ELEM_80211_WTP_MODE_AND_TYPE 54 /* useful macros and inline functions */ @@ -193,6 +199,10 @@ extern int lw_readelem_wtp_name(bstr_t * dst, int type, uint8_t * msgelem, int l extern int lw_put_80211_wtp_wlan_radio_configuration(uint8_t*dst,struct radioinfo *ri); +extern const char * lw_vendor_id_to_str(uint32_t vendor_id); +extern const char * lw_elem_id_to_str(int elem_id); +extern const char * lw_msg_id_to_str(int msg_id); + #endif diff --git a/src/capwap/lwapp_cisco.h b/src/capwap/lwapp_cisco.h index a4236b94..17fd90a5 100644 --- a/src/capwap/lwapp_cisco.h +++ b/src/capwap/lwapp_cisco.h @@ -28,14 +28,22 @@ /* Vendor specific message elements LWAPP Cisco */ +#define LW_CISCO_AP_USERNAME_PASSWORD 20 + +#define LW_CISCO_AC_IP_ADDR_WITH_INDEX 32 +#define LW_CISCO_AP_LOGHOST_CONFIG 36 + #define LW_CISCO_PATH_MTU 73 +#define LW_CISCO_ADD_WLAN 128 + #define LW_CISCO_MWAR_HASH_VALUE 134 /* function proto types */ extern int lw_put_cisco_path_mtu(uint8_t *dst, uint16_t max, uint16_t padding); +extern const char * lw_cisco_id_to_str(int elem_id); /* diff --git a/src/capwap/radioinfo.h b/src/capwap/radioinfo.h index b23f662d..36aa5868 100644 --- a/src/capwap/radioinfo.h +++ b/src/capwap/radioinfo.h @@ -35,12 +35,16 @@ struct radioinfo{ uint16_t regDomain; uint8_t country_str[4]; + uint8_t country_str2[4]; + int cfp_period; int cfp_max_duration; int beacon_period; int dtim_period; int max_bssid; int occupancy_limit; + + bstr_t bssid; }; diff --git a/src/capwap/wtpinfo_print.c b/src/capwap/wtpinfo_print.c index 0b5b0259..e16652de 100644 --- a/src/capwap/wtpinfo_print.c +++ b/src/capwap/wtpinfo_print.c @@ -19,6 +19,7 @@ #include #include +#include "lwapp.h" #include "capwap.h" #include "capwap_80211.h" @@ -92,7 +93,7 @@ static int version_print(char *s, const uint8_t *version, int len, uint32_t vend } - rs+=sprintf(s+rs,", Vendor Id: %d, %s",vendor, cw_ianavendoridtostr(vendor)); + rs+=sprintf(s+rs,", Vendor Id: %d, %s",vendor, lw_vendor_id_to_str(vendor)); rs+=sprintf(s+rs,"\n"); return rs; @@ -180,7 +181,7 @@ for (i0=0; i0<10; i0++){ - s+=sprintf (s,"\tVendor ID: %d, %s\n", wtpinfo->vendor_id,cw_ianavendoridtostr(wtpinfo->vendor_id) ); + s+=sprintf (s,"\tVendor ID: %d, %s\n", wtpinfo->vendor_id,lw_vendor_id_to_str(wtpinfo->vendor_id) ); s+=sprintf (s,"\tModel No.: "); //, (!wtpinfo->model_no ? (uint8_t*)"Not set" : wtpinfo->model_no) ); s+=bstr_to_str(s,wtpinfo->model_no,0); diff --git a/src/wtp/configure.c b/src/wtp/configure.c index 5d7aa3c9..a3033e89 100644 --- a/src/wtp/configure.c +++ b/src/wtp/configure.c @@ -16,6 +16,13 @@ int configure() int rc = cw_readmsg_configuration_status_response(cwrmsg->msgelems,cwrmsg->msgelems_len); -exit(0); + printf("Chage Sate\n"); + cw_prepare_change_state_event_request(conn,rip,wtpinfo); + cwrmsg = conn_send_request(conn); + + + printf("Got change resp %p\n",cwrmsg); + + } diff --git a/src/wtp/run.c b/src/wtp/run.c index 42ecd133..a055a3e6 100644 --- a/src/wtp/run.c +++ b/src/wtp/run.c @@ -9,6 +9,7 @@ #include "capwap/cw_log.h" #include "capwap/dtls.h" #include "capwap/sock.h" +#include "capwap/cw_util.h" #include "wtp_conf.h" @@ -73,6 +74,9 @@ int run(struct conn * conn) struct radioinfo radioinfo; memset(&radioinfo,0,sizeof(radioinfo)); + + struct cwrmsg * cwrmsg; + echo_interval_timer=time(NULL); while (1){ if (time(NULL)-echo_interval_timer >= conf_echo_interval) @@ -85,7 +89,14 @@ int run(struct conn * conn) // cw_log_debug1("Sending echo request"); struct cwmsg *cwmsg=&conn->req_msg; uint8_t * buffer = conn->req_buffer; - cwmsg_init_echo_request(cwmsg,buffer,conn,&radioinfo); + + + struct wtpinfo * wtpinfo = get_wtpinfo(); + struct radioinfo *rip = &(wtpinfo->radioinfo[0]); + + cwmsg_init_echo_request(cwmsg,buffer,conn,rip); + +printf("Echo ->>>>>>>>>>>>>>>>>>>>> Seqnum %d\n",conn->req_msg.seqnum); printf("Conn target is %s",sock_addr2str(&conn->addr)); @@ -106,6 +117,17 @@ printf("Error !\n"); } echo_interval_timer=time(NULL); } + + time_t rt = cw_timer_start(5); + cwrmsg = conn_wait_for_request(conn,0,rt); + struct wtpinfo * wtpinfo = get_wtpinfo(); + struct radioinfo *rip = &(wtpinfo->radioinfo[0]); + + if(cwrmsg){ + cw_readmsg_configuration_update_request(cwrmsg->msgelems,cwrmsg->msgelems_len); + cw_send_configuration_update_response(conn,cwrmsg->seqnum,rip); + } + sleep(1); } diff --git a/src/wtp/wtpdrv.c b/src/wtp/wtpdrv.c index e44a5a4d..fea93c87 100644 --- a/src/wtp/wtpdrv.c +++ b/src/wtp/wtpdrv.c @@ -1227,7 +1227,8 @@ int wtpdrv_get_radioinfo(int rid,struct radioinfo * radioinfo) radioinfo->type|=rid+1; //CW_80211_RADIO_TYPE_B; //CWRADIO_TYPE_N; radioinfo->regDomain=1; - memcpy(radioinfo->country_str,"AUDE",4); + strcpy(radioinfo->country_str,"DE "); + strcpy(radioinfo->country_str2,"DE "); /*