Digging deepter into VM concepts...
FossilOrigin-Name: ba6454642f17c0f87106cb6af12689457433d44ba1fe2dd1ef920dba7be2ef27
This commit is contained in:
		| @ -35,7 +35,8 @@ | ||||
| #include "socklist.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; | ||||
|  | ||||
| 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"); | ||||
|  | ||||
| 	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[])  | ||||
| @ -69,27 +120,38 @@ the_tree=t; | ||||
|  | ||||
|  | ||||
| cw_action_t discovery_actions[] = { | ||||
| { CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1,0,0, | ||||
|   dstart | ||||
| }, | ||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE}, | ||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA}, | ||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, | ||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE}, | ||||
| {CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE}, | ||||
| {0} | ||||
| { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1, | ||||
|   dstart,0 }, | ||||
|  | ||||
| { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE, | ||||
|   readelem_discovery_type,0 }, | ||||
|  | ||||
| { 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, | ||||
|   readelem_vendor_specific_payload,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_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,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}, | ||||
| {CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, | ||||
| {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,-1,0,0}, | ||||
| {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE}, | ||||
| {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA}, | ||||
| {0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR}, | ||||
| {0,0,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_MAC_TYPE}, | ||||
| {0} | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -356,15 +356,32 @@ static void wtpman_run_discovery(void *arg) | ||||
| 	struct wtpman * wtpman = (struct wtpman *)arg; | ||||
| 	struct cwrmsg * cwrmsg; | ||||
| 	 | ||||
| 	void conn_msg_processor(struct conn *conn); | ||||
|  | ||||
| 	time_t timer = cw_timer_start(10); | ||||
|  | ||||
| extern cw_actionlist_t the_tree; | ||||
| wtpman->conn->capwap_state=CW_STATE_DISCOVERY; | ||||
| 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); | ||||
|  | ||||
| 	if ( !cwrmsg  ) | ||||
| @ -415,8 +432,6 @@ wtpman->conn->msgtr=the_tree; | ||||
| */ | ||||
|  | ||||
| 	cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo); | ||||
|  | ||||
|  | ||||
| 	wtpman_remove(wtpman); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -160,7 +160,11 @@ CAPWAPOBJS= \ | ||||
| 	cw_readmsg_configuration_status_request.o \ | ||||
| 	cw_cisco_id_to_str.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 \ | ||||
|  | ||||
| @ -63,8 +63,10 @@ enum capwap_states { | ||||
| 	CW_STATE_NONE=0, | ||||
| 	CW_STATE_DISCOVERY, | ||||
| 	CW_STATE_JOIN, | ||||
| 	CW_STATE_CONFIGURE, | ||||
| 	CW_STATE_IMAGE, | ||||
| 	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_RESPONSE	8 | ||||
|  | ||||
| #define CWMSG_WTP_EVENT_REQUEST			9 | ||||
| #define CWMSG_WTP_EVENT_RESPONSE		10 | ||||
| #define CW_MSG_WTP_EVENT_REQUEST			9 | ||||
| #define CW_MSG_WTP_EVENT_RESPONSE		10 | ||||
|  | ||||
| #define CW_MSG_CHANGE_STATE_EVENT_REQUEST	11 | ||||
| #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_RESPONSE			18  | ||||
|  | ||||
| #define CWMSG_PRIMARY_DISCOVERY_REQUEST		19  | ||||
| #define CWMSG_PRIMARY_DISCOVERY_RESPONSE	20  | ||||
| #define CW_MSG_PRIMARY_DISCOVERY_REQUEST		19  | ||||
| #define CW_MSG_PRIMARY_DISCOVERY_RESPONSE	20  | ||||
|  | ||||
| /*           Data Transfer Request               21 | ||||
|            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_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_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_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  | ||||
|  * @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) | ||||
|  | ||||
| /** | ||||
|  * 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  | ||||
|  * @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) \ | ||||
| 	(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 | ||||
|  | ||||
| @ -33,20 +33,25 @@ | ||||
|  | ||||
| #include "cw_action.h" | ||||
|  | ||||
| struct conn{ | ||||
| #include "itemstore.h" | ||||
|  | ||||
| struct conn { | ||||
| 	int sock; | ||||
| 	struct sockaddr_storage addr; | ||||
| 	int recv_timeout; | ||||
|  | ||||
| 	cw_actionlist_t msgtr; | ||||
| 	cw_itemstore_t itemstore; | ||||
|  | ||||
|  | ||||
| 	struct avltree *msgtr; | ||||
|  | ||||
| 	uint8_t capwap_state; | ||||
|  | ||||
| 	FRAGMAN * fragman; | ||||
| //	void (* process_message)(void *,uint8_t *,uint8_t *, int); | ||||
| 	FRAGMAN *fragman; | ||||
| //      void (* process_message)(void *,uint8_t *,uint8_t *, int); | ||||
|  | ||||
| //	void (* process_message)(void *,struct cwrmsg *);  //uint8_t *,uint8_t *, int); | ||||
| //	void * pmsgarg; | ||||
| //      void (* process_message)(void *,struct cwrmsg *);  //uint8_t *,uint8_t *, int); | ||||
| //      void * pmsgarg; | ||||
|  | ||||
| 	int fragid; | ||||
|  | ||||
| @ -55,10 +60,10 @@ struct conn{ | ||||
| 	int last_seqnum_received; | ||||
| 	int last_message_id_received; | ||||
|  | ||||
| //	struct cwmsg * last_response; | ||||
| //	struct cwmsg swm; | ||||
| //	int last_response_seqnum; | ||||
| //	int last_response_rid; | ||||
| //      struct cwmsg * last_response; | ||||
| //      struct cwmsg swm; | ||||
| //      int last_response_seqnum; | ||||
| //      int last_response_rid; | ||||
|  | ||||
| 	struct cwrmsg cwrmsg; | ||||
| 	uint8_t cwrmsg_buffer[65536]; | ||||
| @ -75,36 +80,36 @@ struct conn{ | ||||
|  | ||||
| 	/* receive and send methods */ | ||||
|  | ||||
| 	int (*recv_packet)(struct conn  *, uint8_t *,int); | ||||
| 	int (*recv_packet_peek)(struct conn  *, uint8_t *,int); | ||||
| 	int (*send_packet)(struct conn *, const uint8_t *, int); | ||||
| 	int (*recv_packet) (struct conn *, uint8_t *, int); | ||||
| 	int (*recv_packet_peek) (struct conn *, uint8_t *, int); | ||||
| 	int (*send_packet) (struct conn *, const uint8_t *, int); | ||||
|  | ||||
| 	int (*read)(struct conn *, uint8_t*, int); | ||||
| 	int (*write)(struct conn *, const uint8_t*, int); | ||||
| 	int (*read) (struct conn *, uint8_t *, int); | ||||
| 	int (*write) (struct conn *, const uint8_t *, int); | ||||
|  | ||||
| 	/* optional packet queue */ | ||||
| 	uint8_t ** q;  | ||||
| 	uint8_t **q; | ||||
| 	int qsize; | ||||
| 	int qrpos; | ||||
| 	int qwpos; | ||||
| 	sem_t q_sem; | ||||
| 	uint8_t * cur_packet; | ||||
| 	uint8_t *cur_packet; | ||||
| 	int cur_packet_len; | ||||
| 	int cur_packet_pos; | ||||
|  | ||||
| 	/* dtls stuff */ | ||||
| 	int (*dtls_start)(struct conn*); | ||||
| 	int (*dtls_accept)(struct conn*); | ||||
| 	int (*dtls_start) (struct conn *); | ||||
| 	int (*dtls_accept) (struct conn *); | ||||
|  | ||||
| 	char * dtls_psk; | ||||
| 	char *dtls_psk; | ||||
| 	int dtls_psk_len; | ||||
|  | ||||
| 	char * dtls_cert_file; | ||||
| 	char * dtls_key_file; | ||||
| 	char * dtls_key_pass; | ||||
| 	char *dtls_cert_file; | ||||
| 	char *dtls_key_file; | ||||
| 	char *dtls_key_pass; | ||||
|  | ||||
| 	void * dtls_data; | ||||
| 	char * dtls_cipher; | ||||
| 	void *dtls_data; | ||||
| 	char *dtls_cipher; | ||||
| 	int dtls_error; | ||||
| 	uint8_t dtls_cookie[8]; | ||||
| 	int dtls_verify_peer; | ||||
| @ -122,7 +127,7 @@ struct conn{ | ||||
|  | ||||
|  | ||||
| 	/* used to link the conn obj with other objects */ | ||||
| 	void * data; | ||||
| 	void *data; | ||||
|  | ||||
| 	/* misc */ | ||||
| 	int capwap_mode; | ||||
| @ -130,8 +135,8 @@ struct conn{ | ||||
| 	int strict_capwap; | ||||
|  | ||||
|  | ||||
| 	int (*request_handler) (void*); | ||||
| 	void * request_handler_param; | ||||
| 	int (*request_handler) (void *); | ||||
| 	void *request_handler_param; | ||||
| }; | ||||
|  | ||||
|  | ||||
| @ -140,26 +145,28 @@ struct conn{ | ||||
|  | ||||
|  | ||||
|  | ||||
| struct conn * conn_create(int sock, struct sockaddr * addr, int qsize); | ||||
| struct conn * conn_create_noq(int sock, struct sockaddr * addr); | ||||
| struct conn *conn_create(int sock, struct sockaddr *addr, int qsize); | ||||
| struct conn *conn_create_noq(int sock, struct sockaddr *addr); | ||||
|  | ||||
|  | ||||
| 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 struct cwrmsg * conn_get_message(struct conn * conn); | ||||
| 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 *, uint8_t *,int len), void *cbarg); | ||||
|  | ||||
| extern int conn_send_packet(struct conn * conn,const uint8_t * buffer, int len); | ||||
| extern void conn_destroy(struct conn * conn); | ||||
| extern uint8_t *conn_get_message(struct conn *conn); | ||||
|  | ||||
| uint8_t * conn_q_get_packet(struct conn * conn); | ||||
| extern int conn_q_recv_packet(struct conn * conn, uint8_t * buffer,int len); | ||||
| extern int conn_q_recv_packet_peek(struct conn * conn, 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 int conn_recv_packet(struct conn* conn,uint8_t *buf,int len); | ||||
| extern int conn_recv_packet_peek(struct conn* conn,uint8_t *buf,int len); | ||||
| uint8_t *conn_q_get_packet(struct conn *conn); | ||||
| extern int conn_q_recv_packet(struct conn *conn, uint8_t * buffer, int len); | ||||
| extern int conn_q_recv_packet_peek(struct conn *conn, uint8_t * buffer, int len); | ||||
|  | ||||
| extern int conn_send_response(struct conn * conn,struct cwmsg * cwmsg,int seqnum); | ||||
| extern struct cwrmsg * conn_get_response(struct conn * conn); | ||||
| extern int conn_recv_packet(struct conn *conn, uint8_t * buf, int len); | ||||
| extern int conn_recv_packet_peek(struct conn *conn, uint8_t * buf, int len); | ||||
|  | ||||
| extern int conn_send_response(struct conn *conn, struct cwmsg *cwmsg, int seqnum); | ||||
| extern struct cwrmsg *conn_get_response(struct conn *conn); | ||||
|  | ||||
|  | ||||
| #define conn_get_next_seqnum(conn) (conn->seqnum=((conn->seqnum+1)&0xff)) | ||||
| @ -171,38 +178,38 @@ extern struct cwrmsg * conn_get_response(struct conn * conn); | ||||
| struct connlist { | ||||
| /*	struct conn ** connlist; */ | ||||
|  | ||||
| 	struct avltree * t; | ||||
| 	struct avltree *t; | ||||
| 	int len; | ||||
| 	pthread_mutex_t connlist_mutex; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct connlist * connlist_create(int len); | ||||
| void connlist_lock(struct connlist * cl); | ||||
| void connlist_unlock(struct connlist * cl); | ||||
| void conlist_destroy(struct connlist * cl); | ||||
| struct conn * connlist_get(struct connlist * cl, const struct sockaddr * addr); | ||||
| struct conn * connlist_add(struct connlist * cl, struct conn * conn); | ||||
| void connlist_remove(struct connlist *cl,struct conn * conn); | ||||
| void connlist_destroy(struct connlist * cl); | ||||
| void conn_q_add_packet(struct conn * conn,uint8_t *packet,int len); | ||||
| struct connlist *connlist_create(int len); | ||||
| void connlist_lock(struct connlist *cl); | ||||
| void connlist_unlock(struct connlist *cl); | ||||
| void conlist_destroy(struct connlist *cl); | ||||
| struct conn *connlist_get(struct connlist *cl, const struct sockaddr *addr); | ||||
| struct conn *connlist_add(struct connlist *cl, struct conn *conn); | ||||
| void connlist_remove(struct connlist *cl, struct conn *conn); | ||||
| void connlist_destroy(struct connlist *cl); | ||||
| void conn_q_add_packet(struct conn *conn, uint8_t * packet, int len); | ||||
|  | ||||
| struct image_identifier; | ||||
| struct cwimage_data; | ||||
|  | ||||
| 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 void conn_detect_capwap(struct conn * conn, struct wtpinfo * wtpinfo); | ||||
| struct cwrmsg * conn_send_request(struct conn * conn); | ||||
| struct cwrmsg * conn_wait_for_message(struct conn * conn, time_t timer); | ||||
| 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 void conn_detect_capwap(struct conn *conn, struct wtpinfo *wtpinfo); | ||||
| 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_request(struct conn * conn, int *msglist, time_t timer); | ||||
| struct cwrmsg *conn_wait_for_request(struct conn *conn, int *msglist, time_t timer); | ||||
|  | ||||
|  | ||||
| #define conn_is_error(conn) (conn->dtls_error) | ||||
|  | ||||
| void conn_init(struct conn * conn); | ||||
| void conn_init(struct conn *conn); | ||||
|  | ||||
|  | ||||
| #endif /* __CONLIST_H */ | ||||
|  | ||||
| #endif				/* __CONLIST_H */ | ||||
|  | ||||
| @ -16,25 +16,37 @@ struct args { | ||||
| 	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 conn *conn = args->conn; | ||||
| 	memcpy(conn->cwrmsg_buffer, rawmsg, len); | ||||
|  | ||||
|  | ||||
| /* | ||||
|  | ||||
| 	memcpy(&conn->cwrmsg, cwrmsg, sizeof(struct cwrmsg)); | ||||
| 	memcpy(conn->cwrmsg_buffer, cwrmsg->msgelems, | ||||
| 	       cwrmsg->msgelems_len); | ||||
| 	conn->cwrmsg.msgelems = conn->cwrmsg_buffer; | ||||
| */ | ||||
| 	args->cwrmsg = &conn->cwrmsg; | ||||
| 	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; | ||||
| 	args.cwrmsg = 0; | ||||
| @ -44,18 +56,20 @@ struct cwrmsg *conn_get_message(struct conn *conn) | ||||
|  | ||||
| 	int n = conn->read(conn, buf, len); | ||||
| 	if (n > 0) | ||||
| 		conn_process_packet(conn, buf, n, pmessage, &args); | ||||
| 		conn_process_packet(conn, buf, n, message_cb, &args); | ||||
|  | ||||
|  | ||||
| 	if (args.cwrmsg) { | ||||
|  | ||||
| 		cw_dbg(DBG_MSG,"Message recieved from %s",sock_addr2str(&conn->addr)); | ||||
| /* | ||||
| 		cw_dbg(DBG_MSG, | ||||
| 		       "Received message from %s, type=%d - %s, seq=%d", | ||||
| 		       sock_addr2str(&conn->addr), args.cwrmsg->type, | ||||
| 		       cw_msgtostr(args.cwrmsg->type), | ||||
| 		       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) | ||||
| 	                        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); | ||||
|  | ||||
|         } | ||||
| 	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; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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. */ | ||||
| 		cb(cbarg,cwrmsg); | ||||
| 		cb(cbarg,rawmsg,rawlen); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* It's a request message, check if seqnum is right and if | ||||
| 	 * we have already sent a response message*/ | ||||
|  | ||||
| 	uint8_t seqnum = cw_get_msg_seqnum(msgptr); | ||||
|  | ||||
| 	int s1=conn->last_seqnum_received; | ||||
| 	int s2=cwrmsg->seqnum; | ||||
| 	int s2=seqnum; | ||||
| 	int sd=s2-s1; | ||||
|  | ||||
| 	if ((sd>0 && sd<128) || (sd<0 && sd<-128) || s1<0){ | ||||
| 		/* seqnum is ok, normal message processing */ | ||||
| 		conn->last_seqnum_received=cwrmsg->seqnum; | ||||
| 		cb(cbarg,cwrmsg); | ||||
| 		conn->last_seqnum_received=seqnum; | ||||
| 		cb(cbarg,rawmsg,rawlen); | ||||
| 		return 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", | ||||
| 			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, | ||||
| 	 * 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", | ||||
| 		sock_addr2str(&conn->addr),s2,cwrmsg->type); | ||||
| 	cw_dbg(DBG_MSG_ERR,"Retransmitted request message from %s detected, seqnum=%d, type=%d", | ||||
| 		sock_addr2str(&conn->addr),s2,type); | ||||
|  | ||||
| 	if (conn->resp_msg.type-1 != cwrmsg->type ){ | ||||
| 		cw_dbg(DBG_CW_MSG_ERR,"No cached response for retransmission, request seqnum=%d,in cache=%d",s2,conn->resp_msg.type ); | ||||
| 	if (conn->resp_msg.type-1 != type ){ | ||||
| 		cw_dbg(DBG_MSG_ERR,"No cached response for retransmission, request seqnum=%d,in cache=%d",s2,conn->resp_msg.type ); | ||||
| 		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); | ||||
| 	conn_send_cwmsg(conn,&conn->resp_msg); | ||||
| 	return 1;	 | ||||
| @ -154,72 +161,68 @@ static void cw_dbg_packet(struct conn * conn, uint8_t * packet, int len) | ||||
| #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){ | ||||
| 		/* packet too short */ | ||||
| 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, packet too short, len=%d",sock_addr2str(&conn->addr),len); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	uint32_t val = ntohl(*((uint32_t*)packet)); | ||||
| 	int preamble = cw_get_hdr_preamble(packet); | ||||
|  | ||||
| 	int preamble = val >> 24; | ||||
| 	if ( (preamble & 0xf0) != CW_VERSION){ | ||||
| 		/* wrong version */ | ||||
| 		cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, wrong version, version=%d",sock_addr2str(&conn->addr),(preamble&0xf0)>>8); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	if (preamble & 0xf ) { | ||||
| 		/* decode dtls */ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* log this packet */ | ||||
| 	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){ | ||||
| 		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 */ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| /* | ||||
| 	struct cwrmsg cwrmsg; | ||||
| 	cwrmsg.wbid=(val>>9) & 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 (*(packet+8)+8>hlen){ | ||||
| 		if (cw_get_hdr_rmac_len(packet)+8>offs){ | ||||
| 			/* 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; | ||||
| 		} | ||||
| 		memcpy(cwrmsg.rmac, packet+8,8); | ||||
| 	} | ||||
| 	else{ | ||||
| 		cwrmsg.rmac[0]=0; | ||||
| //		memcpy(cwrmsg.rmac, packet+8,8); | ||||
| 	} | ||||
| //	else{ | ||||
| //		cwrmsg.rmac[0]=0; | ||||
| //	} | ||||
|  | ||||
|  | ||||
| 	if (val & CWTH_FLAGS_F){	/* fragmented */ | ||||
| 	if (cw_get_hdr_flag_f(packet)){	/* fragmented */ | ||||
| 		uint8_t * f; | ||||
| 		f = fragman_add(conn->fragman, packet,hlen,payloadlen); | ||||
| 		f = fragman_add(conn->fragman, packet,offs,payloadlen); | ||||
| 		if (f==NULL) | ||||
| 			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); | ||||
| 		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)){ | ||||
| 			free(f); | ||||
| 			return; | ||||
| 		}; | ||||
| 		process_message(conn,&cwrmsg,cb,cbarg);  | ||||
| */ | ||||
| 		process_message(conn,f+4,*(uint32_t*)f,cb,cbarg);  | ||||
|  | ||||
| 		free (f); | ||||
| 		return; | ||||
| 	} | ||||
| @ -243,13 +251,14 @@ extern int cw_process_msg(struct conn * conn,uint8_t*msg,int 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)); | ||||
| 		return; | ||||
| 	} | ||||
| 	//	return; | ||||
| 	//} | ||||
|  | ||||
|  | ||||
| 	process_message(conn,&cwrmsg,cb,cbarg);  | ||||
| printf("Next big thing\n"); | ||||
| //msg_4*((val >> 19) & 0x1f); | ||||
| 	process_message(conn,packet,len,cb,cbarg);  | ||||
| 	return; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -44,7 +44,7 @@ struct cwrmsg * conn_send_request(struct conn * conn) | ||||
|  | ||||
|                 time_t r_timer = cw_timer_start(conn->retransmit_interval); | ||||
| 		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); | ||||
| 		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; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -22,13 +22,20 @@ static inline int cw_action_cmp(const void *elem1,const void *elem2) | ||||
| 	if (r!=0) | ||||
| 		return r; | ||||
|  | ||||
| 	r = e1->vendor_id - e2->vendor_id; | ||||
| 	if (r!=0) | ||||
| 		return r; | ||||
|  | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
| static void cw_action_del(void*d) | ||||
| { | ||||
| 	free(d); | ||||
| } | ||||
| */ | ||||
|  | ||||
| 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() | ||||
| { | ||||
| 	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) | ||||
| { | ||||
| 	while(actions->capwap_state){ | ||||
| 		cw_action_t *a = actions; | ||||
| 		printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id); | ||||
| //		cw_action_t *a = actions; | ||||
| //		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); | ||||
| 		if (rc==0)  | ||||
| 			return 0;	 | ||||
|  | ||||
| @ -6,16 +6,22 @@ | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "avltree.h" | ||||
| #include "conn.h" | ||||
|  | ||||
| struct cw_action{ | ||||
| 	uint32_t vendor_id; | ||||
| 	uint8_t proto; | ||||
| 	uint8_t capwap_state; | ||||
| 	uint32_t msg_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 (*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; | ||||
|  | ||||
| @ -34,7 +34,6 @@ | ||||
|  */ | ||||
|  | ||||
| #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_DMP			0x00000004	/* Dump CAPWAP message elements */ | ||||
| @ -47,8 +46,9 @@ | ||||
| #define DBG_CW_PKT_DMP			0x00000080	/* Dump packts */ | ||||
| #define DBG_CW_PKT_DTL			0x00000100	 | ||||
| #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_ELEM_ERR			0x00001000 | ||||
|  | ||||
| /* driver specific debugs */ | ||||
| #define DBG_DRV				0x00010000 | ||||
| @ -69,7 +69,7 @@ | ||||
|  | ||||
|  | ||||
| #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_dmp",DBG_CW_PKT_DMP}, | ||||
| 	{"pkt_err",DBG_CW_PKT_ERR}, | ||||
| 	{"msg_err",DBG_CW_MSG_ERR}, | ||||
| 	{"msg_err",DBG_MSG_ERR}, | ||||
| 	{"img_dtl",DBG_CW_IMG_DTL}, | ||||
| 	{"elem_err",DBG_ELEM_ERR}, | ||||
|  | ||||
| 	{"dtls",DBG_DTLS}, | ||||
| 	{"dtls_dietail",DBG_DTLS_DETAIL}, | ||||
|  | ||||
| @ -45,9 +45,9 @@ const char * cw_msgtostr(int type) | ||||
| 		case CW_MSG_CONFIGURATION_UPDATE_RESPONSE: | ||||
| 			return "configuration update response"; | ||||
| 			 | ||||
| 		case CWMSG_WTP_EVENT_REQUEST: | ||||
| 		case CW_MSG_WTP_EVENT_REQUEST: | ||||
| 			return "wtp event request"; | ||||
| 		case CWMSG_WTP_EVENT_RESPONSE: | ||||
| 		case CW_MSG_WTP_EVENT_RESPONSE: | ||||
| 			return "wtp event response"; | ||||
|  | ||||
|  | ||||
| @ -83,9 +83,9 @@ const char * cw_msgtostr(int type) | ||||
|            Reset Request                       17 | ||||
|            Reset Response                      18 | ||||
| */	    | ||||
| 		case CWMSG_PRIMARY_DISCOVERY_REQUEST: | ||||
| 		case CW_MSG_PRIMARY_DISCOVERY_REQUEST: | ||||
| 			return "primary discovery request"; | ||||
| 		case CWMSG_PRIMARY_DISCOVERY_RESPONSE: | ||||
| 		case CW_MSG_PRIMARY_DISCOVERY_RESPONSE: | ||||
| 			return "primary discovery response"; | ||||
|  | ||||
| /*           Data Transfer Request               21 | ||||
|  | ||||
| @ -4,25 +4,61 @@ | ||||
|  | ||||
| #include "conn.h" | ||||
| #include "capwap.h" | ||||
| #include "sock.h" | ||||
| #include "cw_action.h" | ||||
| #include "cw_log.h" | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | ||||
| { | ||||
| 	struct cw_action as,*af; | ||||
|  | ||||
|  | ||||
| 	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 */ | ||||
| 	as.elem_id=-1; | ||||
| 	as.capwap_state=conn->capwap_state; | ||||
| 	as.msg_id = cw_get_msg_id(msg_ptr); | ||||
| 	as.vendor_id=0; | ||||
|  | ||||
|  | ||||
| 	/* Search for state/message combination */ | ||||
| 	af = cw_actionlist_get(conn->msgtr,&as); | ||||
|  | ||||
| 	/* Check if message is comes in right state */ | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
| @ -31,7 +67,6 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int 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); | ||||
|  | ||||
| 	 | ||||
| @ -43,6 +78,8 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len) | ||||
| 		as.elem_id = cw_get_elem_id(elem); | ||||
| 		int elem_len = cw_get_elem_len(elem); | ||||
|  | ||||
|  | ||||
|  | ||||
| 		af = cw_actionlist_get(conn->msgtr,&as); | ||||
| 		 | ||||
| 		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); | ||||
| 		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)); | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| @ -30,7 +30,7 @@ int cw_readelem_80211_wtp_radio_info(void *dst,int type,uint8_t *msgelem, int le | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -28,7 +28,7 @@ int cw_readelem_ac_name(uint8_t **dst, int type,uint8_t *msgelem, int len) | ||||
|  | ||||
| 	if (len > 512 ) { | ||||
| 		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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -26,7 +26,7 @@ int lw_readelem_wtp_board_data(struct wtpinfo *wtpinfo, int type, uint8_t *msgel | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -42,7 +42,7 @@ int lw_readelem_wtp_name(uint8_t ** dst, int type, uint8_t * msgelem, int len) | ||||
|  | ||||
| 	 | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -11,7 +11,7 @@ int wtpinfo_readelem_discovery_type(struct wtpinfo * wtpinfo, int type, uint8_t | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -66,7 +66,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, | ||||
| 	do { | ||||
| 		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; | ||||
| 		} | ||||
|  | ||||
| @ -78,7 +78,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, | ||||
| 		i+=8; | ||||
|  | ||||
| 		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; | ||||
| 		} | ||||
|  | ||||
| @ -102,7 +102,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type, | ||||
| 				wtpinfo->bootloader_version_len=sublen; | ||||
| 				break; | ||||
| 			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; | ||||
| 		} | ||||
| 		i+=sublen; | ||||
|  | ||||
| @ -11,7 +11,7 @@ int wtpinfo_readelem_wtp_frame_tunnel_mode(struct wtpinfo * wtpinfo, int type, u | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
| 	wtpinfo->frame_tunnel_mode=*msgelem; | ||||
|  | ||||
| @ -10,7 +10,7 @@ int wtpinfo_readelem_wtp_mac_type(struct wtpinfo * wtpinfo, int type, uint8_t * | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -12,7 +12,7 @@ int wtpinfo_readelem_wtp_name(struct wtpinfo * wtpinfo, int type, uint8_t * msge | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -30,7 +30,7 @@ int wtpinfo_readelem_wtp_radio_info(struct wtpinfo * wtpinfo,int type,uint8_t *m | ||||
| 		return 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user