diff --git a/src/ac/conf.c b/src/ac/conf.c index c4395410..e5522469 100644 --- a/src/ac/conf.c +++ b/src/ac/conf.c @@ -142,9 +142,9 @@ struct mod_ac * conf_mods[10]; static int init_mods() { - conf_mods[0]=modload_ac("cipwap"); - conf_mods[1]=modload_ac("capwap"); - conf_mods[2]=modload_ac("cisco"); + conf_mods[0]=modload_ac("cisco"); + conf_mods[1]=modload_ac("cipwap"); + conf_mods[2]=modload_ac("capwap"); conf_mods[3]=NULL; diff --git a/src/capwap/Makefile b/src/capwap/Makefile index 2e0ac6d2..4b0295a9 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -63,6 +63,8 @@ UTILOBJS= \ intavltree.o \ cw_util.o \ send.o \ + cw_read_wtp_descriptor_7.o \ + cw_read_wtp_descriptor_versions.o MAVLOBJS= \ mavl_del.o \ diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index d81fa2b5..b6ca721e 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -257,7 +257,7 @@ CW_MSG_MAXMSG = 26 #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 CW_ELEM_AC_NAME_WITH_PRIORITY /* Draft 7 naming */ +#define CW_ELEM_AC_NAME_WITH_INDEX CW_ELEM_AC_NAME_WITH_PRIORITY /* Draft 7 naming */ #define CW_ELEM_AC_TIMESTAMP 6 #define CW_ELEM_ADD_MAC_ACL_ENTRY 7 #define CW_ELEM_ADD_STATION 8 diff --git a/src/capwap/conn_process_packet.c b/src/capwap/conn_process_packet.c index 69639b64..02228e43 100644 --- a/src/capwap/conn_process_packet.c +++ b/src/capwap/conn_process_packet.c @@ -175,7 +175,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len, int i; for (i = 0; mods[i]; i++) { if (mods[i]->detect) { - if (mods[i]->detect(conn, rawmsg, len, from)) { + if (mods[i]->detect(conn, rawmsg, len, elems_len, from)) { cw_dbg(DBG_INFO, "Using mod '%s' to handle connection from %s", mods[i]->name, diff --git a/src/capwap/conn_process_packet2.c b/src/capwap/conn_process_packet2.c index 5b60d9ca..39fe4828 100644 --- a/src/capwap/conn_process_packet2.c +++ b/src/capwap/conn_process_packet2.c @@ -173,7 +173,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len, int i; for (i=0; mods[i]; i++){ if (mods[i]->detect){ - if (mods[i]->detect(conn,rawmsg,len,from)){ + if (mods[i]->detect(conn,rawmsg,len,elems_len,from)){ cw_dbg(DBG_INFO,"Using mod '%s' to handle connection from %s",mods[i]->name,sock_addr2str(from)); break; } diff --git a/src/capwap/mod.h b/src/capwap/mod.h index 1681c8f4..03f8fb43 100644 --- a/src/capwap/mod.h +++ b/src/capwap/mod.h @@ -20,7 +20,7 @@ struct mod_ac This function ifter receiving and disassembling a complete CAPWAP message. Either on Discovery Request or Join Request **/ - int (*detect)(struct conn *conn,const uint8_t *rawmsg, int rawlen,struct sockaddr *from); + int (*detect)(struct conn *conn,const uint8_t *rawmsg, int rawlen,int elems_len, struct sockaddr *from); /** used for private data */ void *data; diff --git a/src/mod/capwap/mod_capwap_ac.c b/src/mod/capwap/mod_capwap_ac.c index 14545a4f..e12ccfc7 100644 --- a/src/mod/capwap/mod_capwap_ac.c +++ b/src/mod/capwap/mod_capwap_ac.c @@ -24,7 +24,7 @@ static int init() } -static int detect(struct conn *conn,const uint8_t *rawmsg, int rawlen,struct sockaddr *from) +static int detect(struct conn *conn,const uint8_t *rawmsg, int rawlen,int elems_len,struct sockaddr *from) { cw_log(LOG_INFO,"Detecting ..."); conn->detected=1; diff --git a/src/mod/cipwap/mod_cipwap_ac.c b/src/mod/cipwap/mod_cipwap_ac.c index 4c943f4e..315473b8 100644 --- a/src/mod/cipwap/mod_cipwap_ac.c +++ b/src/mod/cipwap/mod_cipwap_ac.c @@ -12,7 +12,7 @@ int cipwap_init() } -static int detect(struct conn *conn,const uint8_t *rawmsg, int rawlen,struct sockaddr *from) +static int detect(struct conn *conn,const uint8_t *rawmsg, int rawlen,int elems_len, struct sockaddr *from) { cw_log(LOG_INFO,"Detecting ..."); return 0; diff --git a/src/mod/cisco/Makefile b/src/mod/cisco/Makefile index db0d5a7c..8aae4ea1 100644 --- a/src/mod/cisco/Makefile +++ b/src/mod/cisco/Makefile @@ -2,6 +2,7 @@ OBJS=\ mod_cisco_ac.o \ cisco_actions_ac.o \ + cisco_in_wtp_descriptor.o NAME=libcisco.a diff --git a/src/mod/cisco/cisco_actions_ac.c b/src/mod/cisco/cisco_actions_ac.c index 2869f686..00eec86b 100644 --- a/src/mod/cisco/cisco_actions_ac.c +++ b/src/mod/cisco/cisco_actions_ac.c @@ -23,6 +23,7 @@ #include "capwap_actions.h" #include "capwap/strheap.h" #include "capwap/radio.h" +#include "capwap/capwap_cisco.h" #include "mod_cisco.h" @@ -38,75 +39,31 @@ static cw_action_in_t actions_in[] = { } , - /* Element Discovery Type */ + /* Element WTP Descriptor */ { .capwap_state = CW_STATE_DISCOVERY, .msg_id = CW_MSG_DISCOVERY_REQUEST, - .elem_id = CW_ELEM_DISCOVERY_TYPE, - .start = cw_in_generic2, - .item_id = "discovery_type", + .elem_id = CW_ELEM_WTP_DESCRIPTOR, + .start = cisco_in_wtp_descriptor, + .item_id = "wtp_descriptor", .mand = 1, - .min_len = 1, - .max_len = 1 } , - /* Element WTP Frame Tunnel Mode */ { .capwap_state = CW_STATE_DISCOVERY, .msg_id = CW_MSG_DISCOVERY_REQUEST, - .elem_id = CW_ELEM_WTP_FRAME_TUNNEL_MODE, - .start = cw_in_generic2, - .item_id = "wtp_frame_tunnel_mode", - .mand = 1, - .min_len = 1, - .max_len = 1 - } - , - - /* Element WTP Mac Type */ - { - .capwap_state = CW_STATE_DISCOVERY, - .msg_id = CW_MSG_DISCOVERY_REQUEST, - .elem_id = CW_ELEM_WTP_MAC_TYPE, - .start = cw_in_generic2, - .item_id = "wtp_mac_type", - .mand = 1, - .min_len = 1, - .max_len = 1 - } - , - - - -// , - - /* Element WTP Board Data */ -// {0, 0, CW_STATE_CONFIGURE, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_BOARD_DATA, -// 1} - - - /* Vendor Specific Payload */ - { - .capwap_state = CW_STATE_DISCOVERY, - .msg_id = CW_MSG_DISCOVERY_REQUEST, - .elem_id = CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, - }, - - - /* Element WTP Name */ - { - .capwap_state = CW_STATE_DISCOVERY, - .msg_id = CW_MSG_DISCOVERY_REQUEST, - .elem_id = CW_ELEM_WTP_NAME, - .start = cw_in_generic2, + .vendor_id = CW_VENDOR_ID_CISCO, + .elem_id = CW_CISCO_RAD_NAME, + .start=cw_in_generic2, .item_id = "wtp_name", - .mand = 0, - .min_len = 1, - .max_len = 1024 + .min_len=1, + .max_len=512 } , + + /* End of list */ {0, 0} }; diff --git a/src/mod/cisco/cisco_in_wtp_descriptor.c b/src/mod/cisco/cisco_in_wtp_descriptor.c index 85f7baab..4203b2bc 100644 --- a/src/mod/cisco/cisco_in_wtp_descriptor.c +++ b/src/mod/cisco/cisco_in_wtp_descriptor.c @@ -17,149 +17,16 @@ */ -#include "capwap/capwap.h" -#include "capwap/capwap_items.h" +#include "capwap/cw.h" -#include "capwap/cw_util.h" -#include "capwap/dbg.h" - -#include "capwap/sock.h" - - -static int cw_read_wtp_descriptor_versions(mbag_t mbag, uint8_t * data, - int len, int silent) -{ - int i = 0; - while (i len) { - if (!silent) - cw_dbg(DBG_ELEM_ERR, - "WTP descriptor sub-element too long, length=%d>%d", - i + 8, len); - return 0; - } - - uint32_t vendor_id = cw_get_dword(data + i); - uint32_t val = cw_get_dword(data + i + 4); - - int subtype = (val >> 16) & 0xffff; - int sublen = val & 0xffff; - i += 8; - - if (sublen + i > len) { - if (!silent) - cw_dbg(DBG_ELEM_ERR, - "WTP Descriptor sub-element too long, length = %d", - sublen); - return 0; - } - - if (!silent) { - char *dmp; - char *dmpmem = NULL; - if (cw_dbg_is_level(DBG_SUBELEM_DMP)) { - dmpmem = cw_dbg_mkdmp(data + i, sublen); - dmp = dmpmem; - } else - dmp = ""; - cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d%s", subtype, - sublen, dmp); - - if (dmpmem) - free(dmpmem); - } - - switch (subtype) { - case CW_SUBELEM_WTP_HARDWARE_VERSION: - - mbag_set_vendorstr(mbag, - CW_ITEM_WTP_HARDWARE_VERSION, - vendor_id, data + i, sublen); - - break; - case CW_SUBELEM_WTP_SOFTWARE_VERSION: - - mbag_set_vendorstr(mbag, - CW_ITEM_WTP_SOFTWARE_VERSION, - vendor_id, data + i, sublen); - break; - case CW_SUBELEM_WTP_BOOTLOADER_VERSION: - - mbag_set_vendorstr(mbag, - CW_ITEM_WTP_BOOTLOADER_VERSION, - vendor_id, data + i, sublen); - -/* - mbag_set_dword(mbag, - CW_ITEM_WTP_BOOTLOADER_VENDOR, - vendor_id); - mbag_set_bstrn(mbag, - CW_ITEM_WTP_BOOTLOADER_VERSION, - data + i, sublen); -*/ - break; - default: - if (!silent) - cw_dbg(DBG_ELEM_ERR, - "Unknown WTP descriptor subelement, type = %d", - subtype); - break; - } - i += sublen; - - } //while (i < len); - - return 1; - -} - -static int cw_read_wtp_descriptor(mbag_t mbag, struct conn *conn, - struct cw_action_in *a, uint8_t * data, int len, - int silent) -{ - - - mbag_set_byte(mbag, CW_ITEM_WTP_MAX_RADIOS, cw_get_byte(data)); - mbag_set_byte(mbag, CW_ITEM_WTP_RADIOS_IN_USE, - cw_get_byte(data + 1)); - - - /* Get number of encryption elements */ - int ncrypt = cw_get_byte(data + 2); - if (ncrypt == 0) { - if (conn->strict_capwap) { - if (!silent) - cw_dbg(DBG_ELEM_ERR, - "Bad WTP Descriptor, number of encryption elements is 0."); - return 0; - } - if (!silent) - cw_dbg(DBG_RFC, - "Non standard conform WTP Descriptor, number of encryptoin elements is 0."); - } - - int pos = 3; - int i; - for (i = 0; i < ncrypt; i++) { - // It's a dummy for now - pos += 3; - } - - return cw_read_wtp_descriptor_versions(mbag, data + pos, len - pos, silent); - -} - - - -int capwap_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, +int cisco_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, struct sockaddr *from) { mbag_t mbag = conn->incomming; - int rc =cw_read_wtp_descriptor(mbag, conn, a, data, len, 0); + int rc =cw_read_wtp_descriptor_7(mbag, conn, a, data, len); return rc; } diff --git a/src/mod/cisco/mod_cisco.h b/src/mod/cisco/mod_cisco.h index e9afa38f..9a2900ca 100644 --- a/src/mod/cisco/mod_cisco.h +++ b/src/mod/cisco/mod_cisco.h @@ -3,4 +3,8 @@ struct mod_ac * mod_cisco_ac(); +extern int cisco_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len, struct sockaddr *from); + + #endif diff --git a/src/mod/cisco/mod_cisco_ac.c b/src/mod/cisco/mod_cisco_ac.c index feeb0647..8b50ea4c 100644 --- a/src/mod/cisco/mod_cisco_ac.c +++ b/src/mod/cisco/mod_cisco_ac.c @@ -1,4 +1,5 @@ +#include "capwap/capwap.h" #include "capwap/mod.h" #include "capwap/log.h" #include "capwap/dbg.h" @@ -6,37 +7,58 @@ #include "capwap/action.h" #include "mod_cisco.h" +#include "../modload.h" static struct cw_actiondef actions; -#include "../modload.h" extern int cisco_register_actions_ac(struct cw_actiondef *def); static int init() { - struct mod_ac * cmod = modload_ac("capwap"); - - cmod->register_actions(&actions); - - - cw_dbg(DBG_INFO,"Initialiazing mod_cisco ..."); + struct mod_ac * cmod = modload_ac("capwap"); + cmod->register_actions(&actions); + if (!cmod ){ + cw_log(LOG_ERR,"Can't initzialize mod_cisco, failed to load bas mod mod_capwap"); + return 1; + } + int rc = cisco_register_actions_ac(&actions); cw_dbg(DBG_INFO,"Initialized mod cisco with %d actions",rc); return 0; } -static int detect(struct conn *conn,const uint8_t *rawmsg, int rawlen,struct sockaddr *from) +static int detect(struct conn *conn,const uint8_t *rawmsg, int rawlen,int elems_len,struct sockaddr *from) { - cw_log(LOG_INFO,"Detecting ..."); - conn->detected=1; - conn->actions=&actions; - return 1; + + int offset = cw_get_hdr_msg_offset(rawmsg); + const uint8_t *msg_ptr = rawmsg + offset; + + const uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr); + const uint8_t *elem; + + + cw_foreach_elem(elem, elems_ptr, elems_len) { + int id = cw_get_elem_id(elem); + if (id==CW_ELEM_VENDOR_SPECIFIC_PAYLOAD){ + uint32_t vendor_id = cw_get_dword(cw_get_elem_data(elem)); + if (vendor_id==CW_VENDOR_ID_CISCO){ + conn->detected=1; + conn->actions=&actions; + return 1; + + } + + } + + } + + return 0; } static struct mod_ac capwap_ac = {