Digging deepter into VM concepts...

FossilOrigin-Name: ba6454642f17c0f87106cb6af12689457433d44ba1fe2dd1ef920dba7be2ef27
This commit is contained in:
7u83@mail.ru 2015-03-31 06:04:03 +00:00
parent 97a8506278
commit 0d9a3ad8c7
26 changed files with 370 additions and 175 deletions

View File

@ -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}

View File

@ -355,16 +355,33 @@ 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 )
@ -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);
}

View File

@ -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 \

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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)
/**@}*/

View File

@ -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},

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}