diff --git a/actube.workspace b/actube.workspace index b21adfd1..07586c53 100644 --- a/actube.workspace +++ b/actube.workspace @@ -1,7 +1,7 @@ - - + + diff --git a/libcw.project b/libcw.project index 0ce1b7ef..0ac0a825 100644 --- a/libcw.project +++ b/libcw.project @@ -265,6 +265,8 @@ + + diff --git a/src/cw/Makefile b/src/cw/Makefile index 5e5de050..390674d6 100644 --- a/src/cw/Makefile +++ b/src/cw/Makefile @@ -89,6 +89,7 @@ CWSRC=\ cw_put_msg.c\ cw_radio_set_admin_state.c\ cw_rand.c\ + cw_randint.c\ cw_read_ac_descriptor.c\ cw_read_descriptor_subelems.c\ cw_readelem_statistics_timer.c\ @@ -186,6 +187,7 @@ SOCKSRC=\ LOGSRC=\ log.c\ log_file.c\ + log_errno.c\ log_syslog.c\ dbg.c\ dbg_strings.c\ diff --git a/src/cw/capwap.h b/src/cw/capwap.h index 927ff100..0e6e4a52 100644 --- a/src/cw/capwap.h +++ b/src/cw/capwap.h @@ -349,8 +349,10 @@ /* capwap timer default values */ -#define CW_DISCOVERY_INTERVAL 5 -#define CW_MAX_DISCOVERY_INTERVAL 20 +#define CAPWAP_DISCOVERY_INTERVAL 5 +#define CAPWAP_MAX_DISCOVERY_INTERVAL 20 +#define CAPWAP_MIN_DISCOVERY_INTERVAL 2 + #define CAPWAP_RETRANSMIT_INTERVAL 3 #define CAPWAP_MAX_DISCOVERIES 10 #define CAPWAP_MAX_RETRANSMIT 5 diff --git a/src/cw/cw_randint.c b/src/cw/cw_randint.c new file mode 100644 index 00000000..d4b0197b --- /dev/null +++ b/src/cw/cw_randint.c @@ -0,0 +1,25 @@ + +#include + + +#include "rand.h" + +/** + * @brief Get e random integer in a specific range. + * @param min minimum value + * @param max maximum value + * @return The random number, which is greater or equal to min and + * less than max. + */ +uint16_t cw_randint(int min,int max) +{ + uint16_t randval; + uint32_t diff; + + diff = max-min; + + cw_rand((uint8_t*)(&randval),sizeof(randval)); + + + return min+diff * randval / 0xffff; +} \ No newline at end of file diff --git a/src/cw/log.h b/src/cw/log.h index f062746d..b81e27cd 100644 --- a/src/cw/log.h +++ b/src/cw/log.h @@ -52,6 +52,7 @@ extern struct cw_LogWriter cw_log_console_writer; void cw_log_init(); void cw_log(int level, const char *format, ...); +void cw_log_errno(char * format, ...); extern const char *cw_log_name; extern struct cw_LogWriter * cw_log_writers[]; diff --git a/src/cw/log_errno.c b/src/cw/log_errno.c new file mode 100644 index 00000000..62917a93 --- /dev/null +++ b/src/cw/log_errno.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +#include "log.h" + +void cw_log_errno(char * format, ...) +{ + char str[2048]; + int err=errno; + + va_list args; + va_start(args,format); + vsprintf(str,format,args); + va_end(args); + + cw_log(LOG_ERR,"%s: %s",str,strerror(err)); + +} diff --git a/src/cw/mod.h b/src/cw/mod.h index 4aff722b..bf67fb07 100644 --- a/src/cw/mod.h +++ b/src/cw/mod.h @@ -74,6 +74,8 @@ struct cw_Mod { /** used for private data */ void *data; + + int (*setup_cfg)(struct conn *conn); }; diff --git a/src/cw/rand.h b/src/cw/rand.h index 6785e003..f2b93d36 100644 --- a/src/cw/rand.h +++ b/src/cw/rand.h @@ -1,7 +1,10 @@ #ifndef __CW_RAND_H #define __CW_RAND_H -extern int cw_rand(uint8_t*dst, int len); +#include + +int cw_rand(uint8_t*dst, int len); +uint16_t cw_randint(int min,int max); #endif diff --git a/src/cw/timer.h b/src/cw/timer.h index 3eb8b2ad..d8c2d21f 100644 --- a/src/cw/timer.h +++ b/src/cw/timer.h @@ -74,12 +74,18 @@ typedef time_t cw_timer_t; * and #cw_clock_lap. * @param c name of the variable * - * Example: - * @code + * Example + * @code{.c} + * #include "cw/timer.h" + * * CW_CLOCK_DEFINE(clk); + * int t; + * * cw_clock_start(clk); + * * @startcomment do something ... @endcomment - * int t = cw_clock_lap(clk); + * + * t = cw_clock_lap(clk); * printf("Caclulation took %d seconds\n",t); * @endcode * diff --git a/src/mod/capwap/mod_capwap_ac.c b/src/mod/capwap/mod_capwap_ac.c index 7d789c02..8ebcf113 100644 --- a/src/mod/capwap/mod_capwap_ac.c +++ b/src/mod/capwap/mod_capwap_ac.c @@ -11,6 +11,11 @@ static int init(struct cw_Mod * mod, mavl_t global_cfg, int role) { cw_dbg(DBG_INFO,"CAPWAP: Inititalizing mod_capwap."); + + + + + switch (role){ case CW_ROLE_AC:{ cw_dbg(DBG_MOD, "CAPWAP: Initialiazing mod_capwap in AC mode"); @@ -42,6 +47,14 @@ static int detect(struct conn *conn, const uint8_t * rawmsg, int rawlen, int ele return 1; } +int static setup_cfg(struct conn * conn) +{ + + + return 0; + +} + struct cw_Mod mod_capwap = { "capwap", /* name */ @@ -49,12 +62,6 @@ struct cw_Mod mod_capwap = { detect, /* detect */ capwap_register_msg_set, /* register_messages */ NULL, /* dll_handle */ - NULL /* data */ + NULL, /* data */ + setup_cfg /* setup_cfg */ }; - - -/* -struct cw_Mod * mod_capwap(){ - return &capwap_data; -} -*/ \ No newline at end of file diff --git a/src/wtp/config.ktv b/src/wtp/config.ktv index 596dc925..050f7735 100644 --- a/src/wtp/config.ktv +++ b/src/wtp/config.ktv @@ -1,5 +1,3 @@ -capwap/vars/MaxDiscoveries:Word:10 -capwap/vars/MaxRetransmit:Word:4 windows:Word:124 @@ -39,4 +37,10 @@ ac-name-with-priority/TubesACx:Byte:3 ac-name-with-priority/"ac2":Byte:01 +capwap-timers/max-discovery-interval:Byte:0 +capwap-timers/min-discovery-interval:Byte:0 +capwap-timers/echo-interval:Byte:3 + +"discovery-interval":Byte:1 + diff --git a/src/wtp/discovery.c b/src/wtp/discovery.c index 45b33d06..33e817f6 100644 --- a/src/wtp/discovery.c +++ b/src/wtp/discovery.c @@ -12,160 +12,150 @@ #include "cw/dbg.h" #include "cw/timer.h" #include "cw/cw.h" +#include "cw/rand.h" #include "wtp.h" -int cw_select_ac(mavl_t local_cfg,mlist_t aclist){ - mlistelem_t * e; +mavl_t cw_select_ac(mavl_t local_cfg, mlist_t aclist) +{ + mlistelem_t *e; mavl_t iplist; int en; - - iplist=cw_ktv_create(); + + iplist = cw_ktv_create(); if (iplist == NULL) return 0; - en=0; + en = 0; /* for each discovery response */ - mlist_foreach(e,aclist){ - char acname[CAPWAP_MAX_AC_NAME_LEN+1]; + mlist_foreach(e, aclist) { + char acname[CAPWAP_MAX_AC_NAME_LEN + 1]; char key[CW_KTV_MAX_KEY_LEN]; mavl_t remote_cfg; - cw_KTV_t * val, *ipval; - int prio,i; - + cw_KTV_t *val, *ipval; + int prio, i; + remote_cfg = mlistelem_get_ptr(e); - + /* get ac name */ - val = cw_ktv_get(remote_cfg,"ac-name", CW_TYPE_BSTR16); - if (val==NULL){ + val = cw_ktv_get(remote_cfg, "ac-name", CW_TYPE_BSTR16); + if (val == NULL) { /* this should not happen, because AC Name is a * amndatory message element */ - prio=255; - } - else{ + prio = 255; + } else { /* Get priority for AC from * ac-name-with-priority list */ - val->type->to_str(val,acname,CAPWAP_MAX_AC_NAME_LEN); - sprintf(key,"ac-name-with-priority/%s",acname); - prio = cw_ktv_get_byte(local_cfg,key,255); + val->type->to_str(val, acname, CAPWAP_MAX_AC_NAME_LEN); + sprintf(key, "ac-name-with-priority/%s", acname); + prio = cw_ktv_get_byte(local_cfg, key, 255); } - + /* for each control ip address the AC has sent */ - i=0; + i = 0; do { - sprintf(key,"%s.%d","capwap-control-ip-address/wtps",i); - val = cw_ktv_get(remote_cfg,key,CW_TYPE_WORD); + sprintf(key, "%s.%d", "capwap-control-ip-address/wtps", i); + val = cw_ktv_get(remote_cfg, key, CW_TYPE_WORD); if (val == NULL) break; - - - sprintf(key,"%s.%d","capwap-control-ip-address/address",i); - ipval = cw_ktv_get(remote_cfg,key,CW_TYPE_IPADDRESS); - sprintf(key,"%04d%05d%04d",prio,val->val.word,en); - cw_ktv_add(iplist,key,CW_TYPE_SYSPTR,(uint8_t*)(&ipval),sizeof(ipval)); + sprintf(key, "%s.%d", "capwap-control-ip-address/address", i); + ipval = cw_ktv_get(remote_cfg, key, CW_TYPE_IPADDRESS); + + sprintf(key, "%04d%05d%04d", prio, val->val.word, en); + + cw_ktv_add(iplist, key, CW_TYPE_SYSPTR, (uint8_t *) (&ipval), + sizeof(ipval)); i++; en++; - }while(1); - + } while (1); + } - - cw_dbg_ktv_dump(iplist,DBG_INFO,"=== IP list ===", "IP", "=== END IP List ==="); + + cw_dbg_ktv_dump(iplist, DBG_INFO, "=== IP list ===", "IP", "=== END IP List ==="); { mavliter_t i; - mavliter_init(&i,iplist); - - mavliter_foreach(&i){ + mavliter_init(&i, iplist); + + mavliter_foreach(&i) { char ipstr[100]; char *rk; - cw_KTV_t * val; + cw_KTV_t *val; val = mavliter_get(&i); rk = val->key; val = val->val.ptr; - val->type->to_str(val,ipstr,100); - printf("PTRVAL(%s): %s - %s\n",rk,val->key,ipstr); + val->type->to_str(val, ipstr, 100); + printf("PTRVAL(%s): %s - %s\n", rk, val->key, ipstr); } } - + return 0; } static int run_discovery(struct conn *conn) { -/*// conn->incomming = mbag_create();*/ time_t timer; -/* uint8_t dtype=0;*/ mlist_t discovery_results; struct sockaddr_storage from; + int delay, min, max; + + min = cw_ktv_get_byte(conn->local_cfg,"capwap-timers/min-discovery-interval", + CAPWAP_MIN_DISCOVERY_INTERVAL); + max = cw_ktv_get_byte(conn->local_cfg,"capwap-timers/max-discovery-interval", + CAPWAP_MAX_DISCOVERY_INTERVAL); + + delay = cw_randint(min,max); + if (delay>0){ + cw_dbg(DBG_INFO,"Sleeping for %d seconds before sending Discovery Request.", delay); + sleep(delay); + } + + conn->capwap_state = CAPWAP_STATE_DISCOVERY; - - - /*cw_ktv_add(conn->local_cfg, "discovery-type", CW_TYPE_BYTE, &dtype,17);*/ + /* create and send a discovery request message */ cw_init_request(conn, CAPWAP_MSG_DISCOVERY_REQUEST); cw_put_msg(conn, conn->req_buffer); conn_send_msg(conn, conn->req_buffer); - timer = cw_timer_start(0); + timer = cw_timer_start(cw_ktv_get_byte(conn->local_cfg, "discovery-interval", + CAPWAP_DISCOVERY_INTERVAL))-1; - - discovery_results = mlist_create(NULL,NULL,sizeof(void*)); + discovery_results = mlist_create(NULL, NULL, sizeof(void *)); while (!cw_timer_timeout(timer) && conn->capwap_state == CAPWAP_STATE_DISCOVERY) { int rc; char addr_str[SOCK_ADDR_BUFSIZE]; - /*mavl_del_all(conn->incomming);*/ - rc = cw_read_from(conn, &from); - if (rc<0) { - if (errno==EAGAIN) - continue; - - cw_log(LOG_ERROR,"Error reading messages: %s",strerror(errno)); + conn->remote_cfg = cw_ktv_create(); + if (conn->remote_cfg == NULL) { + cw_log_errno("Can't allocate memory for remote_cfg"); break; } - cw_dbg(DBG_INFO,"Received Discovery Response from %s", sock_addr2str(&from,addr_str)); - mlist_append_ptr(discovery_results,conn->remote_cfg); - conn->remote_cfg=cw_ktv_create(); + + rc = cw_read_from(conn, &from); + if (rc < 0) { + if (errno == EAGAIN) + continue; + + cw_log(LOG_ERROR, "Error reading messages: %s", strerror(errno)); + break; + } + cw_dbg(DBG_INFO, "Received Discovery Response from %s", + sock_addr2str(&from, addr_str)); + mlist_append_ptr(discovery_results, conn->remote_cfg); } - cw_select_ac(conn->local_cfg,discovery_results); - - -/* - mbag_t discs; - discs = mbag_get_mavl(conn->remote, CW_ITEM_DISCOVERIES); - - - if (!discs) { - cw_log(LOG_ERR,"No discovery responses received"); - return 0; - } - - int i; - - cw_aciplist_t list = cw_select_ac(conn, discs); + cw_select_ac(conn->local_cfg, discovery_results); - DEFINE_AVLITER(ii,list); - avliter_foreach(&ii){ - cw_acip_t * ip = avliter_get(&ii); - - } - - - - mavl_del_all(conn->remote); - - mbag_set_mavl(conn->local,CW_ITEM_CAPWAP_CONTROL_IP_ADDRESS_LIST,list); -*/ return 1; } @@ -177,50 +167,48 @@ int cw_run_discovery(struct conn *conn, const char *addr, const char *bindaddr) char sock_buf[SOCK_ADDR_BUFSIZE]; struct sockaddr_storage dstaddr; char caddr[256], control_port[64]; - + int rc; - + /* get addr of destination */ struct addrinfo hints; struct addrinfo *res, *res0; - - + + memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_family = AF_UNSPEC; - - + + strncpy(caddr, addr, sizeof(caddr)); - + /* try to convert the given address string to sockaddr */ - rc = sock_strtoaddr(caddr,(struct sockaddr*)&dstaddr); + rc = sock_strtoaddr(caddr, (struct sockaddr *) &dstaddr); if (rc) { int iport; - /* converting to socaddr was successful */ - iport = sock_getport((struct sockaddr*)&dstaddr); + /* converting to socaddr was successful */ + iport = sock_getport((struct sockaddr *) &dstaddr); if (iport != 0) sprintf(control_port, "%d", iport); else - sprintf(control_port,"%d", CAPWAP_CONTROL_PORT); - } - else{ - char * port; + sprintf(control_port, "%d", CAPWAP_CONTROL_PORT); + } else { + char *port; /* converting went wrong, so the address string might * be a DNS entry. Look for a colon to find the port. */ - port = strchr(addr,':'); - if (port){ - strncpy(control_port,port+1,sizeof(control_port)); - caddr[port-addr]=0; - } - else{ - sprintf(control_port,"%d", CAPWAP_CONTROL_PORT); + port = strchr(addr, ':'); + if (port) { + strncpy(control_port, port + 1, sizeof(control_port)); + caddr[port - addr] = 0; + } else { + sprintf(control_port, "%d", CAPWAP_CONTROL_PORT); } } - - /*printf("Addr: %s, Port: %s\n",caddr,control_port);*/ + + /*printf("Addr: %s, Port: %s\n",caddr,control_port); */ rc = getaddrinfo(caddr, control_port, &hints, &res0); if (rc) { @@ -248,29 +236,31 @@ int cw_run_discovery(struct conn *conn, const char *addr, const char *bindaddr) sock_copyaddr(&conn->addr, res->ai_addr); - - if (bindaddr){ + + if (bindaddr) { int brc; - + struct sockaddr bind_address; - sock_strtoaddr(bindaddr,&bind_address); - brc = bind(sockfd,&bind_address,sock_addrlen(&bind_address)); - if (brc<0) { - cw_log(LOG_ERR,"Can't bind to %s",sock_addr2str(&bind_address,sock_buf)); + sock_strtoaddr(bindaddr, &bind_address); + brc = bind(sockfd, &bind_address, sock_addrlen(&bind_address)); + if (brc < 0) { + cw_log(LOG_ERR, "Can't bind to %s", + sock_addr2str(&bind_address, sock_buf)); return 0; } } - + conn->sock = sockfd; conn->readfrom = conn_recvfrom_packet; - - cw_dbg(DBG_INFO,"Discovery to %s", sock_addr2str_p(&conn->addr,sock_buf)); + + cw_dbg(DBG_INFO, "Discovery to %s", + sock_addr2str_p(&conn->addr, sock_buf)); run_discovery(conn); - conn->readfrom=NULL; + conn->readfrom = NULL; close(sockfd); @@ -280,6 +270,3 @@ int cw_run_discovery(struct conn *conn, const char *addr, const char *bindaddr) return 0; } - - - diff --git a/src/wtp/wtp_conf.h b/src/wtp/wtp_conf.h index f6c6f63e..c27d4d50 100644 --- a/src/wtp/wtp_conf.h +++ b/src/wtp/wtp_conf.h @@ -93,7 +93,7 @@ extern uint8_t conf_macaddress_len; #ifndef CONF_DEFAULT_MAX_DISCOVERY_INTERVAL - #define CONF_DEFAULT_MAX_DISCOVERY_INTERVAL CW_MAX_DISCOVERY_INTERVAL + #define CONF_DEFAULT_MAX_DISCOVERY_INTERVAL CAPWAP_MAX_DISCOVERY_INTERVAL #endif #ifndef CONF_DEFAULT_SILENT_INTERVAL @@ -101,7 +101,7 @@ extern uint8_t conf_macaddress_len; #endif #ifndef CONF_DEFAULT_DISCOVERY_INTERVAL - #define CONF_DEFAULT_DISCOVERY_INTERVAL CW_DISCOVERY_INTERVAL + #define CONF_DEFAULT_DISCOVERY_INTERVAL CAPWAP_DISCOVERY_INTERVAL #endif #ifndef CONF_DEFAULT_MAX_DISCOVERIES diff --git a/src/wtp/wtp_main.c b/src/wtp/wtp_main.c index de87d52a..5f1cf759 100644 --- a/src/wtp/wtp_main.c +++ b/src/wtp/wtp_main.c @@ -13,8 +13,9 @@ #include "wtp.h" +#define MAX_MODS 32 struct bootcfg{ - const char * modnames[32]; + const char * modnames[MAX_MODS]; int nmods; const char * modpath; const char * cfgfilename; @@ -43,6 +44,10 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg) break; } case 'm': + if (bootcfg->nmods>MAX_MODS){ + fprintf(stderr,"Too many modules\n"); + exit(EXIT_FAILURE); + } bootcfg->modnames[bootcfg->nmods++] = optarg; break; case 'p': @@ -63,7 +68,7 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg) return 0; } - +#include "cw/rand.h" int main (int argc, char **argv) { @@ -75,7 +80,8 @@ int main (int argc, char **argv) mavl_t global_cfg, types_tree; const cw_Type_t ** ti; int i; - + + bootcfg.nmods=0; /* read command line args, results are in bootcfg */ @@ -146,7 +152,7 @@ int main (int argc, char **argv) conn->dtls_mtu = 12000; conn->msgset=msgset; conn->local_cfg = global_cfg; - conn->remote_cfg = cw_ktv_create(); + conn->remote_cfg = NULL; conn->receiver = CW_RECEIVER_WTP; conn->wbid=1;