Does a lot more error checking and debug info.
Also a malformed message could trigger a core dump which is now fixed. FossilOrigin-Name: 6757da0ee3243d5077210acea2e202fb5e63ad6390dff579089ebf97c8b6eed5
This commit is contained in:
parent
b9d772ee6a
commit
6ec66c7511
@ -22,32 +22,52 @@
|
||||
|
||||
#include "capwap.h"
|
||||
#include "cw_log.h"
|
||||
#include "cw_util.h"
|
||||
|
||||
#include "conn.h"
|
||||
#include "sock.h"
|
||||
|
||||
#include <stdio.h> //tube
|
||||
|
||||
static int cwrmsg_init_ctrlhdr(struct cwrmsg * cwrmsg, uint8_t * msg, int len)
|
||||
static int cwrmsg_init_ctrlhdr(struct conn * conn, struct cwrmsg * cwrmsg, uint8_t * msg, int len)
|
||||
{
|
||||
if (len<8)
|
||||
if (len<8){
|
||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, len=%d (too short)",sock_addr2str(&conn->addr),len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t val;
|
||||
val = ntohl(*((uint32_t*)(msg+0)));
|
||||
|
||||
|
||||
/* first dword of header is the message type*/
|
||||
cwrmsg->type = ntohl(*((uint32_t*)(msg)));
|
||||
|
||||
|
||||
/* second dword = seqnum, len and flags */
|
||||
val = ntohl(*((uint32_t*)(msg+4)));
|
||||
cwrmsg->seqnum = CW_GET_DWORD_BITS(val,0,8);
|
||||
cwrmsg->msgelems_len=CW_GET_DWORD_BITS(val,8,16)-3;
|
||||
|
||||
cwrmsg->seqnum = cw_get_dword_bits(val,0,8);
|
||||
|
||||
cwrmsg->msgelems_len=cw_get_dword_bits(val,8,16)-3;
|
||||
|
||||
// ch->flags=CW_GET_DWORD_BITS(val,24,8);
|
||||
cwrmsg->msgelems=msg+8;
|
||||
|
||||
if (8+cwrmsg->msgelems_len != len){
|
||||
return 0;
|
||||
}
|
||||
if (conn_is_strict_capwap(conn)){
|
||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, msgelems len=%d, data len=%d, (strict capwap) ",
|
||||
sock_addr2str(&conn->addr),cwrmsg->msgelems_len,len-8);
|
||||
return 0;
|
||||
}
|
||||
if (8+cwrmsg->msgelems_len < len){
|
||||
cw_dbg(DBG_CW_RFC,"Packet from from %s has %d bytes extra data, ignoring.",
|
||||
sock_addr2str(&conn->addr),len-8-cwrmsg->msgelems_len);
|
||||
}
|
||||
|
||||
if (8+cwrmsg->msgelems_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),cwrmsg->msgelems_len,len-8);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
@ -87,26 +107,58 @@ 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",
|
||||
sock_addr2str(&conn->addr),s2);
|
||||
cw_dbg(DBG_CW_MSG_ERR,"Retransmitted request message from %s detected, seqnum=%d, type=%d",
|
||||
sock_addr2str(&conn->addr),s2,cwrmsg->type);
|
||||
|
||||
if (!conn->last_response){
|
||||
cw_dbg(DBG_CW_MSG_ERR,"No cached response for retransmission, request seqnum=%d",s2);
|
||||
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 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
cw_dbg(DBG_CW_MSG_ERR,"Retransmitting response message to %s, seqnum=%d",
|
||||
sock_addr2str(&conn->addr),s2);
|
||||
conn_send_cwmsg(conn,conn->last_response);
|
||||
conn_send_cwmsg(conn,&conn->resp_msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_CW_LOG_DEBUG
|
||||
|
||||
static void cw_dbg_packet(struct conn * conn, uint8_t * packet, int len)
|
||||
{
|
||||
if (!cw_dbg_is_level(DBG_CW_PKT))
|
||||
return;
|
||||
|
||||
/* print the header */
|
||||
char hdr[200];
|
||||
hdr_print(hdr,packet,len);
|
||||
|
||||
|
||||
if (!cw_dbg_is_level(DBG_CW_PKT_DMP)){
|
||||
cw_dbg(DBG_CW_PKT,"Processing capwap packet from %s, len=%d\n%s",sock_addr2str(&conn->addr),len,hdr);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
cw_dbg_dmp(DBG_CW_PKT_DMP,packet,len,"Processing packet from %s, len=%d\n%s\n\tDump:",
|
||||
sock_addr2str(&conn->addr),len,hdr
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#define cw_dbg_packet(...)
|
||||
#endif
|
||||
|
||||
|
||||
void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(void*,struct cwrmsg*),void *cbarg)
|
||||
{
|
||||
|
||||
cw_dbg(DBG_CW_PKT_DTL,"Processing packet from %s, len=%d",sock_addr2str(&conn->addr),len);
|
||||
cw_dbg_packet(conn,packet,len);
|
||||
|
||||
|
||||
|
||||
|
||||
if (len<8){
|
||||
/* packet too short */
|
||||
@ -119,7 +171,7 @@ void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(
|
||||
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);
|
||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, wrong version, version=%d",sock_addr2str(&conn->addr),(preamble&0xf0)>>8);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -167,13 +219,19 @@ void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(
|
||||
if (f==NULL)
|
||||
return;
|
||||
|
||||
cwrmsg_init_ctrlhdr(&cwrmsg,f+4,*(uint32_t*)f);
|
||||
if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,f+4,*(uint32_t*)f)){
|
||||
free(f);
|
||||
return;
|
||||
};
|
||||
process_message(conn,&cwrmsg,cb,cbarg);
|
||||
free (f);
|
||||
return;
|
||||
}
|
||||
|
||||
cwrmsg_init_ctrlhdr(&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;
|
||||
}
|
||||
|
||||
process_message(conn,&cwrmsg,cb,cbarg);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user