From eee2d96b2207c6bd731e74a669f1be2cf6709187 Mon Sep 17 00:00:00 2001 From: "7u83@mail.ru" <7u83@mail.ru@noemail.net> Date: Sun, 12 Apr 2015 17:19:29 +0000 Subject: [PATCH] Strict mode is ceonsequntely paid attention no. FossilOrigin-Name: 14cb543cc584b8895a1bbd4ab8ed4519030e8d27e4a17b13f4e0709992aa8cee --- src/ac/ac_main.c | 29 +--- src/ac/wtpman.c | 5 + src/capwap/Makefile | 2 +- src/capwap/action.c | 8 +- src/capwap/action.h | 11 +- src/capwap/avltree.h | 10 +- src/capwap/capwap.h | 6 +- src/capwap/capwap_actions_ac.c | 19 +-- src/capwap/capwap_cisco.h | 3 + src/capwap/conn_init.c | 2 + src/capwap/conn_process_packet.c | 18 ++- src/capwap/conn_send_msg.c | 7 +- src/capwap/cw_check_missing_mand.c | 13 +- .../cw_in_capwap_control_ipv4_address.c | 6 +- src/capwap/cw_in_check_disc_req.c | 14 +- src/capwap/cw_in_check_disc_resp.c | 12 +- src/capwap/cw_in_generic.c | 12 +- src/capwap/cw_in_wtp_board_data.c | 4 +- src/capwap/cw_in_wtp_descriptor.c | 133 ++++++++++++------ src/capwap/cw_process_msg.c | 4 + src/capwap/dbg.c | 9 +- src/capwap/dbg_strings.c | 5 + src/capwap/format.h | 6 +- src/wtp/discovery.c | 2 +- src/wtp/wtp_interface.c | 1 - src/wtp/wtp_main.c | 2 +- 26 files changed, 207 insertions(+), 136 deletions(-) diff --git a/src/ac/ac_main.c b/src/ac/ac_main.c index ae0f8d23..09af81bf 100644 --- a/src/ac/ac_main.c +++ b/src/ac/ac_main.c @@ -142,6 +142,8 @@ int main (int argc, const char * argv[]) cw_dbg_opt_display=DBG_DISP_ASC_DMP | DBG_DISP_COLORS; + DBGX("Attention! %s","DBGX is ON!"); + cw_register_actions_cipwap_ac(&capwap_actions); @@ -305,26 +307,15 @@ int ac_run() void process_cw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len) { -// int sock = socklist[index].reply_sockfd; - - char hdrstr[1024]; - hdr_print(hdrstr,buffer,len); -// cw_dbg(DBG_CW_PKT_IN,"Header for packet from %s\n%s",sock_addr2str(addr),hdrstr); - - - /* first of all check preamble */ int preamble = cw_get_hdr_preamble(buffer); -#ifdef WITH_DTLS if (preamble != CAPWAP_PACKET_PREAMBLE && preamble != CAPWAP_DTLS_PACKET_PREAMBLE){ -#else - if (preamble != CAPWAP_PACKET_PREAMBLE ){ -#endif - cw_dbg(DBG_PKT_ERR,"Discarding packet, wrong preamble, preamble = 0x%01X",preamble); + cw_dbg(DBG_PKT_ERR,"Discarding packet from %s, wrong preamble, preamble = 0x%01X",sock_addr2str(addr),preamble); return; } + wtplist_lock(); struct wtpman * wtpman = wtplist_get(addr); if (!wtpman){ @@ -429,17 +420,6 @@ void process_lw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, void process_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len) { - -#ifdef WITH_CW_LOG_DEBUG - char str[100]; - sock_addrtostr(addr,str,100); -// cw_dbg(DBG_PKT_IN,"Received packet from %s, len = %i, via %s\n",sock_addr2str(addr),len, -// socklist[index].type==SOCKLIST_UNICAST_SOCKET ? "unicast":"bcast/mcast"); - -// cw_dbg_dmp(DBG_CW_PKT_DMP,buffer,len,"Dump ..."); -// cw_dbg_dmp(buffer,len,"Packet data for packet, recevied from %s",str); -#endif - switch (socklist[index].ac_proto){ case AC_PROTO_CAPWAP: process_cw_ctrl_packet(index,addr,buffer,len); @@ -448,7 +428,6 @@ void process_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int process_lw_ctrl_packet(index,addr,buffer,len); return; } - } diff --git a/src/ac/wtpman.c b/src/ac/wtpman.c index 2c4b7a4b..969d80b5 100644 --- a/src/ac/wtpman.c +++ b/src/ac/wtpman.c @@ -104,9 +104,14 @@ int check_discovery(struct conn *conn, struct cw_action_in *a, uint8_t * data, i static void wtpman_run_discovery(void *arg) { + struct wtpman *wtpman = (struct wtpman *) arg; struct cwrmsg *cwrmsg; + struct conn * conn = wtpman->conn; + +conn->strict_capwap=0; + time_t timer = cw_timer_start(10); diff --git a/src/capwap/Makefile b/src/capwap/Makefile index baaeacad..2275ab98 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -37,7 +37,6 @@ SOCKOBJS=sock_create.o sock_copyaddr.o sock_strtoaddr.o sock_cmpaddr.o sock_addr LOGOBJS=log.o \ log_syslog.o \ log_file.o \ - cw_log_debug.o \ cw_dbg_elem.o \ dbg_strings.o @@ -84,6 +83,7 @@ LWAPPOBJS = \ # lw_readelem_wtp_name.o \ lw_readelem_wtp_board_data.o \ + cw_log_debug.o \ # LWAPP cisco vendor specific objs diff --git a/src/capwap/action.c b/src/capwap/action.c index 0412f962..890bed8a 100644 --- a/src/capwap/action.c +++ b/src/capwap/action.c @@ -33,6 +33,10 @@ static inline int cw_action_in_cmp(const void *elem1, const void *elem2) struct cw_action_in *e2 = (struct cw_action_in *) elem2; int r; + r = e1->capwap_state - e2->capwap_state; + if (r != 0) + return r; + r = e1->msg_id - e2->msg_id; if (r != 0) return r; @@ -41,10 +45,6 @@ static inline int cw_action_in_cmp(const void *elem1, const void *elem2) 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; diff --git a/src/capwap/action.h b/src/capwap/action.h index 6c972baf..e5cc192a 100644 --- a/src/capwap/action.h +++ b/src/capwap/action.h @@ -97,15 +97,18 @@ extern int cw_actionlist_out_register_actions(cw_actionlist_out_t t,cw_action_ou * Definition CAPWAP modes */ enum capwapmodes { + /** Unknown -- means auto detect and + set as soon as possible */ + CW_MODE_UNKNOWN, /** Standard mode as specified in RFC 5415 */ - CWMODE_STD = 0, + CW_MODE_STD , /** Cisco specific CAPWAP */ - CWMODE_CISCO, + CW_MODE_CISCO, /** CIPWAP, a mix of standard CAPWAP and some Cisco extension */ - CWMODE_CIPWAP, + CW_MODE_CIPWAP, /** Zyxel */ - CWMODE_ZYXEL + CW_MODE_ZYXEL }; diff --git a/src/capwap/avltree.h b/src/capwap/avltree.h index 420face4..68dab140 100644 --- a/src/capwap/avltree.h +++ b/src/capwap/avltree.h @@ -40,15 +40,7 @@ * Defines the structure of an AVL Node. */ struct avlnode { - union { - void *data; - uint8_t ubyte; - uint16_t uword; - uint32_t udword; - int8_t byte; - int16_t word; - int32_t dword; - }; + void *data; struct avlnode *left; struct avlnode *right; int bal; diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index 67bed5ef..186034f3 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -37,7 +37,7 @@ #include "strlist.h" /* capwap version and iana number */ -#define CW_VERSION 0 +#define CAPWAP_VERSION ((uint8_t)0) #define CWIANA_ENTERPRISE_NUMBER 0 /* for capwap base the number */ @@ -96,8 +96,8 @@ enum capwap_states { #define CWTH_WBID_EPCGLOBAL 3 -#define CAPWAP_PACKET_PREAMBLE (CW_VERSION<<4) -#define CAPWAP_DTLS_PACKET_PREAMBLE (CW_VERSION<<4|1) +#define CAPWAP_PACKET_PREAMBLE (CAPWAP_VERSION<<4) +#define CAPWAP_DTLS_PACKET_PREAMBLE (CAPWAP_VERSION<<4|1) /* * control header stuff diff --git a/src/capwap/capwap_actions_ac.c b/src/capwap/capwap_actions_ac.c index 2e49830d..01a5f849 100644 --- a/src/capwap/capwap_actions_ac.c +++ b/src/capwap/capwap_actions_ac.c @@ -39,14 +39,6 @@ cw_action_in_t capwap_actions_ac_in[] = { {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE, cw_in_generic, 0, CW_ITEMTYPE_BYTE, CW_ITEM_DISCOVERY_TYPE, 1, 1, 1} , - /* Element WTP Board Data */ - {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_BOARD_DATA, - 1} - , - /* Element WTP Descriptor */ - {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_DESCRIPTOR, - 1} - , /* Element Frame Tunnel Mode */ {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_FRAME_TUNNEL_MODE, 1} @@ -58,6 +50,15 @@ cw_action_in_t capwap_actions_ac_in[] = { {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD} , + /* Element WTP Descriptor */ + {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_DESCRIPTOR, + 1} + , + /* Element WTP Board Data */ + {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_BOARD_DATA, + 1} + , + /* ------------------------------------------------------------------------------- */ @@ -253,7 +254,7 @@ int cw_register_actions_capwap_ac(struct cw_actiondef *def) rc += cw_strheap_register_strings(def->strelem, capwap_strings_elem); - intavltree_add(defs->wbids,0); + intavltree_add(def->wbids,0); diff --git a/src/capwap/capwap_cisco.h b/src/capwap/capwap_cisco.h index ff48978b..ef52fc07 100644 --- a/src/capwap/capwap_cisco.h +++ b/src/capwap/capwap_cisco.h @@ -153,10 +153,13 @@ static inline int cw_addelem_cisco_ap_regulatory_domain(uint8_t *dst, struct rad * This message elemet is basically an LWAPP AC Descriptor * encapsulated in a CAPWAP vendor specific payload message */ + +/* static inline int cw_addelem_cisco_mwar(uint8_t *dst, struct ac_info *acinfo){ int l = lw_put_ac_descriptor(dst+10,acinfo); return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_MWAR,l); } +*/ /** * Add a Cisco Certificate payload message element diff --git a/src/capwap/conn_init.c b/src/capwap/conn_init.c index a701bea8..fa74f442 100644 --- a/src/capwap/conn_init.c +++ b/src/capwap/conn_init.c @@ -40,6 +40,8 @@ void conn_init(struct conn * conn) conn->wait_join=CAPWAP_WAIT_JOIN; conn->mtu_discovery=1; conn->remote = cw_itemstore_create(); + conn->capwap_mode = CW_MODE_UNKNOWN; + conn->strict_capwap=1; } diff --git a/src/capwap/conn_process_packet.c b/src/capwap/conn_process_packet.c index 76caadcb..77f1f98d 100644 --- a/src/capwap/conn_process_packet.c +++ b/src/capwap/conn_process_packet.c @@ -254,6 +254,9 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) } + /* all message elements are processed, do now after processing + by calling the "end" function for the message */ + int result_code = 0; if (afm->end) { result_code = afm->end(conn, afm, rawmsg, len); @@ -265,14 +268,19 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) /* the end method gave us an result code, so send an error message */ cw_send_error_response(conn, rawmsg, result_code); - } else { - /* regular response message */ + } else if ( result_code == 0 ){ + /* All ok, send regular response message */ cw_send_response(conn, rawmsg, len); + } else { + /* the request message is ignored, no response + sent */ + errno=EAGAIN; } } else { - /* whe have got a response message */ - - + /* + * Whe have got a response message. + * Put further actions here, if needed. + */ } intavltree_destroy(conn->mand); diff --git a/src/capwap/conn_send_msg.c b/src/capwap/conn_send_msg.c index 9e6dce11..6e7152d0 100644 --- a/src/capwap/conn_send_msg.c +++ b/src/capwap/conn_send_msg.c @@ -15,7 +15,7 @@ int conn_send_msg(struct conn * conn, uint8_t *rawmsg) /* Zyxel doesn't count msg element length from behind seqnum */ - if (conn->capwap_mode == CWMODE_ZYXEL){ + if (conn->capwap_mode == CW_MODE_ZYXEL){ // XXX val-=3; } @@ -26,6 +26,9 @@ int conn_send_msg(struct conn * conn, uint8_t *rawmsg) int hlen = cw_get_hdr_hlen(rawmsg)*4; +//cw_set_hdr_hlen(rawmsg,223); +//*(rawmsg + 8)=99; +//cw_set_hdr_flags(rawmsg,CW_FLAG_HDR_M,1); int mtu = conn->mtu; @@ -94,6 +97,6 @@ int conn_send_msg(struct conn * conn, uint8_t *rawmsg) //printf("Send packet len %p %d\n",ptr,packetlen); - return conn->write(conn,ptr,packetlen); + return conn->write(conn,ptr,packetlen-0); } diff --git a/src/capwap/cw_check_missing_mand.c b/src/capwap/cw_check_missing_mand.c index 0b6990e2..3a99b472 100644 --- a/src/capwap/cw_check_missing_mand.c +++ b/src/capwap/cw_check_missing_mand.c @@ -1,5 +1,6 @@ #include "capwap.h" +#include "dbg.h" @@ -65,16 +66,18 @@ int cw_check_missing_mand(cw_action_in_t ** out, struct conn * conn, cw_action_i DEFINE_AVLITER(it,conn->actions->in); int n=0; avliter_foreach_from(&it,&as) { - cw_action_in_t * a = avliter_get(&it); - if (a->msg_id != as.msg_id) +// avliter_foreach(&it) { + cw_action_in_t * ai = avliter_get(&it); + + if (ai->msg_id != as.msg_id && ai->capwap_state != as.capwap_state) break; - if (!a->mand) + if (!ai->mand) continue; - int i = a->item_id; + int i = ai->item_id; void * rc = avltree_del(conn->mand,&i); if (!rc) { - out[n++]=a; + out[n++]=ai; } } diff --git a/src/capwap/cw_in_capwap_control_ipv4_address.c b/src/capwap/cw_in_capwap_control_ipv4_address.c index 4b8fdec4..1ab9e19b 100644 --- a/src/capwap/cw_in_capwap_control_ipv4_address.c +++ b/src/capwap/cw_in_capwap_control_ipv4_address.c @@ -19,14 +19,14 @@ int cw_in_capwap_control_ipv4_address(struct conn *conn, struct cw_action_in *a, if (!list) { cw_log(LOG_ERR, "Error: Can't allocate CAWAP IP Adress List"); - return -1; + return 0; } cw_acip_t * acip; acip = malloc(sizeof(cw_acip_t)); if (!acip) { cw_log(LOG_ERR,"Can't allocate memory for acv4ip: %s",strerror(errno)); - return 1; + return 0; } struct sockaddr_in addr; @@ -39,5 +39,5 @@ int cw_in_capwap_control_ipv4_address(struct conn *conn, struct cw_action_in *a, cw_aciplist_replace(list,acip); - return 0; + return 1; } diff --git a/src/capwap/cw_in_check_disc_req.c b/src/capwap/cw_in_check_disc_req.c index 82818dbd..e7c8b42d 100644 --- a/src/capwap/cw_in_check_disc_req.c +++ b/src/capwap/cw_in_check_disc_req.c @@ -11,21 +11,27 @@ int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * da int len) { - cw_action_in_t *mlist[20]; + cw_action_in_t *mlist[120]; int n = cw_check_missing_mand(mlist, conn, a); - cw_dbg_missing_mand(DBG_ELEM, conn, mlist, n, a); conn->capwap_state = CW_STATE_NONE; - /* if mandatory elements are missing send no discovery response */ - if (n) { + if (n && conn->strict_capwap) { + cw_dbg_missing_mand(DBG_MSG_ERR, conn, mlist, n, a); + /* if mandatory elements are missing, in strict + mode send no discovery response */ cw_dbg(DBG_MSG_ERR, "Ignoring Discovery Request from %s - missing mandatory elements.", sock_addr2str(&conn->addr)); return -1; } + if ( n ) { + /* put a warning here */ + cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a); + } + /* ok, send response */ diff --git a/src/capwap/cw_in_check_disc_resp.c b/src/capwap/cw_in_check_disc_resp.c index 2c503f3f..153f11fa 100644 --- a/src/capwap/cw_in_check_disc_resp.c +++ b/src/capwap/cw_in_check_disc_resp.c @@ -1,3 +1,4 @@ +#include #include "capwap.h" #include "capwap_items.h" @@ -11,18 +12,22 @@ int cw_in_check_disc_resp(struct conn *conn, struct cw_action_in *a, uint8_t * d { cw_action_in_t *mlist[20]; int n = cw_check_missing_mand(mlist, conn, a); - cw_dbg_missing_mand(DBG_ELEM, conn, mlist, n, a); //cw_dbg(DBG_INFO,"This response came from: %s",sock_addr2str(&conn->addr)); /* if mandatory elements are missing, ignore this response */ - if (n) { + if (n && conn->strict_capwap) { + cw_dbg_missing_mand(DBG_MSG_ERR, conn, mlist, n, a); cw_dbg(DBG_MSG_ERR, "Ignoring Discovery Response from %s - missing mandatory elements.", sock_addr2str(&conn->addr)); + errno = EAGAIN; return -1; } + if (n) { + cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a); + } /* we have all AC information in the incomming buffer */ cw_itemstore_t discs; @@ -32,7 +37,8 @@ int cw_in_check_disc_resp(struct conn *conn, struct cw_action_in *a, uint8_t * d if ( !discs ) { cw_log(LOG_ERR,"Can't allocate store for disc resp"); - return 0; + errno = ENOMEM; + return -1; } cw_itemstore_set_avltree(discs,discs->count,conn->incomming); diff --git a/src/capwap/cw_in_generic.c b/src/capwap/cw_in_generic.c index 9f6787fd..09567b4d 100644 --- a/src/capwap/cw_in_generic.c +++ b/src/capwap/cw_in_generic.c @@ -1,6 +1,7 @@ #include "action.h" #include "dbg.h" +#include "log.h" #include "itemstore.h" #include "capwap.h" @@ -42,15 +43,12 @@ int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int le case CW_ITEMTYPE_VENDORSTR: cw_itemstore_set_vendorstr(itemstore,a->item_id, cw_get_dword(data),data+4,len-4); + default: + cw_log(LOG_ERR,"Can't handle item type %d in definition for incomming msg %d (%s) - %d, cw_in_generic.", a->itemtype,a->msg_id,cw_strmsg(a->msg_id), a->elem_id); + return 0; } - - -//int src = cw_itemstore_set(conn->incomming,a->item_id,a->itemtype,data,len); - -//printf("Cunint ic: %d %d\n",src,conn->incomming->count); - - return 0; + return 1; } diff --git a/src/capwap/cw_in_wtp_board_data.c b/src/capwap/cw_in_wtp_board_data.c index a75fa48a..139f461a 100644 --- a/src/capwap/cw_in_wtp_board_data.c +++ b/src/capwap/cw_in_wtp_board_data.c @@ -89,17 +89,19 @@ static void readsubelems_wtp_board_data(cw_itemstore_t itemstore, uint8_t * msge */ int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len) { + if (len < 4) { cw_dbg(DBG_ELEM_ERR, "Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d", a->elem_id, len); - return 1; + return 0; } cw_itemstore_t itemstore = conn->incomming; cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data)); readsubelems_wtp_board_data(itemstore,data+4,len-4); + return 1; } diff --git a/src/capwap/cw_in_wtp_descriptor.c b/src/capwap/cw_in_wtp_descriptor.c index 167cf732..85e0d6c0 100644 --- a/src/capwap/cw_in_wtp_descriptor.c +++ b/src/capwap/cw_in_wtp_descriptor.c @@ -25,87 +25,130 @@ #include "cw_util.h" #include "dbg.h" +#include "sock.h" - -static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t *data, int len, int cq) +static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len, int cq) { - if (len<6) - return -1; + if (len < 6) { + return 0; + } cw_itemstore_t itemstore = conn->incomming; - cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data)); - cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1)); + cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_MAX_RADIOS, cw_get_byte(data)); + cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_RADIOS_IN_USE, + cw_get_byte(data + 1)); - int ncrypt = cw_get_byte(data+2); + /* Get number encryption elements */ + int ncrypt = cw_get_byte(data + 2); int i; - if (ncrypt == 0 ){ + if (ncrypt == 0) { + + + /* non-conform */ - cw_dbg(DBG_RFC,"Non-standard-conform WTP descriptor detected (See RFC 5415)"); - if (!cq) - i=3; + cw_dbg(DBG_RFC, + "Non-standard-conform WTP descriptor detected (See RFC 5415)"); + if (!cq) + i = 3; else - i=4; - } - else{ - i=ncrypt*3+3; + i = 4; + } else { + i = ncrypt * 3 + 3; } + + do { - if (i+8>len) - { - cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len); - return -1; + if (i + 8 > len) { + cw_dbg(DBG_ELEM_ERR, + "WTP descriptor subelement to long, length=%d>%d", i + 8, + len); + return 0; } - uint32_t vendor_id=cw_get_dword(data+i); //ntohl(*((uint32_t*)(msgelem+i))); + uint32_t vendor_id = cw_get_dword(data + i); //ntohl(*((uint32_t*)(msgelem+i))); - uint32_t val = cw_get_dword(data+i+4); - int subtype= (val>>16)&0xffff; - int sublen = val&0xffff; - i+=8; + uint32_t val = cw_get_dword(data + i + 4); + int subtype = (val >> 16) & 0xffff; + int sublen = val & 0xffff; + i += 8; - if (sublen+i>len){ - cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement too long, length = %d",sublen); - return -1; + if (sublen + i > len) { + cw_dbg(DBG_ELEM_ERR, + "WTP Descriptor subelement too long, length = %d", sublen); + return 0; } - cw_dbg(DBG_SUBELEM,"Reading WTP descriptor subelement, type=%d,len=%d",subtype,sublen); - - switch(subtype){ + cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d", subtype, sublen); + + switch (subtype) { case CW_SUBELEM_WTP_HARDWARE_VERSION: - cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_HARDWARE_VENDOR,vendor_id); - cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_HARDWARE_VERSION,data+i,sublen); + cw_itemstore_set_dword(itemstore, + CW_ITEM_WTP_HARDWARE_VENDOR, + vendor_id); + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_HARDWARE_VERSION, + data + i, sublen); break; case CW_SUBELEM_WTP_SOFTWARE_VERSION: - cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_SOFTWARE_VENDOR,vendor_id); - cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_SOFTWARE_VERSION,data+i,sublen); + cw_itemstore_set_dword(itemstore, + CW_ITEM_WTP_SOFTWARE_VENDOR, + vendor_id); + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_SOFTWARE_VERSION, + data + i, sublen); break; case CW_SUBELEM_WTP_BOOTLOADER_VERSION: - cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_BOOTLOADER_VENDOR,vendor_id); - cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_BOOTLOADER_VERSION,data+i,sublen); + cw_itemstore_set_dword(itemstore, + CW_ITEM_WTP_BOOTLOADER_VENDOR, + vendor_id); + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_BOOTLOADER_VERSION, + data + i, sublen); break; default: - cw_dbg(DBG_ELEM_ERR,"Unknown WTP descriptor subelement, type = %d",subtype); + cw_dbg(DBG_ELEM_ERR, + "Unknown WTP descriptor subelement, type = %d", + subtype); break; } - i+=sublen; + i += sublen; - }while(icapwap_mode) { + case CW_MODE_STD: + { + int rc = + readelem_wtp_descriptor(conn, a, data, len, + CW_MODE_STD); + if (!rc) { + cw_dbg(DBG_ELEM_ERR, "Bad WTP descriptor from %s", + sock_addr2str(&conn->addr)); + return 0; + } + return 1; + } + + + + } + + int rc = readelem_wtp_descriptor(conn, a, data, len, 0); + if (rc == -1) { + cw_dbg(DBG_RFC, "Bad WTP descriptor, trying cisco hack"); + rc = readelem_wtp_descriptor(conn, a, data, len, 1); } return rc; } - diff --git a/src/capwap/cw_process_msg.c b/src/capwap/cw_process_msg.c index 5b17dcac..c76cfbcf 100644 --- a/src/capwap/cw_process_msg.c +++ b/src/capwap/cw_process_msg.c @@ -66,6 +66,10 @@ void cw_init_request(struct conn *conn, int msg_id) uint8_t *buffer = conn->req_buffer; cw_put_dword(buffer + 0, 0); + + /* unencrypted */ + cw_put_hdr_preamble(CAPWAP_VERSION<<8 | 0); + cw_put_dword(buffer + 4, 0); cw_set_hdr_preamble(buffer, 0); cw_set_hdr_hlen(buffer, 2); diff --git a/src/capwap/dbg.c b/src/capwap/dbg.c index 69c7a869..952ce5cc 100644 --- a/src/capwap/dbg.c +++ b/src/capwap/dbg.c @@ -46,6 +46,7 @@ static struct cw_str color_on[] = { { DBG_ELEM, "\x1b[39m" }, { DBG_MSG_ERR, "\x1b[31m" }, { DBG_PKT_ERR, "\x1b[31m" }, + { DBG_RFC, "\x1b[31m" }, { DBG_X, "\x1b[31m" }, { CW_STR_STOP, "" } }; @@ -68,6 +69,7 @@ static struct cw_str prefix[] = { { DBG_ELEM, " Msg Element -" }, { DBG_MSG_ERR," Msg Error -" }, { DBG_PKT_ERR," Pkt Error -" }, + { DBG_RFC, " RFC Violation -" }, { DBG_X, "XXXXX - "}, { CW_STR_STOP, "" } }; @@ -113,7 +115,10 @@ static const char * get_dbg_color_ontext(int level){ void cw_dbg_missing_mand(int level, struct conn *conn, cw_action_in_t ** ml, int n, cw_action_in_t * a) { - if (!cw_dbg_is_level(DBG_MSG_ERR) || n == 0) +// if (!cw_dbg_is_level(DBG_MSG_ERR) || n == 0) +// return; + + if ( !cw_dbg_is_level(level) || n==0) return; char buffer[2000]; @@ -125,7 +130,7 @@ void cw_dbg_missing_mand(int level, struct conn *conn, cw_action_in_t ** ml, int delim = ", "; p += sprintf(p, "%s", cw_strelemp(conn->actions, ml[i]->elem_id)); } - cw_dbg(DBG_MSG_ERR, "Missing mandatory elements: [%s]", buffer); + cw_dbg(level, "Missing mandatory elements: [%s]", buffer); } int cw_format_pkt(char *dst,int level,struct conn *conn, uint8_t * packet, int len) diff --git a/src/capwap/dbg_strings.c b/src/capwap/dbg_strings.c index 3d165d6b..6a0ef620 100644 --- a/src/capwap/dbg_strings.c +++ b/src/capwap/dbg_strings.c @@ -26,11 +26,16 @@ struct cw_str cw_dbg_strings[] = { { DBG_INFO, "info" }, { DBG_PKT_IN, "pkt_in" }, { DBG_PKT_OUT, "pkt_out" }, + { DBG_PKT_ERR, "pkt_err" }, + { DBG_PKT_DMP, "pkt_dmp" }, + { DBG_RFC, "rfc" }, + { DBG_MSG_IN, "msg_in" }, { DBG_MSG_ERR, "msg_err" }, { DBG_ELEM, "elem" }, { DBG_ELEM_DMP, "elem_dmp" }, { DBG_ELEM_ERR, "elem_err" }, + { DBG_X,"dbgx" }, { CW_STR_STOP, NULL } }; diff --git a/src/capwap/format.h b/src/capwap/format.h index d8add300..6ad7dde1 100644 --- a/src/capwap/format.h +++ b/src/capwap/format.h @@ -53,7 +53,11 @@ extern int cw_format_hex_bytes(char *dst, const char *format, const char *delim, */ #define cw_format_hex cw_format_hexl - +/** + * Format MAC Address. + */ +#define cw_format_mac(dst,src,len)\ + cw_format_hex_bytes(dst,"%02x",":",src,len) /*#define cw_format_hdr_flags(s,th) \ sprintf(s,"(T=%d,F=%d,L=%d,W=%d,M=%d,K=%d)",\ diff --git a/src/wtp/discovery.c b/src/wtp/discovery.c index 8b361de7..d09e9f67 100644 --- a/src/wtp/discovery.c +++ b/src/wtp/discovery.c @@ -28,11 +28,11 @@ #include "capwap/capwap_items.h" #include "capwap/log.h" #include "capwap/wtpinfo.h" -#include "capwap/acinfo.h" #include "capwap/sock.h" #include "capwap/cw_util.h" #include "capwap/aciplist.h" #include "capwap/acpriolist.h" +#include "capwap/timer.h" #include "wtp.h" diff --git a/src/wtp/wtp_interface.c b/src/wtp/wtp_interface.c index 2d2ebedd..39d0708f 100644 --- a/src/wtp/wtp_interface.c +++ b/src/wtp/wtp_interface.c @@ -3,7 +3,6 @@ #include "capwap/wtpinfo.h" -#include "capwap/acinfo.h" #include "capwap/conn.h" #include "capwap/capwap_80211.h" #include "capwap/log.h" diff --git a/src/wtp/wtp_main.c b/src/wtp/wtp_main.c index 8037b982..a335ea37 100644 --- a/src/wtp/wtp_main.c +++ b/src/wtp/wtp_main.c @@ -82,7 +82,7 @@ int main() cw_itemstore_set_byte(conn->local,CW_ITEM_WTP_FRAME_TUNNEL_MODE,0); - + the_conn->strict_capwap=0; discovery(); join(); image_update();