diff --git a/src/ac/ac_main.c b/src/ac/ac_main.c index d68db98f..d0fe5958 100644 --- a/src/ac/ac_main.c +++ b/src/ac/ac_main.c @@ -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; iconn->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 ) @@ -414,9 +431,7 @@ wtpman->conn->msgtr=the_tree; cw_dbg(DBG_CW_INFO,"Discovery request gave us the follwing WTP Info:\n%s",wtpinfostr); */ - 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); } diff --git a/src/capwap/Makefile b/src/capwap/Makefile index d5d7a8fe..2c95feaa 100644 --- a/src/capwap/Makefile +++ b/src/capwap/Makefile @@ -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 \ diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index dde21699..baba4469 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -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 diff --git a/src/capwap/conn.h b/src/capwap/conn.h index 8403a5e0..2898cb40 100644 --- a/src/capwap/conn.h +++ b/src/capwap/conn.h @@ -33,32 +33,37 @@ #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; int seqnum; - int last_seqnum_received; + 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]; @@ -69,42 +74,42 @@ struct conn{ uint8_t req_buffer[65536]; uint8_t resp_buffer[65536]; - + int mtu; /* max mtu, could be changed during discovery */ int mtu_discovery; /* 0 mtu discovery turned off, 1 discovery tuned on */ /* 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; @@ -118,11 +123,11 @@ struct conn{ int max_retransmit; int wait_dtls; int wait_join; - + /* 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 */ diff --git a/src/capwap/conn_get_message.c b/src/capwap/conn_get_message.c index e8cb27ed..6de4f9f1 100644 --- a/src/capwap/conn_get_message.c +++ b/src/capwap/conn_get_message.c @@ -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; } diff --git a/src/capwap/conn_get_response.c b/src/capwap/conn_get_response.c index 9c990fb5..388ebdd2 100644 --- a/src/capwap/conn_get_response.c +++ b/src/capwap/conn_get_response.c @@ -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; } diff --git a/src/capwap/conn_process_packet.c b/src/capwap/conn_process_packet.c index b87193e7..826156a1 100644 --- a/src/capwap/conn_process_packet.c +++ b/src/capwap/conn_process_packet.c @@ -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)); - - if (val & CWTH_FLAGS_M){ + /* Check Radio MAC if preset */ + if (cw_get_hdr_flag_m(packet)){ - 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; } diff --git a/src/capwap/conn_send_request.c b/src/capwap/conn_send_request.c index 6debc5d0..48bc426b 100644 --- a/src/capwap/conn_send_request.c +++ b/src/capwap/conn_send_request.c @@ -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; } diff --git a/src/capwap/cw_action.c b/src/capwap/cw_action.c index 32b90893..77cc4b1d 100644 --- a/src/capwap/cw_action.c +++ b/src/capwap/cw_action.c @@ -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; diff --git a/src/capwap/cw_action.h b/src/capwap/cw_action.h index f1268b2d..0516a2b8 100644 --- a/src/capwap/cw_action.h +++ b/src/capwap/cw_action.h @@ -6,16 +6,22 @@ #include #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; diff --git a/src/capwap/cw_log.h b/src/capwap/cw_log.h index 76e94595..4d2edf00 100644 --- a/src/capwap/cw_log.h +++ b/src/capwap/cw_log.h @@ -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) /**@}*/ diff --git a/src/capwap/cw_log_str2dbglevel.c b/src/capwap/cw_log_str2dbglevel.c index 3318651c..abd31438 100644 --- a/src/capwap/cw_log_str2dbglevel.c +++ b/src/capwap/cw_log_str2dbglevel.c @@ -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}, diff --git a/src/capwap/cw_msgtostr.c b/src/capwap/cw_msgtostr.c index d51cd7c4..ec678290 100644 --- a/src/capwap/cw_msgtostr.c +++ b/src/capwap/cw_msgtostr.c @@ -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 diff --git a/src/capwap/cw_process_msg.c b/src/capwap/cw_process_msg.c index f024b675..f6b2f874 100644 --- a/src/capwap/cw_process_msg.c +++ b/src/capwap/cw_process_msg.c @@ -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); + } } diff --git a/src/capwap/cw_read_image_data_request.c b/src/capwap/cw_read_image_data_request.c index 1c4e493f..45f6288f 100644 --- a/src/capwap/cw_read_image_data_request.c +++ b/src/capwap/cw_read_image_data_request.c @@ -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; } diff --git a/src/capwap/cw_readelem_80211_wtp_radio_info.c b/src/capwap/cw_readelem_80211_wtp_radio_info.c index 753466c7..b26984a9 100644 --- a/src/capwap/cw_readelem_80211_wtp_radio_info.c +++ b/src/capwap/cw_readelem_80211_wtp_radio_info.c @@ -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; } diff --git a/src/capwap/cw_readelem_ac_name.c b/src/capwap/cw_readelem_ac_name.c index 43beb9de..92c09df5 100644 --- a/src/capwap/cw_readelem_ac_name.c +++ b/src/capwap/cw_readelem_ac_name.c @@ -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; } diff --git a/src/capwap/lw_readelem_wtp_board_data.c b/src/capwap/lw_readelem_wtp_board_data.c index 22710dc1..08671a45 100644 --- a/src/capwap/lw_readelem_wtp_board_data.c +++ b/src/capwap/lw_readelem_wtp_board_data.c @@ -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; } diff --git a/src/capwap/lw_readelem_wtp_name.c b/src/capwap/lw_readelem_wtp_name.c index 626e1429..219e380e 100644 --- a/src/capwap/lw_readelem_wtp_name.c +++ b/src/capwap/lw_readelem_wtp_name.c @@ -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; } diff --git a/src/capwap/wtpinfo_readelem_discovery_type.c b/src/capwap/wtpinfo_readelem_discovery_type.c index cdc8baba..6b0342b4 100644 --- a/src/capwap/wtpinfo_readelem_discovery_type.c +++ b/src/capwap/wtpinfo_readelem_discovery_type.c @@ -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; } diff --git a/src/capwap/wtpinfo_readelem_wtp_descriptor.c b/src/capwap/wtpinfo_readelem_wtp_descriptor.c index 26408b91..a452773d 100644 --- a/src/capwap/wtpinfo_readelem_wtp_descriptor.c +++ b/src/capwap/wtpinfo_readelem_wtp_descriptor.c @@ -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; diff --git a/src/capwap/wtpinfo_readelem_wtp_frame_tunnel_mode.c b/src/capwap/wtpinfo_readelem_wtp_frame_tunnel_mode.c index 4ec1f63c..fdaca50e 100644 --- a/src/capwap/wtpinfo_readelem_wtp_frame_tunnel_mode.c +++ b/src/capwap/wtpinfo_readelem_wtp_frame_tunnel_mode.c @@ -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; diff --git a/src/capwap/wtpinfo_readelem_wtp_mac_type.c b/src/capwap/wtpinfo_readelem_wtp_mac_type.c index f299caa8..d9e7cc88 100644 --- a/src/capwap/wtpinfo_readelem_wtp_mac_type.c +++ b/src/capwap/wtpinfo_readelem_wtp_mac_type.c @@ -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; } diff --git a/src/capwap/wtpinfo_readelem_wtp_name.c b/src/capwap/wtpinfo_readelem_wtp_name.c index e9153049..ec61718a 100644 --- a/src/capwap/wtpinfo_readelem_wtp_name.c +++ b/src/capwap/wtpinfo_readelem_wtp_name.c @@ -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; } diff --git a/src/capwap/wtpinfo_readelem_wtp_radio_info.c b/src/capwap/wtpinfo_readelem_wtp_radio_info.c index d9021b57..cf58294c 100644 --- a/src/capwap/wtpinfo_readelem_wtp_radio_info.c +++ b/src/capwap/wtpinfo_readelem_wtp_radio_info.c @@ -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; }