diff --git a/src/capwap/action.c b/src/capwap/action.c index 890bed8a..bf5f3a6d 100644 --- a/src/capwap/action.c +++ b/src/capwap/action.c @@ -174,7 +174,7 @@ cw_action_in_t *cw_actionlist_in_set_msg_end_callback(cw_actionlist_in_t a, uint32_t msg_id, int (*fun) (struct conn * conn, struct cw_action_in * a, uint8_t * data, - int len)) + int len,struct sockaddr *from)) { cw_action_in_t as,*ar; as.vendor_id=0; diff --git a/src/capwap/action.h b/src/capwap/action.h index e5cc192a..96f3595e 100644 --- a/src/capwap/action.h +++ b/src/capwap/action.h @@ -41,8 +41,8 @@ struct cw_action_in{ uint8_t capwap_state; uint32_t msg_id; uint16_t elem_id; - int (*start)(struct conn *conn,struct cw_action_in *a,uint8_t*data,int len); - int (*end)(struct conn *conn,struct cw_action_in *a,uint8_t*elem,int len); + int (*start)(struct conn *conn,struct cw_action_in *a,uint8_t*data,int len,struct sockaddr *from); + int (*end)(struct conn *conn,struct cw_action_in *a,uint8_t*elem,int len,struct sockaddr *from); uint8_t itemtype; uint16_t item_id; uint16_t min_len; @@ -65,7 +65,7 @@ extern cw_action_in_t *cw_actionlist_in_set_msg_end_callback(cw_actionlist_in_t uint32_t msg_id, int (*fun) (struct conn * conn, struct cw_action_in * a, uint8_t * data, - int len)); + int len,struct sockaddr *from)); /* Definitions for outgoing messages */ diff --git a/src/capwap/capwap.h b/src/capwap/capwap.h index 186034f3..fce98f33 100644 --- a/src/capwap/capwap.h +++ b/src/capwap/capwap.h @@ -878,17 +878,17 @@ static inline const char *cw_strelemp_(cw_strheap_t h, int msg_id) extern int cw_in_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); extern int cw_in_vendor_specific_payload(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len); + uint8_t * data, int len,struct sockaddr *from); extern int cw_in_wtp_name(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); extern int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); extern int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); extern int cw_in_capwap_control_ipv4_address(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len); + uint8_t * data, int len, struct sockaddr *from); //extern int cw_out_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len); extern int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst); //, struct cw_item *item); @@ -961,22 +961,22 @@ int cw_in_set_state_none(struct conn *conn, struct cw_action_in *a, uint8_t * da struct cw_item *cw_out_get_outgoing(struct conn *conn, struct cw_action_out *a); struct cw_item *cw_out_get_local(struct conn *conn, struct cw_action_out *a); extern int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len); + uint8_t * data, int len,struct sockaddr *from); extern int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); int cw_in_check_disc_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); int cw_check_missing_mand(cw_action_in_t ** out, struct conn *conn, cw_action_in_t * a); int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); extern int cw_in_check_img_data_req_wtp(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len); + uint8_t * data, int len,struct sockaddr *from); extern int cw_in_check_img_data_req_ac(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len); + uint8_t * data, int len,struct sockaddr *from); int cw_in_check_img_data_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len); + int len,struct sockaddr *from); int cw_out_wtp_board_data(struct conn *conn, struct cw_action_out *a, uint8_t * dst); diff --git a/src/capwap/capwap_cisco.h b/src/capwap/capwap_cisco.h index ef52fc07..a70cff11 100644 --- a/src/capwap/capwap_cisco.h +++ b/src/capwap/capwap_cisco.h @@ -194,7 +194,7 @@ int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct ra int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri); extern int cw_out_cisco_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) ; -int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len); +int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from); diff --git a/src/capwap/conn.h b/src/capwap/conn.h index ec0a4705..e4570fda 100644 --- a/src/capwap/conn.h +++ b/src/capwap/conn.h @@ -106,6 +106,7 @@ struct conn { int (*recv_packet_peek) (struct conn *, uint8_t *, int); int (*send_packet) (struct conn *, const uint8_t *, int); + int (*readfrom) (struct conn *, uint8_t *, int, struct sockaddr_storage *); int (*read) (struct conn *, uint8_t *, int); int (*write) (struct conn *, const uint8_t *, int); @@ -239,6 +240,9 @@ void conn_init(struct conn *conn); extern int cw_read_messages(struct conn *conn); +extern int conn_recvfrom_packet(struct conn *conn, uint8_t * buf, int len, + struct sockaddr_storage *from); + diff --git a/src/capwap/conn_process_packet.c b/src/capwap/conn_process_packet.c index 77f1f98d..0a9e89ba 100644 --- a/src/capwap/conn_process_packet.c +++ b/src/capwap/conn_process_packet.c @@ -126,7 +126,7 @@ int cw_send_error_response(struct conn *conn, uint8_t * rawmsg, uint32_t result_ } -static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) +static int process_elements(struct conn *conn, uint8_t * rawmsg, int len,struct sockaddr *from) { struct cw_action_in as, *af, *afm; @@ -211,7 +211,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) /* Execute start processor for message */ if (afm->start) { - afm->start(conn, afm, rawmsg, len); + afm->start(conn, afm, rawmsg, len,from); } uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr); @@ -234,7 +234,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) if (!af) { cw_dbg(DBG_ELEM_ERR, - "ELEM_ERR: Element %d (%s) not allowed in msg of type %d (%s).", + "Element %d (%s) not allowed in msg of type %d (%s), ignoring.", as.elem_id, cw_strelem(as.elem_id), as.msg_id, cw_strmsg(as.msg_id)); continue; @@ -242,7 +242,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) int afrc = 1; if (af->start) { - afrc = af->start(conn, af, cw_get_elem_data(elem), elem_len); + afrc = af->start(conn, af, cw_get_elem_data(elem), elem_len,from); } @@ -259,7 +259,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) int result_code = 0; if (afm->end) { - result_code = afm->end(conn, afm, rawmsg, len); + result_code = afm->end(conn, afm, rawmsg, len,from); } /* if we've got a request message, we always have to send a response message */ @@ -296,8 +296,7 @@ static int process_elements(struct conn *conn, uint8_t * rawmsg, int len) -static int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen, - int (*cb) (void *, uint8_t *, int), void *cbarg) +static int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen,struct sockaddr *from) { uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg); @@ -306,7 +305,7 @@ static int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen, if (!(type & 0x1)) { /* It's a response message, no further examination required. */ - return process_elements(conn, rawmsg, rawlen); + return process_elements(conn, rawmsg, rawlen, from); } /* It's a request message, check if seqnum is right and if @@ -321,7 +320,7 @@ static int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen, if ((sd > 0 && sd < 128) || (sd < 0 && sd < -128) || s1 < 0) { /* seqnum is ok, normal message processing */ conn->last_seqnum_received = seqnum; - return process_elements(conn, rawmsg, rawlen); + return process_elements(conn, rawmsg, rawlen,from); } if (sd != 0) { @@ -364,10 +363,10 @@ static int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen, * @param packet pointer to packet data * @param len lenght of packet data */ -int conn_process_packet(struct conn *conn, uint8_t * packet, int len) +int conn_process_packet(struct conn *conn, uint8_t * packet, int len,struct sockaddr *from) { /* show this packet in debug output */ - cw_dbg_pkt(DBG_PKT_IN, conn, packet, len); + cw_dbg_pkt(DBG_PKT_IN, conn, packet, len,from); if (len < 8) { @@ -436,16 +435,16 @@ int conn_process_packet(struct conn *conn, uint8_t * packet, int len) if (f == NULL) return 0; - cw_dbg_msg(DBG_MSG_IN, conn, packet, len); - int rc = process_message(conn, f + 4, *(uint32_t *) f, NULL, NULL); + cw_dbg_msg(DBG_MSG_IN, conn, packet, len,from); + int rc = process_message(conn, f + 4, *(uint32_t *) f, from); free(f); return rc; } /* not fragmented, we have a complete message */ - cw_dbg_msg(DBG_MSG_IN, conn, packet, len); - return process_message(conn, packet, len, NULL, NULL); + cw_dbg_msg(DBG_MSG_IN, conn, packet, len,from); + return process_message(conn, packet, len, from); } @@ -462,11 +461,32 @@ int cw_read_messages(struct conn *conn) return n; if (n > 0) { -// printf("Have a packet with %d bytes\n",n); - return conn_process_packet(conn, buf, n); + return conn_process_packet(conn, buf, n,(struct sockaddr*)&conn->addr); + } + errno = EAGAIN; + return -1; +} + +int cw_read_from(struct conn * conn) +{ + if (!conn->readfrom){ + cw_log(LOG_ERR,"Fatal error, no readfrom method available."); + errno = EPROTO; + return -1; + } + uint8_t buf[2024]; + int len = 2024; + + struct sockaddr_storage from; + int n = conn->readfrom(conn, buf, len,&from); + if (n < 0) + return n; + + if (n > 0) { + return conn_process_packet(conn, buf, n,(struct sockaddr*)&from); } - //printf("DTLS_ERROR: %d\n",conn->dtls_error); errno = EAGAIN; return -1; + } diff --git a/src/capwap/conn_recv_packet.c b/src/capwap/conn_recv_packet.c index 9df23527..08f0613c 100644 --- a/src/capwap/conn_recv_packet.c +++ b/src/capwap/conn_recv_packet.c @@ -24,13 +24,14 @@ #include "conn.h" -int conn_recv_packet_(struct conn* conn,uint8_t *buf,int len,int flags) +#include "sock.h" + +int conn_recv_packet_(struct conn *conn, uint8_t * buf, int len, int flags) { int n; - while( (n = recv(conn->sock,(char*)buf,len,flags)) < 0 ){ - if (errno!=EINTR) - { - if ( errno==EAGAIN ) + while ((n = recv(conn->sock, (char *) buf, len, flags)) < 0) { + if (errno != EINTR) { + if (errno == EAGAIN) return n; } @@ -39,17 +40,37 @@ int conn_recv_packet_(struct conn* conn,uint8_t *buf,int len,int flags) } +int conn_recvfrom_packet(struct conn *conn, uint8_t * buf, int len, + struct sockaddr_storage *from) +{ + socklen_t al; + + al = sizeof(struct sockaddr_storage); + memset(from, 0, sizeof(struct sockaddr_storage)); + + int n; + while ((n = recvfrom(conn->sock, (char *) buf, len, 0, (struct sockaddr*)from, &al)) < 0) { + if (errno != EINTR) { + if (errno == EAGAIN) + return n; + + } + + } + return n; + +} + /* yes, these functions could be better defined as macros in a .h file */ -int conn_recv_packet(struct conn* conn,uint8_t *buf,int len) +int conn_recv_packet(struct conn *conn, uint8_t * buf, int len) { - return conn_recv_packet_(conn,buf,len,0); + return conn_recv_packet_(conn, buf, len, 0); } -int conn_recv_packet_peek(struct conn* conn,uint8_t *buf,int len) +int conn_recv_packet_peek(struct conn *conn, uint8_t * buf, int len) { - int rc = conn_recv_packet_(conn,buf,len,MSG_PEEK); + int rc = conn_recv_packet_(conn, buf, len, MSG_PEEK); return rc; - -} +} diff --git a/src/capwap/conn_resp_init.c b/src/capwap/conn_resp_init.c deleted file mode 100644 index 765cd13e..00000000 --- a/src/capwap/conn_resp_init.c +++ /dev/null @@ -1,11 +0,0 @@ - -#include "conn.h" - - -void conn_resp_init(strucct conn * conn) -{ - - - - -} diff --git a/src/capwap/cw_in_capwap_control_ipv4_address.c b/src/capwap/cw_in_capwap_control_ipv4_address.c index 222537f4..48a37531 100644 --- a/src/capwap/cw_in_capwap_control_ipv4_address.c +++ b/src/capwap/cw_in_capwap_control_ipv4_address.c @@ -19,7 +19,7 @@ int cw_in_capwap_control_ipv4_address(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len) + uint8_t * data, int len,struct sockaddr *from) { cw_aciplist_t list = cw_itemstore_get_avltree_c(conn->incomming,a->item_id,cw_aciplist_create); diff --git a/src/capwap/cw_in_check_disc_req.c b/src/capwap/cw_in_check_disc_req.c index e7c8b42d..c7a5a390 100644 --- a/src/capwap/cw_in_check_disc_req.c +++ b/src/capwap/cw_in_check_disc_req.c @@ -8,7 +8,7 @@ #include "sock.h" int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len,struct sockaddr *from) { cw_action_in_t *mlist[120]; diff --git a/src/capwap/cw_in_check_disc_resp.c b/src/capwap/cw_in_check_disc_resp.c index 153f11fa..519111ed 100644 --- a/src/capwap/cw_in_check_disc_resp.c +++ b/src/capwap/cw_in_check_disc_resp.c @@ -8,7 +8,7 @@ #include "sock.h" int cw_in_check_disc_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len,struct sockaddr *from) { cw_action_in_t *mlist[20]; int n = cw_check_missing_mand(mlist, conn, a); diff --git a/src/capwap/cw_in_check_img_data_req_ac.c b/src/capwap/cw_in_check_img_data_req_ac.c index cfa81cba..9dffd3eb 100644 --- a/src/capwap/cw_in_check_img_data_req_ac.c +++ b/src/capwap/cw_in_check_img_data_req_ac.c @@ -8,7 +8,7 @@ int cw_in_check_img_data_req_ac(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len,struct sockaddr *from) { /* Check for mandatory elements */ cw_action_in_t * mlist[60]; diff --git a/src/capwap/cw_in_check_img_data_req_wtp.c b/src/capwap/cw_in_check_img_data_req_wtp.c index 2c6a2934..684a1c4e 100644 --- a/src/capwap/cw_in_check_img_data_req_wtp.c +++ b/src/capwap/cw_in_check_img_data_req_wtp.c @@ -9,7 +9,7 @@ #include //Tube int cw_in_check_img_data_req_wtp(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len,struct sockaddr *from) { cw_itemstore_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0); diff --git a/src/capwap/cw_in_check_img_data_resp.c b/src/capwap/cw_in_check_img_data_resp.c index 11257cdb..a084b053 100644 --- a/src/capwap/cw_in_check_img_data_resp.c +++ b/src/capwap/cw_in_check_img_data_resp.c @@ -8,7 +8,7 @@ int cw_in_check_img_data_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len, struct sockaddr *from) { cw_action_in_t * mlist[60]; diff --git a/src/capwap/cw_in_check_join_req.c b/src/capwap/cw_in_check_join_req.c index d24d6083..3d629fa9 100644 --- a/src/capwap/cw_in_check_join_req.c +++ b/src/capwap/cw_in_check_join_req.c @@ -6,7 +6,7 @@ #include "capwap_items.h" int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len,struct sockaddr *from) { cw_action_in_t * mlist[60]; diff --git a/src/capwap/cw_in_check_join_resp.c b/src/capwap/cw_in_check_join_resp.c index 9605f475..5d0f17e9 100644 --- a/src/capwap/cw_in_check_join_resp.c +++ b/src/capwap/cw_in_check_join_resp.c @@ -8,7 +8,7 @@ #include "capwap_items.h" int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, - int len) + int len,struct sockaddr *from) { cw_action_in_t * mlist[60]; diff --git a/src/capwap/cw_in_cisco_image_identifier.c b/src/capwap/cw_in_cisco_image_identifier.c index d1a1dda9..ba595ffc 100644 --- a/src/capwap/cw_in_cisco_image_identifier.c +++ b/src/capwap/cw_in_cisco_image_identifier.c @@ -3,9 +3,10 @@ #include "dbg.h" #include "itemstore.h" #include "capwap.h" +#include "capwap_cisco.h" -int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) +int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from) { if (lenmin_len) { diff --git a/src/capwap/cw_in_generic.c b/src/capwap/cw_in_generic.c index 09567b4d..f7dcc97b 100644 --- a/src/capwap/cw_in_generic.c +++ b/src/capwap/cw_in_generic.c @@ -7,7 +7,7 @@ -int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) +int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from) { if (lenmin_len) { cw_dbg(DBG_ELEM_ERR,"Message element too short, %d < %d", len,a->min_len); diff --git a/src/capwap/cw_in_vendor_specific_payload.c b/src/capwap/cw_in_vendor_specific_payload.c index c3295b83..26004a2c 100644 --- a/src/capwap/cw_in_vendor_specific_payload.c +++ b/src/capwap/cw_in_vendor_specific_payload.c @@ -11,7 +11,7 @@ /** * Default handler for Vendor Specific Payload message elements. */ -int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len) +int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from) { cw_action_in_t as,*af; as = *a; @@ -31,7 +31,7 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint } if (af->start) { - af->start(conn,af,data+6,len-6); + af->start(conn,af,data+6,len-6,from); } return 1; diff --git a/src/capwap/cw_in_wtp_board_data.c b/src/capwap/cw_in_wtp_board_data.c index 139f461a..316af293 100644 --- a/src/capwap/cw_in_wtp_board_data.c +++ b/src/capwap/cw_in_wtp_board_data.c @@ -34,7 +34,7 @@ static void readsubelems_wtp_board_data(cw_itemstore_t itemstore, uint8_t * msgelem, - int len) + int len) { int i = 0; @@ -45,35 +45,40 @@ static void readsubelems_wtp_board_data(cw_itemstore_t itemstore, uint8_t * msge int sublen = val & 0xffff; i += 4; if (sublen + i > len) { - cw_dbg(DBG_ELEM_ERR, "WTP Board data sub-element too long, type=%d,len=%d", + cw_dbg(DBG_ELEM_ERR, + "WTP Board data sub-element too long, type=%d,len=%d", subtype, sublen); return; } - cw_dbg(DBG_SUBELEM, "Reading WTP board data sub-element, type=%d, len=%d", subtype, - sublen); + cw_dbg(DBG_SUBELEM, "Reading WTP board data sub-element, type=%d, len=%d", + subtype, sublen); switch (subtype) { case CW_BOARDDATA_MODELNO: - cw_itemstore_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_MODELNO, + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_BOARD_MODELNO, msgelem + i, sublen); break; case CW_BOARDDATA_SERIALNO: - cw_itemstore_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_SERIALNO, + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_BOARD_SERIALNO, msgelem + i, sublen); - + break; case CW_BOARDDATA_MACADDRESS: - cw_itemstore_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_MACADDRESS, + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_BOARD_MACADDRESS, msgelem + i, sublen); - + break; case CW_BOARDDATA_BOARDID: cw_itemstore_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_ID, msgelem + i, sublen); break; case CW_BOARDDATA_REVISION: - cw_itemstore_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_REVISION, + cw_itemstore_set_bstrn(itemstore, + CW_ITEM_WTP_BOARD_REVISION, msgelem + i, sublen); default: break; @@ -86,22 +91,22 @@ static void readsubelems_wtp_board_data(cw_itemstore_t itemstore, uint8_t * msge /** * Parse a WTP Board Data messag element and put results to itemstore. - */ -int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len) + */ +int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, + int len, struct sockaddr *from) { if (len < 4) { cw_dbg(DBG_ELEM_ERR, - "Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d", a->elem_id, - len); + "Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d", + a->elem_id, len); return 0; } - cw_itemstore_t itemstore = conn->incomming; - cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data)); + cw_itemstore_t itemstore = conn->incomming; + cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR, cw_get_dword(data)); - readsubelems_wtp_board_data(itemstore,data+4,len-4); + readsubelems_wtp_board_data(itemstore, data + 4, len - 4); return 1; } - diff --git a/src/capwap/cw_in_wtp_descriptor.c b/src/capwap/cw_in_wtp_descriptor.c index 85e0d6c0..9d05ce43 100644 --- a/src/capwap/cw_in_wtp_descriptor.c +++ b/src/capwap/cw_in_wtp_descriptor.c @@ -28,40 +28,9 @@ #include "sock.h" -static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, - uint8_t * data, int len, int cq) +static int cw_read_wtp_descriptor_versions(cw_itemstore_t itemstore, uint8_t *data,int len) { - - if (len < 6) { - return 0; - } - - cw_itemstore_t itemstore = conn->incomming; - - cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_MAX_RADIOS, cw_get_byte(data)); - cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_RADIOS_IN_USE, - cw_get_byte(data + 1)); - - /* Get number encryption elements */ - int ncrypt = cw_get_byte(data + 2); - int i; - if (ncrypt == 0) { - - - - /* non-conform */ - cw_dbg(DBG_RFC, - "Non-standard-conform WTP descriptor detected (See RFC 5415)"); - if (!cq) - i = 3; - else - i = 4; - } else { - i = ncrypt * 3 + 3; - } - - - + int i=0; do { if (i + 8 > len) { cw_dbg(DBG_ELEM_ERR, @@ -70,9 +39,9 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, return 0; } - uint32_t vendor_id = cw_get_dword(data + i); //ntohl(*((uint32_t*)(msgelem+i))); - + uint32_t vendor_id = cw_get_dword(data + i); uint32_t val = cw_get_dword(data + i + 4); + int subtype = (val >> 16) & 0xffff; int sublen = val & 0xffff; i += 8; @@ -83,7 +52,19 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, return 0; } - cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d", subtype, sublen); + char *dmp; + char *dmpmem=NULL; + if (cw_dbg_is_level(DBG_SUBELEM_DMP)) { + dmpmem=cw_dbg_mkdmp(data+i,sublen); + dmp=dmpmem; + } + else + dmp=""; + cw_dbg(DBG_SUBELEM, "WTP Descriptor subtype=%d,len=%d%s", subtype, sublen,dmp); + + if (dmpmem) + free(dmpmem); + switch (subtype) { case CW_SUBELEM_WTP_HARDWARE_VERSION: @@ -121,11 +102,50 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, } while (i < len); return 1; + +} + +static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len) +{ + + if (len < 6) { + return 0; + } + + cw_itemstore_t itemstore = conn->incomming; + + cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_MAX_RADIOS, cw_get_byte(data)); + cw_itemstore_set_byte(itemstore, CW_ITEM_WTP_RADIOS_IN_USE, + cw_get_byte(data + 1)); + + + /* Get number of encryption elements */ + int ncrypt = cw_get_byte(data + 2); + if (ncrypt == 0) { + if (conn->strict_capwap){ + cw_dbg(DBG_ELEM_ERR,"Bad WTP Descriptor, number of encryption elements is 0."); + return 0; + } + cw_dbg(DBG_RFC,"Non standard conform WTP Descriptor, number of encryptoin elements is 0."); + } + + + int pos = 3; + int i; + for (i=0; icapwap_mode) { case CW_MODE_STD: { @@ -134,7 +154,7 @@ int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * da CW_MODE_STD); if (!rc) { cw_dbg(DBG_ELEM_ERR, "Bad WTP descriptor from %s", - sock_addr2str(&conn->addr)); + sock_addr2str(from)); return 0; } return 1; @@ -143,12 +163,15 @@ int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t * da } +*/ - int rc = readelem_wtp_descriptor(conn, a, data, len, 0); + int rc = readelem_wtp_descriptor(conn, a, data, len); + +/* if (rc == -1) { cw_dbg(DBG_RFC, "Bad WTP descriptor, trying cisco hack"); rc = readelem_wtp_descriptor(conn, a, data, len, 1); } - +*/ return rc; } diff --git a/src/capwap/dbg.c b/src/capwap/dbg.c index 952ce5cc..6dbe0a69 100644 --- a/src/capwap/dbg.c +++ b/src/capwap/dbg.c @@ -16,6 +16,11 @@ */ +/** + * @file + * @brief Various debug functions. + */ + #include "capwap.h" #include "dbg.h" #include "sock.h" @@ -37,7 +42,7 @@ uint32_t cw_dbg_opt_display = 0; uint32_t cw_dbg_opt_level = 0; - +#define DBG_CLR_MAGENTA "\x1b[35m" static struct cw_str color_on[] = { @@ -46,6 +51,10 @@ static struct cw_str color_on[] = { { DBG_ELEM, "\x1b[39m" }, { DBG_MSG_ERR, "\x1b[31m" }, { DBG_PKT_ERR, "\x1b[31m" }, + { DBG_ELEM_ERR, "\x1b[31m" }, + { DBG_SUBELEM, "\x1b[30m"}, + { DBG_DTLS, DBG_CLR_MAGENTA }, + { DBG_RFC, "\x1b[31m" }, { DBG_X, "\x1b[31m" }, { CW_STR_STOP, "" } @@ -69,7 +78,10 @@ static struct cw_str prefix[] = { { DBG_ELEM, " Msg Element -" }, { DBG_MSG_ERR," Msg Error -" }, { DBG_PKT_ERR," Pkt Error -" }, + { DBG_ELEM_ERR," Elem Error -" }, { DBG_RFC, " RFC Violation -" }, + { DBG_SUBELEM," Sub-Element - "}, + { DBG_DTLS, " DTLS - "}, { DBG_X, "XXXXX - "}, { CW_STR_STOP, "" } }; @@ -133,15 +145,15 @@ void cw_dbg_missing_mand(int level, struct conn *conn, cw_action_in_t ** ml, int cw_dbg(level, "Missing mandatory elements: [%s]", buffer); } -int cw_format_pkt(char *dst,int level,struct conn *conn, uint8_t * packet, int len) +int cw_format_pkt(char *dst,int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from) { char *s=dst; switch (level) { case DBG_PKT_IN: - s+=sprintf(s,"From %s",sock_addr2str(&conn->addr)); + s+=sprintf(s,"From %s",sock_addr2str(from)); break; case DBG_PKT_OUT: - s+=sprintf(s,"To %s",sock_addr2str(&conn->addr)); + s+=sprintf(s,"To %s",sock_addr2str(from)); break; } s+=sprintf(s," l=%d: ",len); @@ -201,8 +213,14 @@ abort: } - -char * make_dmp( const uint8_t * data, int len) +/** + * Create an ASCII hex dump of binary data + * + * @param data data to dump + * @len number of bytes data contains + * @return a character string with the created data ASCII dump ( must be release with free) + */ +char * cw_dbg_mkdmp( const uint8_t * data, int len) { int maxtlen = 2048; @@ -222,21 +240,11 @@ char * make_dmp( const uint8_t * data, int len) char *dst = malloc(2*(md * (len * 3 + (rows * 2) + 8 + maxtlen))); if (!dst) return NULL; -/* - if (format != NULL) { - va_list args; - va_start(args, format); - tlen = vsnprintf(dst, maxtlen, format, args); - va_end(args); - } -*/ - if (len % CW_LOG_DUMP_ROW_LEN) rows++; - char *pdst = dst + tlen; sprintf(pdst, "\n\t"); pdst += 2; @@ -278,10 +286,6 @@ char * make_dmp( const uint8_t * data, int len) } - - -// cw_log_cb(LOG_DEBUG, "%s",dst); - return dst; } @@ -303,16 +307,16 @@ char * make_dmp( const uint8_t * data, int len) -void cw_dbg_pkt(int level,struct conn *conn, uint8_t * packet, int len) +void cw_dbg_pkt(int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from) { if (!cw_dbg_is_level(level)) return; char buf[1024]; - cw_format_pkt(buf,level,conn,packet,len); + cw_format_pkt(buf,level,conn,packet,len,from); if (cw_dbg_is_level(DBG_PKT_DMP)){ - char *dmp = make_dmp(packet,len); + char *dmp = cw_dbg_mkdmp(packet,len); cw_dbg(level,"%s%s",buf,dmp); free(dmp); } @@ -321,7 +325,7 @@ void cw_dbg_pkt(int level,struct conn *conn, uint8_t * packet, int len) } -void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len) +void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from) { if (!cw_dbg_is_level(level)) return; @@ -336,7 +340,7 @@ void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len) int msg_id=cw_get_msg_id(msgptr); s+=sprintf(s,"%s Message (type=%d) ",cw_strmsg(msg_id),msg_id); - s+=sprintf(s,"from %s ",sock_addr2str(&conn->addr)); + s+=sprintf(s,"from %s ",sock_addr2str(from)); s+=sprintf(s,", Seqnum: %d ElemLen: %d",cw_get_msg_seqnum(msgptr),cw_get_msg_elems_len(msgptr)); //abort: @@ -536,7 +540,7 @@ void cw_dbg_elem_colored(int level, struct conn *conn, int msg, int msgelem, msgelem, elemname, len); else{ - char *dmp = make_dmp(msgbuf,len); + char *dmp = cw_dbg_mkdmp(msgbuf,len); cw_dbg(DBG_ELEM, "%d (%s), len=%d%s%s", msgelem, diff --git a/src/capwap/dbg.h b/src/capwap/dbg.h index c7f8fbeb..a746333d 100644 --- a/src/capwap/dbg.h +++ b/src/capwap/dbg.h @@ -1,3 +1,27 @@ +/* + This file is part of libcapwap. + + libcapwap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libcapwap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + +*/ + +/** + * @file + * @brief + */ + + #ifndef __DBG_H #define __DBG_H @@ -74,18 +98,28 @@ enum debug_levels{ /** Show subelements */ DBG_SUBELEM, + /** Show subelements */ + DBG_SUBELEM_DMP, + /** hex dump elements */ DBG_ELEM_DMP, /** General infos, like CAPWAP state */ DBG_INFO, + /** Misc. warnings */ + DBG_WARN, + /** RFC related */ DBG_RFC, + /** DTLS related messages */ DBG_DTLS, - DBG_DTLS_DETAIL, + + /** DTLS BIOs in/out */ DBG_DTLS_BIO, + + /** Dump DTLS BIO i/o */ DBG_DTLS_BIO_DMP, DBG_X @@ -136,8 +170,10 @@ void cw_dbg_dmp_(int level, const char *file, int line, extern void cw_dbg_elem_colored(int level, struct conn *conn, int msg, int msgelem, const uint8_t * msgbuf, int len); -void cw_dbg_pkt(int level,struct conn *conn, uint8_t * packet, int len); -void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len); +void cw_dbg_pkt(int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from); +void cw_dbg_msg(int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from); +char * cw_dbg_mkdmp(const uint8_t * data, int len); + #define cw_dbg_set_level(level,on)\ diff --git a/src/capwap/dbg_strings.c b/src/capwap/dbg_strings.c index 6a0ef620..0b146ad3 100644 --- a/src/capwap/dbg_strings.c +++ b/src/capwap/dbg_strings.c @@ -29,12 +29,15 @@ struct cw_str cw_dbg_strings[] = { { DBG_PKT_ERR, "pkt_err" }, { DBG_PKT_DMP, "pkt_dmp" }, { DBG_RFC, "rfc" }, - + { DBG_SUBELEM, "subelem" }, + { DBG_SUBELEM_DMP, "subelem_dmp" }, { DBG_MSG_IN, "msg_in" }, { DBG_MSG_ERR, "msg_err" }, { DBG_ELEM, "elem" }, { DBG_ELEM_DMP, "elem_dmp" }, { DBG_ELEM_ERR, "elem_err" }, + { DBG_DTLS, "dtls" }, + { DBG_DTLS_BIO, "dtls_bio" }, { DBG_X,"dbgx" }, { CW_STR_STOP, NULL } diff --git a/src/capwap/dtls_gnutls_accept.c b/src/capwap/dtls_gnutls_accept.c index 146c838a..041bb7d5 100644 --- a/src/capwap/dtls_gnutls_accept.c +++ b/src/capwap/dtls_gnutls_accept.c @@ -40,7 +40,7 @@ int dtls_gnutls_accept(struct conn *conn) gnutls_datum_t cookie_key; gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE); - cw_dbg(DBG_DTLS, "DTLS session cookie for %s generated: %s", + cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s", sock_addr2str(&conn->addr), sock_hwaddr2idstr((uint8_t *) (&cookie_key), sizeof(cookie_key))); @@ -75,7 +75,7 @@ int dtls_gnutls_accept(struct conn *conn) &conn->addr, sizeof(conn->addr), buffer+4, tlen-4, &prestate); if (rc<0){ - cw_dbg(DBG_DTLS, "DTLS - Cookie couldn't be verified: %s", gnutls_strerror(rc)); + cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s", gnutls_strerror(rc)); dtls_gnutls_bio_read(conn, buffer, sizeof(buffer)); continue; } @@ -86,12 +86,13 @@ int dtls_gnutls_accept(struct conn *conn) } if (rc <0 ){ - cw_log(LOG_ERR, "DTLS - Cookie couldn't be verified: %s", gnutls_strerror(rc)); + cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc)); return 0; } - cw_dbg(DBG_DTLS, "DTLS - Cookie verified! Starting handshake ..."); + cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",sock_addr2str(&conn->addr)); + d = dtls_gnutls_data_create(conn,GNUTLS_SERVER | GNUTLS_DATAGRAM); @@ -109,12 +110,12 @@ int dtls_gnutls_accept(struct conn *conn) if ( rc < 0 ) { - cw_log(LOG_ERR, "DTLS - Error in handshake: %s", gnutls_strerror(rc)); + cw_log(LOG_ERR, "Error in handshake with %s: %s",sock_addr2str(&conn->addr), gnutls_strerror(rc)); return 0; } - cw_dbg(DBG_DTLS,"DTLS - Handshake successful"); + cw_dbg(DBG_DTLS,"Handshake with %s successful.",sock_addr2str(&conn->addr)); conn->dtls_data=d; conn->read = dtls_gnutls_read; diff --git a/src/capwap/dtls_openssl.c b/src/capwap/dtls_openssl.c index 42358f68..f6776d46 100644 --- a/src/capwap/dtls_openssl.c +++ b/src/capwap/dtls_openssl.c @@ -65,7 +65,7 @@ static void dtls_debug_cb(int write_p,int version,int type, const void * buf,siz s += sprintf(s,"SSL msg in: "); s+=sprintf(s,"type = %d (0x%02X), %s (%08x), len = %d",type,type,ssl_version2str(version),version,(int)len); - cw_dbg(DBG_DTLS_DETAIL,buffer); +// cw_dbg(DBG_DTLS_DETAIL,buffer); } #endif diff --git a/src/capwap/sock_receive.c b/src/capwap/sock_receive.c index 6819768c..fc75d8e9 100644 --- a/src/capwap/sock_receive.c +++ b/src/capwap/sock_receive.c @@ -23,34 +23,37 @@ #include "sock.h" -int sock_receive(int sock,void *buf, size_t len, int flags, struct sockaddr * srcaddr,socklen_t *addrlen) +int +sock_receive (int sock, void *buf, size_t len, int flags, + struct sockaddr *srcaddr, socklen_t * addrlen) { - //unsigned int al; - socklen_t al; + //unsigned int al; + socklen_t al; - al = sizeof (struct sockaddr_storage); - - memset(srcaddr, 0, sizeof(struct sockaddr)); -// srcaddr->sa_port=999; + al = sizeof (struct sockaddr_storage); - int n; - while( (n = recvfrom(sock,(char*)buf,len,flags,srcaddr,&al)) < 0 ){ - if (errno!=EINTR) - return n ; - } -// printf("Received betes %d\n",n); -// char str[8000]; -// sock_addrtostr(srcaddr,str,1000); -// printf("RECFROM: %s\n",str); + memset (srcaddr, 0, sizeof (struct sockaddr)); +// srcaddr->sa_port=999; -// struct sockaddr_in * s = (struct sockaddr_in*)srcaddr; -// s->sin_port=htons(78); -// sock_addrtostr(srcaddr,str,1000); -// printf("RECFROMset: %s\n",str); - - - -// exit(9); + int n; + while ((n = recvfrom (sock, (char *) buf, len, flags, srcaddr, &al)) < 0) + { + if (errno != EINTR) return n; + } +// printf("Received betes %d\n",n); +// char str[8000]; +// sock_addrtostr(srcaddr,str,1000); +// printf("RECFROM: %s\n",str); + +// struct sockaddr_in * s = (struct sockaddr_in*)srcaddr; +// s->sin_port=htons(78); +// sock_addrtostr(srcaddr,str,1000); +// printf("RECFROMset: %s\n",str); + + + +// exit(9); + return n; } diff --git a/src/wtp/discovery.c b/src/wtp/discovery.c index d09e9f67..511a3c5a 100644 --- a/src/wtp/discovery.c +++ b/src/wtp/discovery.c @@ -119,7 +119,7 @@ static int run_discovery(struct conn *conn) && conn->capwap_state == CW_STATE_DISCOVERY) { avltree_del_all(conn->incomming); - int rc = cw_read_messages(conn); + int rc = cw_read_from(conn); if (rc<0) { if (errno==EAGAIN) @@ -199,9 +199,11 @@ static int cw_run_discovery(struct conn *conn, const char *acaddr) sock_copyaddr(&conn->addr, res->ai_addr); conn->sock = sockfd; + conn->readfrom = conn_recvfrom_packet; run_discovery(conn); + conn->readfrom=NULL; close(sockfd);