Strict mode is ceonsequntely paid attention no.
FossilOrigin-Name: 14cb543cc584b8895a1bbd4ab8ed4519030e8d27e4a17b13f4e0709992aa8cee
This commit is contained in:
		| @ -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; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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 | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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; | ||||
| 		} | ||||
| 	 | ||||
| 	} | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| #include <errno.h> | ||||
|  | ||||
| #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); | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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(i<len); | ||||
| 	} while (i < len); | ||||
|  | ||||
| 	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); | ||||
| 	if (rc==-1){ | ||||
| 		cw_dbg(DBG_RFC,"Bad WTP descriptor, trying cisco hack"); | ||||
| 		rc =readelem_wtp_descriptor(conn, a,data,len,1); | ||||
| 	switch (conn->capwap_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; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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 }  | ||||
| }; | ||||
|  | ||||
| @ -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)",\ | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user