Digging deepter into VM concepts...
FossilOrigin-Name: ba6454642f17c0f87106cb6af12689457433d44ba1fe2dd1ef920dba7be2ef27
This commit is contained in:
		| @ -35,7 +35,8 @@ | |||||||
| #include "socklist.h" | #include "socklist.h" | ||||||
|  |  | ||||||
| #include "db.h" | #include "db.h" | ||||||
|  | #include "capwap_items.h" | ||||||
|  | #include "capwap_cisco.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -53,11 +54,61 @@ void alive_thread(void *data) | |||||||
|  |  | ||||||
| cw_actionlist_t the_tree; | cw_actionlist_t the_tree; | ||||||
|  |  | ||||||
| int dstart(struct conn *conn,struct cw_action a,uint8_t *data,int len) | int dstart(struct conn *conn,struct cw_action_t * a,uint8_t *data,int len) | ||||||
| { | { | ||||||
| 	printf("DISCO STart Action!!\n"); | 	printf("DISCO STart Action!!\n"); | ||||||
|  |  | ||||||
|  | 	uint8_t * rmac = cw_get_hdr_rmac(data); | ||||||
|  | 	printf ("This msg is for %s\n",sock_hwaddr2str(bstr_data(rmac), bstr_len(rmac))); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int readelem_discovery_type(struct conn *conn,struct cw_action * a,uint8_t *data,int len) | ||||||
|  | { | ||||||
|  | 	printf("Discovery Type = %d\n",*data); | ||||||
|  | 	cw_itemstore_set_byte(conn->itemstore,CW_ITEM_DISCOVERY_TYPE,*data); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int readelem_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len) | ||||||
|  | { | ||||||
|  |         cw_action_t as,*af; | ||||||
|  | 	as = *a; | ||||||
|  |  | ||||||
|  | 	as.vendor_id = cw_get_dword(data); | ||||||
|  | 	as.elem_id = cw_get_word(data+4); | ||||||
|  | 	printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id); | ||||||
|  |  | ||||||
|  |  	af = cw_actionlist_get(conn->msgtr,&as); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	if (!af) { | ||||||
|  | 		printf("Msg unknown\n"); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	printf("Found\n"); | ||||||
|  |  | ||||||
|  | 	if (af->start) { | ||||||
|  | 		af->start(conn,af,data+6,len-6); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len) | ||||||
|  | { | ||||||
|  | 	printf("Here is the rad name reader\n"); | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	for (i=0; i<len; i++) { | ||||||
|  | 		printf("%c",data[i]); | ||||||
|  | 	} | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int main (int argc, const char * argv[])  | int main (int argc, const char * argv[])  | ||||||
| @ -69,27 +120,38 @@ the_tree=t; | |||||||
|  |  | ||||||
|  |  | ||||||
| cw_action_t discovery_actions[] = { | cw_action_t discovery_actions[] = { | ||||||
| { CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1,0,0, | { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1, | ||||||
|   dstart |   dstart,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_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA}, |   readelem_discovery_type,0 }, | ||||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, |  | ||||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, | { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, | ||||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE}, |   readelem_vendor_specific_payload,0 }, | ||||||
| {0} |  | ||||||
|  | { CW_VENDOR_ID_CISCO,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME, | ||||||
|  |   readelem_cisco_rad_name,0 }, | ||||||
|  |  | ||||||
|  |  | ||||||
|  | { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA}, | ||||||
|  | { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, | ||||||
|  | { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, | ||||||
|  | { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE}, | ||||||
|  |  | ||||||
|  |  | ||||||
|  | { 0,0,0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| cw_action_t join_actions[] = { | cw_action_t join_actions[] = { | ||||||
|  |  | ||||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,0,0}, | {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,0,0}, | ||||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE}, | {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE}, | ||||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA}, | {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA}, | ||||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, | {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, | ||||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, | {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, | ||||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_MAC_TYPE}, | {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_MAC_TYPE}, | ||||||
| {0} | {0} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -356,15 +356,32 @@ 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; | ||||||
| 	 | 	 | ||||||
|  | 	void conn_msg_processor(struct conn *conn); | ||||||
|  |  | ||||||
|  | 	time_t timer = cw_timer_start(10); | ||||||
|  |  | ||||||
| extern cw_actionlist_t the_tree; | extern cw_actionlist_t the_tree; | ||||||
| wtpman->conn->capwap_state=CW_STATE_DISCOVERY; | wtpman->conn->capwap_state=CW_STATE_DISCOVERY; | ||||||
| wtpman->conn->msgtr=the_tree; | wtpman->conn->msgtr=the_tree; | ||||||
|  |  | ||||||
|  | wtpman->conn->itemstore = cw_itemstore_create(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	time_t timer = cw_timer_start(10); | 	while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_DISCOVERY){ | ||||||
|  | 		conn_msg_processor(wtpman->conn); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | //	cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo); | ||||||
|  | 	wtpman_remove(wtpman); | ||||||
|  | 	return; | ||||||
|  | 	 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	timer = cw_timer_start(10); | ||||||
| 	cwrmsg = wtpman_wait_for_message(wtpman, timer); | 	cwrmsg = wtpman_wait_for_message(wtpman, timer); | ||||||
|  |  | ||||||
| 	if ( !cwrmsg  ) | 	if ( !cwrmsg  ) | ||||||
| @ -415,8 +432,6 @@ wtpman->conn->msgtr=the_tree; | |||||||
| */ | */ | ||||||
|  |  | ||||||
| 	cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo); | 	cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	wtpman_remove(wtpman); | 	wtpman_remove(wtpman); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -160,7 +160,11 @@ CAPWAPOBJS= \ | |||||||
| 	cw_readmsg_configuration_status_request.o \ | 	cw_readmsg_configuration_status_request.o \ | ||||||
| 	cw_cisco_id_to_str.o\ | 	cw_cisco_id_to_str.o\ | ||||||
| 	cw_readelem_cisco_wtp_radio_cfg.o \ | 	cw_readelem_cisco_wtp_radio_cfg.o \ | ||||||
| 	cw_addelem_cisco_wtp_radio_cfg.o | 	cw_addelem_cisco_wtp_radio_cfg.o \ | ||||||
|  | 	cw_strlist_get_str.o \ | ||||||
|  | 	capwap_msg_strings.o \ | ||||||
|  | 	capwap_state_strings.o \ | ||||||
|  | 	itemstore.o | ||||||
|  |  | ||||||
| 	 | 	 | ||||||
| 	   #cw_ianavendoridtostr.o \ | 	   #cw_ianavendoridtostr.o \ | ||||||
|  | |||||||
| @ -63,8 +63,10 @@ enum capwap_states { | |||||||
| 	CW_STATE_NONE=0, | 	CW_STATE_NONE=0, | ||||||
| 	CW_STATE_DISCOVERY, | 	CW_STATE_DISCOVERY, | ||||||
| 	CW_STATE_JOIN, | 	CW_STATE_JOIN, | ||||||
|  | 	CW_STATE_CONFIGURE, | ||||||
|  | 	CW_STATE_IMAGE, | ||||||
| 	CW_STATE_UPDATE, | 	CW_STATE_UPDATE, | ||||||
| 	CW_STATE_RUN, | 	CW_STATE_RUN | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -122,8 +124,8 @@ struct capwap_ctrlhdr | |||||||
| #define CW_MSG_CONFIGURATION_UPDATE_REQUEST	7 | #define CW_MSG_CONFIGURATION_UPDATE_REQUEST	7 | ||||||
| #define CW_MSG_CONFIGURATION_UPDATE_RESPONSE	8 | #define CW_MSG_CONFIGURATION_UPDATE_RESPONSE	8 | ||||||
|  |  | ||||||
| #define CWMSG_WTP_EVENT_REQUEST			9 | #define CW_MSG_WTP_EVENT_REQUEST			9 | ||||||
| #define CWMSG_WTP_EVENT_RESPONSE		10 | #define CW_MSG_WTP_EVENT_RESPONSE		10 | ||||||
|  |  | ||||||
| #define CW_MSG_CHANGE_STATE_EVENT_REQUEST	11 | #define CW_MSG_CHANGE_STATE_EVENT_REQUEST	11 | ||||||
| #define CW_MSG_CHANGE_STATE_EVENT_RESPONSE	12 | #define CW_MSG_CHANGE_STATE_EVENT_RESPONSE	12 | ||||||
| @ -137,8 +139,8 @@ struct capwap_ctrlhdr | |||||||
| #define CW_MSG_RESET_REQUEST			17 | #define CW_MSG_RESET_REQUEST			17 | ||||||
| #define CW_MSG_RESET_RESPONSE			18  | #define CW_MSG_RESET_RESPONSE			18  | ||||||
|  |  | ||||||
| #define CWMSG_PRIMARY_DISCOVERY_REQUEST		19  | #define CW_MSG_PRIMARY_DISCOVERY_REQUEST		19  | ||||||
| #define CWMSG_PRIMARY_DISCOVERY_RESPONSE	20  | #define CW_MSG_PRIMARY_DISCOVERY_RESPONSE	20  | ||||||
|  |  | ||||||
| /*           Data Transfer Request               21 | /*           Data Transfer Request               21 | ||||||
|            Data Transfer Response              22 |            Data Transfer Response              22 | ||||||
| @ -503,6 +505,9 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len) | |||||||
| #define cw_get_hdr_hlen(th) ((ntohl(((uint32_t*)th)[0]) >> 19) & 0x1f) | #define cw_get_hdr_hlen(th) ((ntohl(((uint32_t*)th)[0]) >> 19) & 0x1f) | ||||||
|  |  | ||||||
| #define cw_get_hdr_rmac(th) (th+8) | #define cw_get_hdr_rmac(th) (th+8) | ||||||
|  | #define cw_get_hdr_rmac_len(th) (*(th+8)) | ||||||
|  | #define cw_get_hdr_rmac_size(th) cw_get_hdr_rmac_len(th) | ||||||
|  | #define cw_get_hdr_rmac_data(th) (th+9) | ||||||
|  |  | ||||||
| #define cw_get_hdr_flag_r1(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R1 ) ? 1:0) | #define cw_get_hdr_flag_r1(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R1 ) ? 1:0) | ||||||
| #define cw_get_hdr_flag_r2(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R2 ) ? 1:0) | #define cw_get_hdr_flag_r2(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R2 ) ? 1:0) | ||||||
| @ -524,6 +529,10 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len) | |||||||
| #define cw_get_msg_elems_len(msgptr) ( cw_get_word( (msgptr) +5 )-3) | #define cw_get_msg_elems_len(msgptr) ( cw_get_word( (msgptr) +5 )-3) | ||||||
| #define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8) | #define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8) | ||||||
|  |  | ||||||
|  | static inline uint8_t * cw_get_hdr_msg_elems_ptr(uint8_t *m){ | ||||||
|  | 	return cw_get_msg_elems_ptr( m+cw_get_hdr_msg_offset(m) ); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Get length of a CAPWAP message elemet  |  * Get length of a CAPWAP message elemet  | ||||||
|  * @param e pointer to element (uint8_t*) |  * @param e pointer to element (uint8_t*) | ||||||
| @ -540,7 +549,7 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len) | |||||||
| #define cw_get_elem_len(e) cw_get_word(e+2) | #define cw_get_elem_len(e) cw_get_word(e+2) | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Get a pinter to the data of a CAPWAP message element  |  * Get a pointer to the data of a CAPWAP message element  | ||||||
|  * @param e pointer to message element  |  * @param e pointer to message element  | ||||||
|  * @return pointer to data |  * @return pointer to data | ||||||
|  */ |  */ | ||||||
| @ -688,4 +697,25 @@ extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,s | |||||||
| #define cwmsg_addelem_radio_operational_state(cwmsg,ri) \ | #define cwmsg_addelem_radio_operational_state(cwmsg,ri) \ | ||||||
| 	(cwmsg)->pos+=cw_addelem_radio_operational_state((cwmsg)->msgelems+(cwmsg)->pos,ri) | 	(cwmsg)->pos+=cw_addelem_radio_operational_state((cwmsg)->msgelems+(cwmsg)->pos,ri) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Message to text stuff */ | ||||||
|  |  | ||||||
|  | struct cw_strlist {  | ||||||
|  | 	uint32_t id; | ||||||
|  | 	const char * str; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | extern const char * cw_strlist_get_str(struct cw_strlist *s,int id); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | extern struct cw_strlist capwap_msg_strings[]; | ||||||
|  | extern struct cw_strlist capwap_state_strings[]; | ||||||
|  |  | ||||||
|  | #define cw_strmsg(id) cw_strlist_get_str(capwap_msg_strings,id) | ||||||
|  | #define cw_strstate(id) cw_strlist_get_str(capwap_state_strings,id) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -33,12 +33,17 @@ | |||||||
|  |  | ||||||
| #include "cw_action.h" | #include "cw_action.h" | ||||||
|  |  | ||||||
|  | #include "itemstore.h" | ||||||
|  |  | ||||||
| struct conn { | struct conn { | ||||||
| 	int sock; | 	int sock; | ||||||
| 	struct sockaddr_storage addr; | 	struct sockaddr_storage addr; | ||||||
| 	int recv_timeout; | 	int recv_timeout; | ||||||
|  |  | ||||||
| 	cw_actionlist_t msgtr; | 	cw_itemstore_t itemstore; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	struct avltree *msgtr; | ||||||
|  |  | ||||||
| 	uint8_t capwap_state; | 	uint8_t capwap_state; | ||||||
|  |  | ||||||
| @ -145,8 +150,10 @@ struct conn * conn_create_noq(int sock, struct sockaddr * addr); | |||||||
|  |  | ||||||
|  |  | ||||||
| extern int conn_send_cwmsg(struct conn *conn, struct cwmsg *cwmsg); | extern int conn_send_cwmsg(struct conn *conn, struct cwmsg *cwmsg); | ||||||
| extern void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int(*cb)(void*,struct cwrmsg*),void *cbarg); | extern void conn_process_packet(struct conn *conn, uint8_t * packet, int len, | ||||||
| extern struct cwrmsg * conn_get_message(struct conn * conn); | 				int (*cb) (void *, uint8_t *,int len), void *cbarg); | ||||||
|  |  | ||||||
|  | extern uint8_t *conn_get_message(struct conn *conn); | ||||||
|  |  | ||||||
| extern int conn_send_packet(struct conn *conn, const uint8_t * buffer, int len); | extern int conn_send_packet(struct conn *conn, const uint8_t * buffer, int len); | ||||||
| extern void conn_destroy(struct conn *conn); | extern void conn_destroy(struct conn *conn); | ||||||
| @ -191,7 +198,8 @@ struct image_identifier; | |||||||
| struct cwimage_data; | struct cwimage_data; | ||||||
|  |  | ||||||
| extern void conn_prepare_request(struct conn *conn, int type); | extern void conn_prepare_request(struct conn *conn, int type); | ||||||
| extern int conn_prepare_image_data_request(struct conn * conn, struct cwimage_data *, struct image_identifier *id ); | extern int conn_prepare_image_data_request(struct conn *conn, struct cwimage_data *, | ||||||
|  | 					   struct image_identifier *id); | ||||||
| extern void conn_detect_capwap(struct conn *conn, struct wtpinfo *wtpinfo); | extern void conn_detect_capwap(struct conn *conn, struct wtpinfo *wtpinfo); | ||||||
| struct cwrmsg *conn_send_request(struct conn *conn); | 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_message(struct conn *conn, time_t timer); | ||||||
| @ -205,4 +213,3 @@ void conn_init(struct conn * conn); | |||||||
|  |  | ||||||
|  |  | ||||||
| #endif				/* __CONLIST_H */ | #endif				/* __CONLIST_H */ | ||||||
|  |  | ||||||
|  | |||||||
| @ -16,25 +16,37 @@ struct args { | |||||||
| 	struct cwrmsg *cwrmsg; | 	struct cwrmsg *cwrmsg; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int pmessage(void *p, struct cwrmsg *cwrmsg) | static int message_cb(void *p, uint8_t *rawmsg, int len) | ||||||
| { | { | ||||||
| 	struct args *args = (struct args *) p; | 	struct args *args = (struct args *) p; | ||||||
| 	struct conn *conn = args->conn; | 	struct conn *conn = args->conn; | ||||||
|  | 	memcpy(conn->cwrmsg_buffer, rawmsg, len); | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  | ||||||
| 	memcpy(&conn->cwrmsg, cwrmsg, sizeof(struct cwrmsg)); | 	memcpy(&conn->cwrmsg, cwrmsg, sizeof(struct cwrmsg)); | ||||||
| 	memcpy(conn->cwrmsg_buffer, cwrmsg->msgelems, |  | ||||||
| 	       cwrmsg->msgelems_len); |  | ||||||
| 	conn->cwrmsg.msgelems = conn->cwrmsg_buffer; | 	conn->cwrmsg.msgelems = conn->cwrmsg_buffer; | ||||||
|  | */ | ||||||
| 	args->cwrmsg = &conn->cwrmsg; | 	args->cwrmsg = &conn->cwrmsg; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void conn_msg_processor(struct conn *conn) | ||||||
|  | { | ||||||
|  |         uint8_t buf[2024]; | ||||||
|  |         int len = 2024; | ||||||
|  |  | ||||||
|  |         int n = conn->read(conn, buf, len); | ||||||
|  |         if (n > 0) | ||||||
|  |                 conn_process_packet(conn, buf, n, cw_process_msg, conn); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| struct cwrmsg *conn_get_message(struct conn *conn) |  | ||||||
|  |  | ||||||
|  | uint8_t *conn_get_message(struct conn *conn) | ||||||
| { | { | ||||||
| 	struct args args; | 	struct args args; | ||||||
| 	args.cwrmsg = 0; | 	args.cwrmsg = 0; | ||||||
| @ -44,18 +56,20 @@ struct cwrmsg *conn_get_message(struct conn *conn) | |||||||
|  |  | ||||||
| 	int n = conn->read(conn, buf, len); | 	int n = conn->read(conn, buf, len); | ||||||
| 	if (n > 0) | 	if (n > 0) | ||||||
| 		conn_process_packet(conn, buf, n, pmessage, &args); | 		conn_process_packet(conn, buf, n, message_cb, &args); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (args.cwrmsg) { | 	if (args.cwrmsg) { | ||||||
|  | 		cw_dbg(DBG_MSG,"Message recieved from %s",sock_addr2str(&conn->addr)); | ||||||
|  | /* | ||||||
| 		cw_dbg(DBG_MSG, | 		cw_dbg(DBG_MSG, | ||||||
| 		       "Received message from %s, type=%d - %s, seq=%d", | 		       "Received message from %s, type=%d - %s, seq=%d", | ||||||
| 		       sock_addr2str(&conn->addr), args.cwrmsg->type, | 		       sock_addr2str(&conn->addr), args.cwrmsg->type, | ||||||
| 		       cw_msgtostr(args.cwrmsg->type), | 		       cw_msgtostr(args.cwrmsg->type), | ||||||
| 		       args.cwrmsg->seqnum); | 		       args.cwrmsg->seqnum); | ||||||
|  |  | ||||||
|  | */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return args.cwrmsg; | 	return conn->cwrmsg_buffer; | ||||||
| } | } | ||||||
|  | |||||||
| @ -34,11 +34,11 @@ struct cwrmsg * conn_get_response(struct conn * conn) | |||||||
| 			if (conn->dtls_error) | 			if (conn->dtls_error) | ||||||
| 	                        return 0; | 	                        return 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); | 		conn_send_cwmsg(conn,&conn->req_msg); | ||||||
|  |  | ||||||
|         } |         } | ||||||
| 	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; | 	return 0; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -74,31 +74,38 @@ static int cwrmsg_init_ctrlhdr(struct conn * conn, struct cwrmsg * cwrmsg, uint8 | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static int process_message(struct conn * conn,struct cwrmsg *cwrmsg,int (*cb)(void*,struct cwrmsg *),void *cbarg) | static int process_message(struct conn * conn,uint8_t *rawmsg,int rawlen,int (*cb)(void*,uint8_t *,int),void *cbarg) | ||||||
| { | { | ||||||
| 	if (!(cwrmsg->type & 0x1)) { | 	uint8_t *msgptr = rawmsg+cw_get_hdr_msg_offset(rawmsg); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	uint32_t type = cw_get_msg_type(msgptr); | ||||||
|  |  | ||||||
|  | 	if (!(type & 0x1)) { | ||||||
| 		/* It's a response  message, no further examination required. */ | 		/* It's a response  message, no further examination required. */ | ||||||
| 		cb(cbarg,cwrmsg); | 		cb(cbarg,rawmsg,rawlen); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* It's a request message, check if seqnum is right and if | 	/* It's a request message, check if seqnum is right and if | ||||||
| 	 * we have already sent a response message*/ | 	 * we have already sent a response message*/ | ||||||
|  |  | ||||||
|  | 	uint8_t seqnum = cw_get_msg_seqnum(msgptr); | ||||||
|  |  | ||||||
| 	int s1=conn->last_seqnum_received; | 	int s1=conn->last_seqnum_received; | ||||||
| 	int s2=cwrmsg->seqnum; | 	int s2=seqnum; | ||||||
| 	int sd=s2-s1; | 	int sd=s2-s1; | ||||||
|  |  | ||||||
| 	if ((sd>0 && sd<128) || (sd<0 && sd<-128) || s1<0){ | 	if ((sd>0 && sd<128) || (sd<0 && sd<-128) || s1<0){ | ||||||
| 		/* seqnum is ok, normal message processing */ | 		/* seqnum is ok, normal message processing */ | ||||||
| 		conn->last_seqnum_received=cwrmsg->seqnum; | 		conn->last_seqnum_received=seqnum; | ||||||
| 		cb(cbarg,cwrmsg); | 		cb(cbarg,rawmsg,rawlen); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (sd != 0) | 	if (sd != 0) | ||||||
| 	{ | 	{ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR, | 		cw_dbg(DBG_MSG_ERR, | ||||||
| 			"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d", | 			"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d", | ||||||
| 			sock_addr2str(&conn->addr),s2,s1); | 			sock_addr2str(&conn->addr),s2,s1); | ||||||
|  |  | ||||||
| @ -108,15 +115,15 @@ static int process_message(struct conn * conn,struct cwrmsg *cwrmsg,int (*cb)(vo | |||||||
| 	/* the received request message was retransmitte by our peer, | 	/* the received request message was retransmitte by our peer, | ||||||
| 	 * let's retransmit our response message if we have one*/ | 	 * let's retransmit our response message if we have one*/ | ||||||
|  |  | ||||||
| 	cw_dbg(DBG_CW_MSG_ERR,"Retransmitted request message from %s detected, seqnum=%d, type=%d", | 	cw_dbg(DBG_MSG_ERR,"Retransmitted request message from %s detected, seqnum=%d, type=%d", | ||||||
| 		sock_addr2str(&conn->addr),s2,cwrmsg->type); | 		sock_addr2str(&conn->addr),s2,type); | ||||||
|  |  | ||||||
| 	if (conn->resp_msg.type-1 != cwrmsg->type ){ | 	if (conn->resp_msg.type-1 != type ){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"No cached response for retransmission, request seqnum=%d,in cache=%d",s2,conn->resp_msg.type ); | 		cw_dbg(DBG_MSG_ERR,"No cached response for retransmission, request seqnum=%d,in cache=%d",s2,conn->resp_msg.type ); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cw_dbg(DBG_CW_MSG_ERR,"Retransmitting response message to %s, seqnum=%d", | 	cw_dbg(DBG_MSG_ERR,"Retransmitting response message to %s, seqnum=%d", | ||||||
| 		sock_addr2str(&conn->addr),s2); | 		sock_addr2str(&conn->addr),s2); | ||||||
| 	conn_send_cwmsg(conn,&conn->resp_msg); | 	conn_send_cwmsg(conn,&conn->resp_msg); | ||||||
| 	return 1;	 | 	return 1;	 | ||||||
| @ -154,72 +161,68 @@ static void cw_dbg_packet(struct conn * conn, uint8_t * packet, int len) | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(void*,struct cwrmsg*),void *cbarg) | void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(void*,uint8_t *,int),void *cbarg) | ||||||
| { | { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (len<8){ | 	if (len<8){ | ||||||
| 		/* packet too short */ | 		/* packet too short */ | ||||||
| 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, packet too short, len=%d",sock_addr2str(&conn->addr),len); | 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, packet too short, len=%d",sock_addr2str(&conn->addr),len); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	uint32_t val = ntohl(*((uint32_t*)packet)); | 	int preamble = cw_get_hdr_preamble(packet); | ||||||
|  |  | ||||||
| 	int preamble = val >> 24; |  | ||||||
| 	if ( (preamble & 0xf0) != CW_VERSION){ | 	if ( (preamble & 0xf0) != CW_VERSION){ | ||||||
| 		/* wrong version */ | 		/* wrong version */ | ||||||
| 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, wrong version, version=%d",sock_addr2str(&conn->addr),(preamble&0xf0)>>8); | 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, wrong version, version=%d",sock_addr2str(&conn->addr),(preamble&0xf0)>>8); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (preamble & 0xf ) { | 	if (preamble & 0xf ) { | ||||||
| 		/* decode dtls */ | 		/* decode dtls */ | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* log this packet */ | ||||||
| 	cw_dbg_packet(conn,packet,len); | 	cw_dbg_packet(conn,packet,len); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	int hlen = 4*((val >> 19) & 0x1f); | 	int offs = cw_get_hdr_msg_offset(packet);  | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
| 	int payloadlen = len - hlen; | 	int payloadlen = len - offs; | ||||||
| 	if (payloadlen<0){ | 	if (payloadlen<0){ | ||||||
| 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, hlen greater than len, hlen=%d",sock_addr2str(&conn->addr),hlen); | 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, header length greater than len, hlen=%d",sock_addr2str(&conn->addr),offs); | ||||||
| 		/* EINVAL */ | 		/* EINVAL */ | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | /* | ||||||
| 	struct cwrmsg cwrmsg; | 	struct cwrmsg cwrmsg; | ||||||
| 	cwrmsg.wbid=(val>>9) & 0x1f; | 	cwrmsg.wbid=(val>>9) & 0x1f; | ||||||
| 	cwrmsg.rid=(val>>14) & 0x1f; | 	cwrmsg.rid=(val>>14) & 0x1f; | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet)); | ||||||
|  |  | ||||||
|  | 	/* Check Radio MAC if preset */ | ||||||
|  | 	if (cw_get_hdr_flag_m(packet)){ | ||||||
| 		 | 		 | ||||||
| 	if (val & CWTH_FLAGS_M){ | 		if (cw_get_hdr_rmac_len(packet)+8>offs){ | ||||||
| 		 |  | ||||||
| 		if (*(packet+8)+8>hlen){ |  | ||||||
| 			/* wrong rmac size */ | 			/* wrong rmac size */ | ||||||
| 			cw_dbg(DBG_CW_PKT_ERR,"Discarding packet, wrong rmac size, size=%d",*(packet+8)); | 			cw_dbg(DBG_CW_PKT_ERR,"Discarding packet, wrong R-MAC size, size=%d",*(packet+8)); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		memcpy(cwrmsg.rmac, packet+8,8); | //		memcpy(cwrmsg.rmac, packet+8,8); | ||||||
| 	} |  | ||||||
| 	else{ |  | ||||||
| 		cwrmsg.rmac[0]=0; |  | ||||||
| 	} | 	} | ||||||
|  | //	else{ | ||||||
|  | //		cwrmsg.rmac[0]=0; | ||||||
|  | //	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (val & CWTH_FLAGS_F){	/* fragmented */ | 	if (cw_get_hdr_flag_f(packet)){	/* fragmented */ | ||||||
| 		uint8_t * f; | 		uint8_t * f; | ||||||
| 		f = fragman_add(conn->fragman, packet,hlen,payloadlen); | 		f = fragman_add(conn->fragman, packet,offs,payloadlen); | ||||||
| 		if (f==NULL) | 		if (f==NULL) | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
| @ -229,12 +232,17 @@ void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)( | |||||||
| 		extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); | 		extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); | ||||||
| 		cw_process_msg(conn,f+4,*(uint32_t*)f); | 		cw_process_msg(conn,f+4,*(uint32_t*)f); | ||||||
|  |  | ||||||
|  | printf("Received a fragmented packetm should process it"); | ||||||
|  | exit(0); | ||||||
|  |  | ||||||
|  | /* | ||||||
| 		if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,f+4,*(uint32_t*)f)){ | 		if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,f+4,*(uint32_t*)f)){ | ||||||
| 			free(f); | 			free(f); | ||||||
| 			return; | 			return; | ||||||
| 		}; | 		}; | ||||||
| 		process_message(conn,&cwrmsg,cb,cbarg);  | */ | ||||||
|  | 		process_message(conn,f+4,*(uint32_t*)f,cb,cbarg);  | ||||||
|  |  | ||||||
| 		free (f); | 		free (f); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| @ -243,13 +251,14 @@ extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len); | |||||||
| cw_process_msg(conn,packet,len); | cw_process_msg(conn,packet,len); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,packet+hlen,len-hlen) ){ | 	//if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,packet+hlen,len-hlen) ){ | ||||||
| 	//	cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, len=%d (too short)",sock_addr2str(&conn->addr)); | 	//	cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, len=%d (too short)",sock_addr2str(&conn->addr)); | ||||||
| 		return; | 	//	return; | ||||||
| 	} | 	//} | ||||||
|  |  | ||||||
|  | printf("Next big thing\n"); | ||||||
| 	process_message(conn,&cwrmsg,cb,cbarg);  | //msg_4*((val >> 19) & 0x1f); | ||||||
|  | 	process_message(conn,packet,len,cb,cbarg);  | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ struct cwrmsg * conn_send_request(struct conn * conn) | |||||||
|  |  | ||||||
|                 time_t r_timer = cw_timer_start(conn->retransmit_interval); |                 time_t r_timer = cw_timer_start(conn->retransmit_interval); | ||||||
| 		if (i!=0) | 		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); | 		conn_send_cwmsg(conn,&conn->req_msg); | ||||||
| 		cwrmsg = conn_wait_for_message(conn,r_timer); | 		cwrmsg = conn_wait_for_message(conn,r_timer); | ||||||
| @ -55,7 +55,7 @@ struct cwrmsg * conn_send_request(struct conn * conn) | |||||||
|                                  |                                  | ||||||
| 		} | 		} | ||||||
|         } |         } | ||||||
|         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; |         return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -22,13 +22,20 @@ static inline int cw_action_cmp(const void *elem1,const void *elem2) | |||||||
| 	if (r!=0) | 	if (r!=0) | ||||||
| 		return r; | 		return r; | ||||||
|  |  | ||||||
|  | 	r = e1->vendor_id - e2->vendor_id; | ||||||
|  | 	if (r!=0) | ||||||
|  | 		return r; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
| static void cw_action_del(void*d) | static void cw_action_del(void*d) | ||||||
| { | { | ||||||
| 	free(d); | 	free(d); | ||||||
| } | } | ||||||
|  | */ | ||||||
|  |  | ||||||
| cw_action_t * cw_actionlist_add(cw_actionlist_t t, struct cw_action * a) | cw_action_t * cw_actionlist_add(cw_actionlist_t t, struct cw_action * a) | ||||||
| { | { | ||||||
| @ -49,15 +56,15 @@ struct cw_action * cw_actionlist_get(cw_actionlist_t t,struct cw_action *a) | |||||||
|  |  | ||||||
| cw_actionlist_t cw_actionlist_create() | cw_actionlist_t cw_actionlist_create() | ||||||
| { | { | ||||||
| 	return avltree_create(cw_action_cmp,cw_action_del); | 	return avltree_create(cw_action_cmp,free); //cw_action_del); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int cw_register_actions(cw_actionlist_t t,cw_action_t * actions) | int cw_register_actions(cw_actionlist_t t,cw_action_t * actions) | ||||||
| { | { | ||||||
| 	while(actions->capwap_state){ | 	while(actions->capwap_state){ | ||||||
| 		cw_action_t *a = actions; | //		cw_action_t *a = actions; | ||||||
| 		printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id); | //		printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id); | ||||||
| 		cw_action_t * rc = cw_actionlist_add(t,actions); | 		cw_action_t * rc = cw_actionlist_add(t,actions); | ||||||
| 		if (rc==0)  | 		if (rc==0)  | ||||||
| 			return 0;	 | 			return 0;	 | ||||||
|  | |||||||
| @ -6,16 +6,22 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  |  | ||||||
| #include "avltree.h" | #include "avltree.h" | ||||||
|  | #include "conn.h" | ||||||
|  |  | ||||||
| struct cw_action{ | struct cw_action{ | ||||||
|  | 	uint32_t vendor_id; | ||||||
|  | 	uint8_t proto; | ||||||
| 	uint8_t capwap_state; | 	uint8_t capwap_state; | ||||||
| 	uint32_t msg_id; | 	uint32_t msg_id; | ||||||
| 	uint16_t elem_id; | 	uint16_t elem_id; | ||||||
| 	uint32_t vendor_id; |  | ||||||
| 	uint16_t vendor_elem_id; |  | ||||||
|  |  | ||||||
| 	int (*start)(struct conn *conn,struct cw_action *a,uint8_t*data,int len); | 	int (*start)(struct conn *conn,struct cw_action *a,uint8_t*data,int len); | ||||||
| 	int (*end)(struct conn *conn,struct cw_action *a,uint8_t*data,int len); | 	int (*end)(struct conn *conn,struct cw_action *a,uint8_t*elem,int len); | ||||||
|  |  | ||||||
|  | 	uint16_t min_len; | ||||||
|  | 	uint16_t max_len; | ||||||
|  |  | ||||||
|  | 	uint8_t capwap_state_next; | ||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
| 	const char *name; | 	const char *name; | ||||||
|  | |||||||
| @ -34,7 +34,6 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #define DBG_MSG				0x00000001	/* Parsed CAPWAP/LWAPP messages */ | #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			0x00000002	/* Parsed CAPWAP/LWAPP message elements */ | ||||||
| #define DBG_ELEM_DMP			0x00000004	/* Dump CAPWAP message elements */ | #define DBG_ELEM_DMP			0x00000004	/* Dump CAPWAP message elements */ | ||||||
| @ -47,8 +46,9 @@ | |||||||
| #define DBG_CW_PKT_DMP			0x00000080	/* Dump packts */ | #define DBG_CW_PKT_DMP			0x00000080	/* Dump packts */ | ||||||
| #define DBG_CW_PKT_DTL			0x00000100	 | #define DBG_CW_PKT_DTL			0x00000100	 | ||||||
| #define DBG_CW_PKT_ERR			0x00000200 | #define DBG_CW_PKT_ERR			0x00000200 | ||||||
| #define DBG_CW_MSG_ERR			0x00000400	/* Errors in CAPWAP messages */ | #define DBG_MSG_ERR			0x00000400	/* Errors in CAPWAP messages */ | ||||||
| #define DBG_CW_IMG_DTL			0x00000800	/* Detail about image transfer */ | #define DBG_CW_IMG_DTL			0x00000800	/* Detail about image transfer */ | ||||||
|  | #define DBG_ELEM_ERR			0x00001000 | ||||||
|  |  | ||||||
| /* driver specific debugs */ | /* driver specific debugs */ | ||||||
| #define DBG_DRV				0x00010000 | #define DBG_DRV				0x00010000 | ||||||
| @ -69,7 +69,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| #define DBG_DETAIL_ALL			0xffffffff | #define DBG_DETAIL_ALL			0xffffffff | ||||||
| #define DBG_ERR				(DBG_CW_MSG_ERR | DBG_CW_PKT_ERR) | #define DBG_ERR				(DBG_MSG_ERR | DBG_CW_PKT_ERR) | ||||||
|  |  | ||||||
| /**@}*/ | /**@}*/ | ||||||
|  |  | ||||||
|  | |||||||
| @ -35,8 +35,9 @@ struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = { | |||||||
| 	{"pkt",(DBG_CW_PKT_IN | DBG_CW_PKT_OUT)}, | 	{"pkt",(DBG_CW_PKT_IN | DBG_CW_PKT_OUT)}, | ||||||
| 	{"pkt_dmp",DBG_CW_PKT_DMP}, | 	{"pkt_dmp",DBG_CW_PKT_DMP}, | ||||||
| 	{"pkt_err",DBG_CW_PKT_ERR}, | 	{"pkt_err",DBG_CW_PKT_ERR}, | ||||||
| 	{"msg_err",DBG_CW_MSG_ERR}, | 	{"msg_err",DBG_MSG_ERR}, | ||||||
| 	{"img_dtl",DBG_CW_IMG_DTL}, | 	{"img_dtl",DBG_CW_IMG_DTL}, | ||||||
|  | 	{"elem_err",DBG_ELEM_ERR}, | ||||||
|  |  | ||||||
| 	{"dtls",DBG_DTLS}, | 	{"dtls",DBG_DTLS}, | ||||||
| 	{"dtls_dietail",DBG_DTLS_DETAIL}, | 	{"dtls_dietail",DBG_DTLS_DETAIL}, | ||||||
|  | |||||||
| @ -45,9 +45,9 @@ const char * cw_msgtostr(int type) | |||||||
| 		case CW_MSG_CONFIGURATION_UPDATE_RESPONSE: | 		case CW_MSG_CONFIGURATION_UPDATE_RESPONSE: | ||||||
| 			return "configuration update response"; | 			return "configuration update response"; | ||||||
| 			 | 			 | ||||||
| 		case CWMSG_WTP_EVENT_REQUEST: | 		case CW_MSG_WTP_EVENT_REQUEST: | ||||||
| 			return "wtp event request"; | 			return "wtp event request"; | ||||||
| 		case CWMSG_WTP_EVENT_RESPONSE: | 		case CW_MSG_WTP_EVENT_RESPONSE: | ||||||
| 			return "wtp event response"; | 			return "wtp event response"; | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -83,9 +83,9 @@ const char * cw_msgtostr(int type) | |||||||
|            Reset Request                       17 |            Reset Request                       17 | ||||||
|            Reset Response                      18 |            Reset Response                      18 | ||||||
| */	    | */	    | ||||||
| 		case CWMSG_PRIMARY_DISCOVERY_REQUEST: | 		case CW_MSG_PRIMARY_DISCOVERY_REQUEST: | ||||||
| 			return "primary discovery request"; | 			return "primary discovery request"; | ||||||
| 		case CWMSG_PRIMARY_DISCOVERY_RESPONSE: | 		case CW_MSG_PRIMARY_DISCOVERY_RESPONSE: | ||||||
| 			return "primary discovery response"; | 			return "primary discovery response"; | ||||||
|  |  | ||||||
| /*           Data Transfer Request               21 | /*           Data Transfer Request               21 | ||||||
|  | |||||||
| @ -4,25 +4,61 @@ | |||||||
|  |  | ||||||
| #include "conn.h" | #include "conn.h" | ||||||
| #include "capwap.h" | #include "capwap.h" | ||||||
|  | #include "sock.h" | ||||||
| #include "cw_action.h" | #include "cw_action.h" | ||||||
|  | #include "cw_log.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | ||||||
| { | { | ||||||
| 	struct cw_action as,*af; | 	struct cw_action as,*af; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg); | 	uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg); | ||||||
|  |  | ||||||
|  | 	int elems_len = cw_get_msg_elems_len(msg_ptr); | ||||||
|  | /* | ||||||
|  | 	if (8+elems_len != len){ | ||||||
|  | 		cw_dbg(DBG_MSG_ERR,"Discarding message from %s, msgelems len=%d, data len=%d, (strict capwap) ", | ||||||
|  | 			sock_addr2str(&conn->addr),elems_len,len-8); | ||||||
|  |  | ||||||
|  | 		if (conn_is_strict_capwap(conn)){ | ||||||
|  | 			cw_dbg(DBG_MSG_ERR,"Discarding message from %s, msgelems len=%d, data len=%d, (strict capwap) ", | ||||||
|  | 				sock_addr2str(&conn->addr),elems_len,len-8); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 		if (8+elems_len < len){ | ||||||
|  | 			cw_dbg(DBG_CW_RFC,"Packet from from %s has %d bytes extra data.", | ||||||
|  | 				sock_addr2str(&conn->addr),len-8-elems_len); | ||||||
|  | 			elems_len=len-8; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (8+elems_len > len){ | ||||||
|  | 			cw_dbg(DBG_CW_RFC,"Packet from from %s hass msgelems len of %d bytes but has only %d bytes of data, truncating.", | ||||||
|  | 				sock_addr2str(&conn->addr),elems_len,len-8); | ||||||
|  | 		} | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | 	 | ||||||
| 	/* prepare struct for search operation */ | 	/* prepare struct for search operation */ | ||||||
| 	as.elem_id=-1; | 	as.elem_id=-1; | ||||||
| 	as.capwap_state=conn->capwap_state; | 	as.capwap_state=conn->capwap_state; | ||||||
| 	as.msg_id = cw_get_msg_id(msg_ptr); | 	as.msg_id = cw_get_msg_id(msg_ptr); | ||||||
|  | 	as.vendor_id=0; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* Search for state/message combination */ | 	/* Search for state/message combination */ | ||||||
| 	af = cw_actionlist_get(conn->msgtr,&as); | 	af = cw_actionlist_get(conn->msgtr,&as); | ||||||
|  |  | ||||||
|  | 	/* Check if message is comes in right state */ | ||||||
| 	if ( !af ){ | 	if ( !af ){ | ||||||
| 		printf("Error - Message not found: %d\n",as.msg_id); | 		cw_dbg(DBG_MSG_ERR,"Message type %d (%s) not allowed in %s State.", | ||||||
|  | 			as.msg_id,cw_strmsg(as.msg_id),cw_strstate(as.capwap_state)); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -31,7 +67,6 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | |||||||
| 		af->start(conn,af,rawmsg,len); | 		af->start(conn,af,rawmsg,len); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	int elems_len = cw_get_msg_elems_len(msg_ptr); |  | ||||||
| 	uint8_t * elems_ptr = cw_get_msg_elems_ptr(msg_ptr); | 	uint8_t * elems_ptr = cw_get_msg_elems_ptr(msg_ptr); | ||||||
|  |  | ||||||
| 	 | 	 | ||||||
| @ -43,6 +78,8 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | |||||||
| 		as.elem_id = cw_get_elem_id(elem); | 		as.elem_id = cw_get_elem_id(elem); | ||||||
| 		int elem_len = cw_get_elem_len(elem); | 		int elem_len = cw_get_elem_len(elem); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		af = cw_actionlist_get(conn->msgtr,&as); | 		af = cw_actionlist_get(conn->msgtr,&as); | ||||||
| 		 | 		 | ||||||
| 		if (!af) { | 		if (!af) { | ||||||
| @ -51,6 +88,9 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		printf("Elem OK: %d, %d\n",as.elem_id,elem_len); | 		printf("Elem OK: %d, %d\n",as.elem_id,elem_len); | ||||||
|  | 		if (af->start) { | ||||||
|  | 			af->start(conn,af,cw_get_elem_data(elem),elem_len); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ int cw_readelem_image_identifier(struct cwimage_data *data, int type,uint8_t *ms | |||||||
| 	data->vendor_id = ntohl(*((uint32_t*)msgelem)); | 	data->vendor_id = ntohl(*((uint32_t*)msgelem)); | ||||||
|  |  | ||||||
| 	if (len >= 1024) { | 	if (len >= 1024) { | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Image identifier too long (>1024), truncating"); | 		cw_dbg(DBG_MSG_ERR,"Image identifier too long (>1024), truncating"); | ||||||
| 		len = 1024; | 		len = 1024; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ int cw_readelem_80211_wtp_radio_info(void *dst,int type,uint8_t *msgelem, int le | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (len!=5){ | 	if (len!=5){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Discarding msgelem 80211_WTP_RADIO_INFO, wrong size, len=%d\n",len); | 		cw_dbg(DBG_MSG_ERR,"Discarding msgelem 80211_WTP_RADIO_INFO, wrong size, len=%d\n",len); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ int cw_readelem_ac_name(uint8_t **dst, int type,uint8_t *msgelem, int len) | |||||||
|  |  | ||||||
| 	if (len > 512 ) { | 	if (len > 512 ) { | ||||||
| 		cw_dbg(DBG_CW_RFC,"AC name too long, max. 512 bytes allowed (RFC 5415)"); | 		cw_dbg(DBG_CW_RFC,"AC name too long, max. 512 bytes allowed (RFC 5415)"); | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"AC name truncated to 512 bytes"); | 		cw_dbg(DBG_MSG_ERR,"AC name truncated to 512 bytes"); | ||||||
| 		len = 512; | 		len = 512; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ int lw_readelem_wtp_board_data(struct wtpinfo *wtpinfo, int type, uint8_t *msgel | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if ( len != 46 ) { | 	if ( len != 46 ) { | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"LWAPP msg size wrong. (WTP BOARD DATA) must be 46"); | 		cw_dbg(DBG_MSG_ERR,"LWAPP msg size wrong. (WTP BOARD DATA) must be 46"); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -42,7 +42,7 @@ int lw_readelem_wtp_name(uint8_t ** dst, int type, uint8_t * msgelem, int len) | |||||||
|  |  | ||||||
| 	 | 	 | ||||||
| 	if (len>254){ | 	if (len>254){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Truncating WTP_NAME msgelem to 254, wrong size, type=%d,len=%d",type,len); | 		cw_dbg(DBG_MSG_ERR,"Truncating WTP_NAME msgelem to 254, wrong size, type=%d,len=%d",type,len); | ||||||
| 		len=254; | 		len=254; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ int wtpinfo_readelem_discovery_type(struct wtpinfo * wtpinfo, int type, uint8_t | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (len!=1){ | 	if (len!=1){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len); | 		cw_dbg(DBG_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -66,7 +66,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, | |||||||
| 	do { | 	do { | ||||||
| 		if (i+8>len) | 		if (i+8>len) | ||||||
| 		{ | 		{ | ||||||
| 			cw_dbg(DBG_CW_MSG_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len); | 			cw_dbg(DBG_MSG_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -78,7 +78,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, | |||||||
| 		i+=8; | 		i+=8; | ||||||
|  |  | ||||||
| 		if (sublen+i>len){ | 		if (sublen+i>len){ | ||||||
| 			cw_dbg(DBG_CW_MSG_ERR,"WTP descriptor subelement too long, length = %d",sublen); | 			cw_dbg(DBG_MSG_ERR,"WTP descriptor subelement too long, length = %d",sublen); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -102,7 +102,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, | |||||||
| 				wtpinfo->bootloader_version_len=sublen; | 				wtpinfo->bootloader_version_len=sublen; | ||||||
| 				break; | 				break; | ||||||
| 			default: | 			default: | ||||||
| 				cw_dbg(DBG_CW_MSG_ERR,"Unknown WTP descriptor subelement, type = %d",subtype); | 				cw_dbg(DBG_MSG_ERR,"Unknown WTP descriptor subelement, type = %d",subtype); | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
| 		i+=sublen; | 		i+=sublen; | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ int wtpinfo_readelem_wtp_frame_tunnel_mode(struct wtpinfo * wtpinfo, int type, u | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (len!=1){ | 	if (len!=1){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len); | 		cw_dbg(DBG_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 	wtpinfo->frame_tunnel_mode=*msgelem; | 	wtpinfo->frame_tunnel_mode=*msgelem; | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ int wtpinfo_readelem_wtp_mac_type(struct wtpinfo * wtpinfo, int type, uint8_t * | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (len!=1){ | 	if (len!=1){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Discarding WTP_MAC_TYPE msgelem, wrong size, type=%d,len=%d",type,len); | 		cw_dbg(DBG_MSG_ERR,"Discarding WTP_MAC_TYPE msgelem, wrong size, type=%d,len=%d",type,len); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ int wtpinfo_readelem_wtp_name(struct wtpinfo * wtpinfo, int type, uint8_t * msge | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (len>512){ | 	if (len>512){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Truncating WTP_NAME msgelem to 512, wrong size, type=%d,len=%d",type,len); | 		cw_dbg(DBG_MSG_ERR,"Truncating WTP_NAME msgelem to 512, wrong size, type=%d,len=%d",type,len); | ||||||
| 		len=512; | 		len=512; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ int wtpinfo_readelem_wtp_radio_info(struct wtpinfo * wtpinfo,int type,uint8_t *m | |||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (len!=5){ | 	if (len!=5){ | ||||||
| 		cw_dbg(DBG_CW_MSG_ERR,"Discarding msgelem WTP_RADIO_INFO, wrong size, len=%d\n",len); | 		cw_dbg(DBG_MSG_ERR,"Discarding msgelem WTP_RADIO_INFO, wrong size, len=%d\n",len); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user