Strict mode is ceonsequntely paid attention no.

FossilOrigin-Name: 14cb543cc584b8895a1bbd4ab8ed4519030e8d27e4a17b13f4e0709992aa8cee
This commit is contained in:
7u83@mail.ru 2015-04-12 17:19:29 +00:00
parent f1f5131735
commit eee2d96b22
26 changed files with 207 additions and 136 deletions

View File

@ -142,6 +142,8 @@ int main (int argc, const char * argv[])
cw_dbg_opt_display=DBG_DISP_ASC_DMP | DBG_DISP_COLORS; cw_dbg_opt_display=DBG_DISP_ASC_DMP | DBG_DISP_COLORS;
DBGX("Attention! %s","DBGX is ON!");
cw_register_actions_cipwap_ac(&capwap_actions); 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) 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 */ /* first of all check preamble */
int preamble = cw_get_hdr_preamble(buffer); int preamble = cw_get_hdr_preamble(buffer);
#ifdef WITH_DTLS
if (preamble != CAPWAP_PACKET_PREAMBLE && preamble != CAPWAP_DTLS_PACKET_PREAMBLE){ if (preamble != CAPWAP_PACKET_PREAMBLE && preamble != CAPWAP_DTLS_PACKET_PREAMBLE){
#else cw_dbg(DBG_PKT_ERR,"Discarding packet from %s, wrong preamble, preamble = 0x%01X",sock_addr2str(addr),preamble);
if (preamble != CAPWAP_PACKET_PREAMBLE ){
#endif
cw_dbg(DBG_PKT_ERR,"Discarding packet, wrong preamble, preamble = 0x%01X",preamble);
return; return;
} }
wtplist_lock(); wtplist_lock();
struct wtpman * wtpman = wtplist_get(addr); struct wtpman * wtpman = wtplist_get(addr);
if (!wtpman){ 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) 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){ switch (socklist[index].ac_proto){
case AC_PROTO_CAPWAP: case AC_PROTO_CAPWAP:
process_cw_ctrl_packet(index,addr,buffer,len); 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); process_lw_ctrl_packet(index,addr,buffer,len);
return; return;
} }
} }

View File

@ -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) static void wtpman_run_discovery(void *arg)
{ {
struct wtpman *wtpman = (struct wtpman *) arg; struct wtpman *wtpman = (struct wtpman *) arg;
struct cwrmsg *cwrmsg; struct cwrmsg *cwrmsg;
struct conn * conn = wtpman->conn;
conn->strict_capwap=0;
time_t timer = cw_timer_start(10); time_t timer = cw_timer_start(10);

View File

@ -37,7 +37,6 @@ SOCKOBJS=sock_create.o sock_copyaddr.o sock_strtoaddr.o sock_cmpaddr.o sock_addr
LOGOBJS=log.o \ LOGOBJS=log.o \
log_syslog.o \ log_syslog.o \
log_file.o \ log_file.o \
cw_log_debug.o \
cw_dbg_elem.o \ cw_dbg_elem.o \
dbg_strings.o dbg_strings.o
@ -84,6 +83,7 @@ LWAPPOBJS = \
# lw_readelem_wtp_name.o \ # lw_readelem_wtp_name.o \
lw_readelem_wtp_board_data.o \ lw_readelem_wtp_board_data.o \
cw_log_debug.o \
# LWAPP cisco vendor specific objs # LWAPP cisco vendor specific objs

View File

@ -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; struct cw_action_in *e2 = (struct cw_action_in *) elem2;
int r; int r;
r = e1->capwap_state - e2->capwap_state;
if (r != 0)
return r;
r = e1->msg_id - e2->msg_id; r = e1->msg_id - e2->msg_id;
if (r != 0) if (r != 0)
return r; return r;
@ -41,10 +45,6 @@ static inline int cw_action_in_cmp(const void *elem1, const void *elem2)
if (r != 0) if (r != 0)
return r; return r;
r = e1->capwap_state - e2->capwap_state;
if (r != 0)
return r;
r = e1->vendor_id - e2->vendor_id; r = e1->vendor_id - e2->vendor_id;
if (r != 0) if (r != 0)
return r; return r;

View File

@ -97,15 +97,18 @@ extern int cw_actionlist_out_register_actions(cw_actionlist_out_t t,cw_action_ou
* Definition CAPWAP modes * Definition CAPWAP modes
*/ */
enum capwapmodes { enum capwapmodes {
/** Unknown -- means auto detect and
set as soon as possible */
CW_MODE_UNKNOWN,
/** Standard mode as specified in RFC 5415 */ /** Standard mode as specified in RFC 5415 */
CWMODE_STD = 0, CW_MODE_STD ,
/** Cisco specific CAPWAP */ /** Cisco specific CAPWAP */
CWMODE_CISCO, CW_MODE_CISCO,
/** CIPWAP, a mix of standard CAPWAP and some /** CIPWAP, a mix of standard CAPWAP and some
Cisco extension */ Cisco extension */
CWMODE_CIPWAP, CW_MODE_CIPWAP,
/** Zyxel */ /** Zyxel */
CWMODE_ZYXEL CW_MODE_ZYXEL
}; };

View File

@ -40,15 +40,7 @@
* Defines the structure of an AVL Node. * Defines the structure of an AVL Node.
*/ */
struct avlnode { struct avlnode {
union { void *data;
void *data;
uint8_t ubyte;
uint16_t uword;
uint32_t udword;
int8_t byte;
int16_t word;
int32_t dword;
};
struct avlnode *left; struct avlnode *left;
struct avlnode *right; struct avlnode *right;
int bal; int bal;

View File

@ -37,7 +37,7 @@
#include "strlist.h" #include "strlist.h"
/* capwap version and iana number */ /* 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 */ #define CWIANA_ENTERPRISE_NUMBER 0 /* for capwap base the number */
@ -96,8 +96,8 @@ enum capwap_states {
#define CWTH_WBID_EPCGLOBAL 3 #define CWTH_WBID_EPCGLOBAL 3
#define CAPWAP_PACKET_PREAMBLE (CW_VERSION<<4) #define CAPWAP_PACKET_PREAMBLE (CAPWAP_VERSION<<4)
#define CAPWAP_DTLS_PACKET_PREAMBLE (CW_VERSION<<4|1) #define CAPWAP_DTLS_PACKET_PREAMBLE (CAPWAP_VERSION<<4|1)
/* /*
* control header stuff * control header stuff

View File

@ -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, {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} 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 */ /* Element Frame Tunnel Mode */
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST,
CW_ACTION_IN_WTP_FRAME_TUNNEL_MODE, 1} 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, {0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST,
CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD} 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); rc += cw_strheap_register_strings(def->strelem, capwap_strings_elem);
intavltree_add(defs->wbids,0); intavltree_add(def->wbids,0);

View File

@ -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 * This message elemet is basically an LWAPP AC Descriptor
* encapsulated in a CAPWAP vendor specific payload message * encapsulated in a CAPWAP vendor specific payload message
*/ */
/*
static inline int cw_addelem_cisco_mwar(uint8_t *dst, struct ac_info *acinfo){ static inline int cw_addelem_cisco_mwar(uint8_t *dst, struct ac_info *acinfo){
int l = lw_put_ac_descriptor(dst+10,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); return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_MWAR,l);
} }
*/
/** /**
* Add a Cisco Certificate payload message element * Add a Cisco Certificate payload message element

View File

@ -40,6 +40,8 @@ void conn_init(struct conn * conn)
conn->wait_join=CAPWAP_WAIT_JOIN; conn->wait_join=CAPWAP_WAIT_JOIN;
conn->mtu_discovery=1; conn->mtu_discovery=1;
conn->remote = cw_itemstore_create(); conn->remote = cw_itemstore_create();
conn->capwap_mode = CW_MODE_UNKNOWN;
conn->strict_capwap=1;
} }

View File

@ -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; int result_code = 0;
if (afm->end) { if (afm->end) {
result_code = afm->end(conn, afm, rawmsg, len); 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 /* the end method gave us an result code, so
send an error message */ send an error message */
cw_send_error_response(conn, rawmsg, result_code); cw_send_error_response(conn, rawmsg, result_code);
} else { } else if ( result_code == 0 ){
/* regular response message */ /* All ok, send regular response message */
cw_send_response(conn, rawmsg, len); cw_send_response(conn, rawmsg, len);
} else {
/* the request message is ignored, no response
sent */
errno=EAGAIN;
} }
} else { } else {
/* whe have got a response message */ /*
* Whe have got a response message.
* Put further actions here, if needed.
*/
} }
intavltree_destroy(conn->mand); intavltree_destroy(conn->mand);

View File

@ -15,7 +15,7 @@ int conn_send_msg(struct conn * conn, uint8_t *rawmsg)
/* Zyxel doesn't count msg element length from /* Zyxel doesn't count msg element length from
behind seqnum */ behind seqnum */
if (conn->capwap_mode == CWMODE_ZYXEL){ if (conn->capwap_mode == CW_MODE_ZYXEL){
// XXX val-=3; // 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; 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; 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); //printf("Send packet len %p %d\n",ptr,packetlen);
return conn->write(conn,ptr,packetlen); return conn->write(conn,ptr,packetlen-0);
} }

View File

@ -1,5 +1,6 @@
#include "capwap.h" #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); DEFINE_AVLITER(it,conn->actions->in);
int n=0; int n=0;
avliter_foreach_from(&it,&as) { avliter_foreach_from(&it,&as) {
cw_action_in_t * a = avliter_get(&it); // avliter_foreach(&it) {
if (a->msg_id != as.msg_id) cw_action_in_t * ai = avliter_get(&it);
if (ai->msg_id != as.msg_id && ai->capwap_state != as.capwap_state)
break; break;
if (!a->mand) if (!ai->mand)
continue; continue;
int i = a->item_id; int i = ai->item_id;
void * rc = avltree_del(conn->mand,&i); void * rc = avltree_del(conn->mand,&i);
if (!rc) { if (!rc) {
out[n++]=a; out[n++]=ai;
} }
} }

View File

@ -19,14 +19,14 @@ int cw_in_capwap_control_ipv4_address(struct conn *conn, struct cw_action_in *a,
if (!list) { if (!list) {
cw_log(LOG_ERR, "Error: Can't allocate CAWAP IP Adress List"); cw_log(LOG_ERR, "Error: Can't allocate CAWAP IP Adress List");
return -1; return 0;
} }
cw_acip_t * acip; cw_acip_t * acip;
acip = malloc(sizeof(cw_acip_t)); acip = malloc(sizeof(cw_acip_t));
if (!acip) { if (!acip) {
cw_log(LOG_ERR,"Can't allocate memory for acv4ip: %s",strerror(errno)); cw_log(LOG_ERR,"Can't allocate memory for acv4ip: %s",strerror(errno));
return 1; return 0;
} }
struct sockaddr_in addr; 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); cw_aciplist_replace(list,acip);
return 0; return 1;
} }

View File

@ -11,21 +11,27 @@ int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * da
int len) int len)
{ {
cw_action_in_t *mlist[20]; cw_action_in_t *mlist[120];
int n = cw_check_missing_mand(mlist, conn, a); 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; conn->capwap_state = CW_STATE_NONE;
/* if mandatory elements are missing send no discovery response */ if (n && conn->strict_capwap) {
if (n) { 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, cw_dbg(DBG_MSG_ERR,
"Ignoring Discovery Request from %s - missing mandatory elements.", "Ignoring Discovery Request from %s - missing mandatory elements.",
sock_addr2str(&conn->addr)); sock_addr2str(&conn->addr));
return -1; return -1;
} }
if ( n ) {
/* put a warning here */
cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a);
}
/* ok, send response */ /* ok, send response */

View File

@ -1,3 +1,4 @@
#include <errno.h>
#include "capwap.h" #include "capwap.h"
#include "capwap_items.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]; cw_action_in_t *mlist[20];
int n = cw_check_missing_mand(mlist, conn, a); 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)); //cw_dbg(DBG_INFO,"This response came from: %s",sock_addr2str(&conn->addr));
/* if mandatory elements are missing, ignore this response */ /* 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, cw_dbg(DBG_MSG_ERR,
"Ignoring Discovery Response from %s - missing mandatory elements.", "Ignoring Discovery Response from %s - missing mandatory elements.",
sock_addr2str(&conn->addr)); sock_addr2str(&conn->addr));
errno = EAGAIN;
return -1; return -1;
} }
if (n) {
cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a);
}
/* we have all AC information in the incomming buffer */ /* we have all AC information in the incomming buffer */
cw_itemstore_t discs; 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 ) { if ( !discs ) {
cw_log(LOG_ERR,"Can't allocate store for disc resp"); 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); cw_itemstore_set_avltree(discs,discs->count,conn->incomming);

View File

@ -1,6 +1,7 @@
#include "action.h" #include "action.h"
#include "dbg.h" #include "dbg.h"
#include "log.h"
#include "itemstore.h" #include "itemstore.h"
#include "capwap.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: case CW_ITEMTYPE_VENDORSTR:
cw_itemstore_set_vendorstr(itemstore,a->item_id, cw_itemstore_set_vendorstr(itemstore,a->item_id,
cw_get_dword(data),data+4,len-4); 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;
} }
return 1;
//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;
} }

View File

@ -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) int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len)
{ {
if (len < 4) { if (len < 4) {
cw_dbg(DBG_ELEM_ERR, cw_dbg(DBG_ELEM_ERR,
"Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d", a->elem_id, "Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d", a->elem_id,
len); len);
return 1; return 0;
} }
cw_itemstore_t itemstore = conn->incomming; cw_itemstore_t itemstore = conn->incomming;
cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data)); cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data));
readsubelems_wtp_board_data(itemstore,data+4,len-4); readsubelems_wtp_board_data(itemstore,data+4,len-4);
return 1; return 1;
} }

View File

@ -25,87 +25,130 @@
#include "cw_util.h" #include "cw_util.h"
#include "dbg.h" #include "dbg.h"
#include "sock.h"
static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a,
static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t *data, int len, int cq) uint8_t * data, int len, int cq)
{ {
if (len<6) if (len < 6) {
return -1; return 0;
}
cw_itemstore_t itemstore = conn->incomming; 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_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_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; int i;
if (ncrypt == 0 ){ if (ncrypt == 0) {
/* non-conform */ /* non-conform */
cw_dbg(DBG_RFC,"Non-standard-conform WTP descriptor detected (See RFC 5415)"); cw_dbg(DBG_RFC,
if (!cq) "Non-standard-conform WTP descriptor detected (See RFC 5415)");
i=3; if (!cq)
i = 3;
else else
i=4; i = 4;
} } else {
else{ i = ncrypt * 3 + 3;
i=ncrypt*3+3;
} }
do { do {
if (i+8>len) if (i + 8 > len) {
{ cw_dbg(DBG_ELEM_ERR,
cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len); "WTP descriptor subelement to long, length=%d>%d", i + 8,
return -1; 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); uint32_t val = cw_get_dword(data + i + 4);
int subtype= (val>>16)&0xffff; int subtype = (val >> 16) & 0xffff;
int sublen = val&0xffff; int sublen = val & 0xffff;
i+=8; i += 8;
if (sublen+i>len){ if (sublen + i > len) {
cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement too long, length = %d",sublen); cw_dbg(DBG_ELEM_ERR,
return -1; "WTP Descriptor subelement too long, length = %d", sublen);
return 0;
} }
cw_dbg(DBG_SUBELEM,"Reading WTP descriptor subelement, type=%d,len=%d",subtype,sublen); cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d", subtype, sublen);
switch(subtype){ switch (subtype) {
case CW_SUBELEM_WTP_HARDWARE_VERSION: case CW_SUBELEM_WTP_HARDWARE_VERSION:
cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_HARDWARE_VENDOR,vendor_id); cw_itemstore_set_dword(itemstore,
cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_HARDWARE_VERSION,data+i,sublen); CW_ITEM_WTP_HARDWARE_VENDOR,
vendor_id);
cw_itemstore_set_bstrn(itemstore,
CW_ITEM_WTP_HARDWARE_VERSION,
data + i, sublen);
break; break;
case CW_SUBELEM_WTP_SOFTWARE_VERSION: case CW_SUBELEM_WTP_SOFTWARE_VERSION:
cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_SOFTWARE_VENDOR,vendor_id); cw_itemstore_set_dword(itemstore,
cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_SOFTWARE_VERSION,data+i,sublen); CW_ITEM_WTP_SOFTWARE_VENDOR,
vendor_id);
cw_itemstore_set_bstrn(itemstore,
CW_ITEM_WTP_SOFTWARE_VERSION,
data + i, sublen);
break; break;
case CW_SUBELEM_WTP_BOOTLOADER_VERSION: case CW_SUBELEM_WTP_BOOTLOADER_VERSION:
cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_BOOTLOADER_VENDOR,vendor_id); cw_itemstore_set_dword(itemstore,
cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_BOOTLOADER_VERSION,data+i,sublen); CW_ITEM_WTP_BOOTLOADER_VENDOR,
vendor_id);
cw_itemstore_set_bstrn(itemstore,
CW_ITEM_WTP_BOOTLOADER_VERSION,
data + i, sublen);
break; break;
default: 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; break;
} }
i+=sublen; i += sublen;
}while(i<len); } while (i < len);
return 1; return 1;
} }
int cw_in_wtp_descriptor(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len)
{ {
int rc =readelem_wtp_descriptor(conn, a,data,len,0); switch (conn->capwap_mode) {
if (rc==-1){ case CW_MODE_STD:
cw_dbg(DBG_RFC,"Bad WTP descriptor, trying cisco hack"); {
rc =readelem_wtp_descriptor(conn, a,data,len,1); 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; return rc;
} }

View File

@ -66,6 +66,10 @@ void cw_init_request(struct conn *conn, int msg_id)
uint8_t *buffer = conn->req_buffer; uint8_t *buffer = conn->req_buffer;
cw_put_dword(buffer + 0, 0); cw_put_dword(buffer + 0, 0);
/* unencrypted */
cw_put_hdr_preamble(CAPWAP_VERSION<<8 | 0);
cw_put_dword(buffer + 4, 0); cw_put_dword(buffer + 4, 0);
cw_set_hdr_preamble(buffer, 0); cw_set_hdr_preamble(buffer, 0);
cw_set_hdr_hlen(buffer, 2); cw_set_hdr_hlen(buffer, 2);

View File

@ -46,6 +46,7 @@ static struct cw_str color_on[] = {
{ DBG_ELEM, "\x1b[39m" }, { DBG_ELEM, "\x1b[39m" },
{ DBG_MSG_ERR, "\x1b[31m" }, { DBG_MSG_ERR, "\x1b[31m" },
{ DBG_PKT_ERR, "\x1b[31m" }, { DBG_PKT_ERR, "\x1b[31m" },
{ DBG_RFC, "\x1b[31m" },
{ DBG_X, "\x1b[31m" }, { DBG_X, "\x1b[31m" },
{ CW_STR_STOP, "" } { CW_STR_STOP, "" }
}; };
@ -68,6 +69,7 @@ static struct cw_str prefix[] = {
{ DBG_ELEM, " Msg Element -" }, { DBG_ELEM, " Msg Element -" },
{ DBG_MSG_ERR," Msg Error -" }, { DBG_MSG_ERR," Msg Error -" },
{ DBG_PKT_ERR," Pkt Error -" }, { DBG_PKT_ERR," Pkt Error -" },
{ DBG_RFC, " RFC Violation -" },
{ DBG_X, "XXXXX - "}, { DBG_X, "XXXXX - "},
{ CW_STR_STOP, "" } { 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, void cw_dbg_missing_mand(int level, struct conn *conn, cw_action_in_t ** ml, int n,
cw_action_in_t * a) 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; return;
char buffer[2000]; char buffer[2000];
@ -125,7 +130,7 @@ void cw_dbg_missing_mand(int level, struct conn *conn, cw_action_in_t ** ml, int
delim = ", "; delim = ", ";
p += sprintf(p, "%s", cw_strelemp(conn->actions, ml[i]->elem_id)); 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) int cw_format_pkt(char *dst,int level,struct conn *conn, uint8_t * packet, int len)

View File

@ -26,11 +26,16 @@ struct cw_str cw_dbg_strings[] = {
{ DBG_INFO, "info" }, { DBG_INFO, "info" },
{ DBG_PKT_IN, "pkt_in" }, { DBG_PKT_IN, "pkt_in" },
{ DBG_PKT_OUT, "pkt_out" }, { 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_IN, "msg_in" },
{ DBG_MSG_ERR, "msg_err" }, { DBG_MSG_ERR, "msg_err" },
{ DBG_ELEM, "elem" }, { DBG_ELEM, "elem" },
{ DBG_ELEM_DMP, "elem_dmp" }, { DBG_ELEM_DMP, "elem_dmp" },
{ DBG_ELEM_ERR, "elem_err" }, { DBG_ELEM_ERR, "elem_err" },
{ DBG_X,"dbgx" }, { DBG_X,"dbgx" },
{ CW_STR_STOP, NULL } { CW_STR_STOP, NULL }
}; };

View File

@ -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 #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) \ /*#define cw_format_hdr_flags(s,th) \
sprintf(s,"(T=%d,F=%d,L=%d,W=%d,M=%d,K=%d)",\ sprintf(s,"(T=%d,F=%d,L=%d,W=%d,M=%d,K=%d)",\

View File

@ -28,11 +28,11 @@
#include "capwap/capwap_items.h" #include "capwap/capwap_items.h"
#include "capwap/log.h" #include "capwap/log.h"
#include "capwap/wtpinfo.h" #include "capwap/wtpinfo.h"
#include "capwap/acinfo.h"
#include "capwap/sock.h" #include "capwap/sock.h"
#include "capwap/cw_util.h" #include "capwap/cw_util.h"
#include "capwap/aciplist.h" #include "capwap/aciplist.h"
#include "capwap/acpriolist.h" #include "capwap/acpriolist.h"
#include "capwap/timer.h"
#include "wtp.h" #include "wtp.h"

View File

@ -3,7 +3,6 @@
#include "capwap/wtpinfo.h" #include "capwap/wtpinfo.h"
#include "capwap/acinfo.h"
#include "capwap/conn.h" #include "capwap/conn.h"
#include "capwap/capwap_80211.h" #include "capwap/capwap_80211.h"
#include "capwap/log.h" #include "capwap/log.h"

View File

@ -82,7 +82,7 @@ int main()
cw_itemstore_set_byte(conn->local,CW_ITEM_WTP_FRAME_TUNNEL_MODE,0); cw_itemstore_set_byte(conn->local,CW_ITEM_WTP_FRAME_TUNNEL_MODE,0);
the_conn->strict_capwap=0;
discovery(); discovery();
join(); join();
image_update(); image_update();