59 Commits

Author SHA1 Message Date
a051ba41de WTP can join w/o any memory leaks 2022-08-15 16:31:26 +02:00
df5e2bcbb7 WTP can run discoveryw/o memory leaks 2022-08-15 00:51:38 +02:00
daa808f9a2 Fixed some memory leaks 2022-08-14 16:03:31 +02:00
5f16ed5455 moved conn_destroy to conn.c 2022-08-14 14:15:18 +02:00
85f79eac6a Eliminated types_tree from msgset 2022-08-14 14:04:58 +02:00
e2e6d29069 Stuff moved to cw.c 2022-08-14 13:37:28 +02:00
fc9ee8dfc2 commented out 2022-08-14 13:31:58 +02:00
143ffb1e08 base_exists and del_sub deleted 2022-08-14 13:31:35 +02:00
f17496592f cw_ktv_del_sub removed 2022-08-14 13:31:05 +02:00
e53b7f1142 Delete cw_ktv_del_sub 2022-08-14 12:43:34 +02:00
459e2e2aeb Lots done in move to typeless 2022-08-14 12:26:34 +02:00
b158544f1a uses cfg_list 2022-08-14 11:26:37 +02:00
46a932dc4b KTV -> CFG 2022-08-14 11:22:30 +02:00
ff8d520972 New msg_callbacks implemented and tested 2022-08-13 11:48:49 +02:00
a3f7a4fc1a Added msg_callbacks 2022-08-13 10:49:15 +02:00
c2e323c941 Formatting 2022-08-13 10:36:05 +02:00
3a8159320f Deleted cwmsg.h 2022-08-13 10:19:06 +02:00
6a64e28982 Removed conn->write_header 2022-08-13 10:18:29 +02:00
6dbf0bc706 Deleted 2022-08-13 09:52:05 +02:00
370942ef7e More work on typeless 2022-08-13 09:47:12 +02:00
add6ffa314 Completely removed cache 2022-08-13 02:02:52 +02:00
ce4a1dd2df Stae MAchine 2022-08-11 00:21:29 +02:00
e5f5687b2b Work on state machine 2022-08-11 00:21:01 +02:00
bf8a8c6d53 Deleted files 2022-08-10 21:36:58 +02:00
10b88b8f86 Renamed capwap_actions_ac 2022-08-10 21:32:16 +02:00
e6e8c8ed32 renamed cisco_actions_ac to cisco_actions 2022-08-10 13:37:46 +02:00
c5e1abb842 Renamed cw_put_msg to cw_assemble_message 2022-08-10 13:16:09 +02:00
9e54e46e45 More move to cw_Conn and conn-stuff within on file 2022-08-10 02:10:10 +02:00
f8654a0408 Removed conn_q_wait_packet 2022-08-10 01:02:45 +02:00
1703be9294 Deleted capwap_mode 2022-08-09 23:45:37 +02:00
d8f18f1a6a deleted capwap_mode 2022-08-09 23:44:35 +02:00
4b5b00009c Renamed struct conn to struct cw_Conn 2022-08-09 22:35:47 +02:00
3da4805c06 cw_in_check_cfg_update_req.c deleted 2022-08-09 21:54:26 +02:00
5b25d49b2b Removed unused code 2022-08-09 21:51:49 +02:00
484be39f78 Fixed: free interface name 2022-08-09 21:48:48 +02:00
0739d57aa6 param attribute added 2022-08-09 21:48:15 +02:00
fe16e62ef2 Deleted unused code 2022-08-09 21:47:39 +02:00
8a1a713c12 new type CW_TYPE_STRUCT 2022-08-09 21:45:46 +02:00
14e69d168b Discovery types and Mac types added 2022-08-09 18:17:10 +02:00
bc5e312ec4 Deleted some unused comments 2022-08-09 17:23:23 +02:00
d2240646f9 Removed cw_ElemHandlerParams.elem 2022-08-09 09:52:30 +02:00
8aa11dccba Moved from ktv to cfg 2022-08-08 23:14:11 +02:00
7d28858a70 New cmp funtion to get sorted integer arrays 2022-08-08 23:11:27 +02:00
8db182a303 Removed ktv stuff and switched to cfg 2022-08-08 23:10:31 +02:00
9452589625 ipv4 and ipv6 configurable 2022-08-08 23:09:28 +02:00
be3adf279d ipv4 and ipv6 are configurable 2022-08-08 23:09:10 +02:00
1544c6aa1b More example cfg 2022-08-08 23:08:38 +02:00
a3bc9dd09c Removed libconfuse-stuff, change to config.ckv 2022-08-08 23:07:58 +02:00
fb280d1c1c Removed libconfuse dependency 2022-08-08 23:06:56 +02:00
5240553144 Creates man pages 2022-08-08 08:40:14 +02:00
1598abee34 New config file 2022-08-01 10:08:01 +02:00
156466eab9 listen addrs are stored in cfg obj now 2022-08-01 10:06:18 +02:00
04d469b970 new function to traverse config
(Work in progress)
2022-08-01 10:05:14 +02:00
0e07e42167 No compiler warnings 2022-08-01 10:04:25 +02:00
4c37d89f03 Changed config.atv to ckv 2022-08-01 10:01:25 +02:00
6d9da94863 Better error handling. 2022-07-31 23:58:43 +02:00
1616d77a0f Much clean-up 2022-07-31 23:00:20 +02:00
a389003199 Fix: memory leak 2022-07-31 22:46:39 +02:00
eac5e73528 Fixed: memory leak 2022-07-31 22:44:58 +02:00
151 changed files with 4347 additions and 4964 deletions

View File

@ -1,13 +1,23 @@
.OBJDIR: ./
all: all: ac wtp
$(MAKE) -C src/cw
$(MAKE) -C src/mod
$(MAKE) -C src/ac
clean: clean:
$(MAKE) -C src/cw clean $(MAKE) -C src/cw clean
$(MAKE) -C src/mod clean $(MAKE) -C src/mod clean
$(MAKE) -C src/ac clean $(MAKE) -C src/ac clean
$(MAKE) -C src/wtp clean
cw:
$(MAKE) -C src/cw
ac: cw mod
$(MAKE) -C src/ac
wtp: cw mod
$(MAKE) -C src/wtp
mod: cw
$(MAKE) -C src/mod

View File

@ -9,6 +9,8 @@ OBJS = \
socklist.o \ socklist.o \
discovery_cache.o\ discovery_cache.o\
shell.o\ shell.o\
statemachine.o\
PRG=actube PRG=actube
LIBPATH=-L../../lib/$(KERNEL)/$(ARCH)/ -L/usr/local/lib -L/usr/lib LIBPATH=-L../../lib/$(KERNEL)/$(ARCH)/ -L/usr/local/lib -L/usr/lib
@ -17,7 +19,6 @@ LIBS+=-lmavl
LIBS+=-lcw LIBS+=-lcw
LIBS+=-lrt LIBS+=-lrt
LIBS+=-lpthread LIBS+=-lpthread
LIBS+=-lconfuse
LIBS+=-lc LIBS+=-lc
LIBS+=-lnettle LIBS+=-lnettle
LIBS+=-lssl LIBS+=-lssl

View File

@ -4,8 +4,6 @@
#include "mavl.h" #include "mavl.h"
#include "cw/mavltypes.h" #include "cw/mavltypes.h"
extern mavl_t actube_global_cfg;
extern struct ac_status ac_global_status; extern struct ac_status ac_global_status;
@ -21,6 +19,7 @@ enum {
AC_PROTO_UNKNOWN AC_PROTO_UNKNOWN
}; };
void start_shell();
#endif #endif

View File

@ -48,8 +48,9 @@
#include "cw/cfg.h" #include "cw/cfg.h"
int ac_run(); int ac_run(cw_Cfg_t * cfg);
#include "statemachine.h"
#include <getopt.h> #include <getopt.h>
@ -64,7 +65,7 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg)
int c; int c;
opterr = 1; opterr = 1;
bootcfg->cfgfilename = "config.atv"; bootcfg->cfgfilename = "config.ckv";
while ( (c = getopt (argc, argv, "vc:d:p:")) != -1) { while ( (c = getopt (argc, argv, "vc:d:p:")) != -1) {
@ -104,7 +105,6 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg)
struct cw_DiscoveryCache * discovery_cache; struct cw_DiscoveryCache * discovery_cache;
mavl_t actube_global_cfg;
int ac_global_init() int ac_global_init()
{ {
@ -141,52 +141,6 @@ extern void test_sets();
#include "discovery_cache.h" #include "discovery_cache.h"
void tester1()
{
struct cw_DiscoveryCache * cache;
struct sockaddr_storage addr;
int rc;
const char *c,*b;
cache = discovery_cache_create(1);
sock_strtoaddr("192.168.0.12:1234",(struct sockaddr*)&addr);
discovery_cache_add(cache,(struct sockaddr*)&addr,"Nase","Loeffel");
sock_strtoaddr("192.168.0.13:1234",(struct sockaddr*)&addr);
discovery_cache_add(cache,(struct sockaddr*)&addr,"Nase","Loeffel");
rc = discovery_cache_get(cache,(struct sockaddr*)&addr,&c,&b);
if (rc) {
printf("RC: %d, %s %s\n",rc,c,b);
}
}
static void show_cfg (FILE *out, mavl_t ktv)
{
char value[500];
struct cw_Val * data;
mavliter_t it;
const struct cw_Type * type;
mavliter_init(&it,ktv);
mavliter_foreach(&it){
data = mavliter_get(&it);
type = data->type;
type->to_str(data,value,0);
fprintf(out,"%s :%s: %s\n",data->key,type->get_type_name(data), value);
}
}
/* /*
{ {
cw_Cfg_t * cfg; cw_Cfg_t * cfg;
@ -214,22 +168,21 @@ static void show_cfg (FILE *out, mavl_t ktv)
return 0; return 0;
*/ */
static cw_Cfg_t * global_cfg = NULL;
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
int rc = 0; int rc = 0;
struct bootcfg bootcfg; struct bootcfg bootcfg;
FILE * file;
mavl_t types_tree, acglobal_cfg;
const cw_Type_t **ti;
cw_Cfg_t * global_cfg = NULL;
/* parse arguments */ /* parse arguments */
parse_args (argc, argv, &bootcfg); parse_args (argc, argv, &bootcfg);
global_cfg=cw_cfg_create(); global_cfg=cw_cfg_create();
if (!global_cfg){ if (!global_cfg){
fprintf(stderr,"Can't create global_cfg: %s\n",strerror(errno)); fprintf(stderr,"Can't create global_cfg: %s\n",strerror(errno));
@ -239,74 +192,49 @@ int main (int argc, char *argv[])
rc = cw_cfg_load(bootcfg.cfgfilename,global_cfg); rc = cw_cfg_load(bootcfg.cfgfilename,global_cfg);
if (rc) if (rc)
{ {
if (rc<0) if (rc)
fprintf(stderr,"Can't load cfg '%s': %s\n",bootcfg.cfgfilename,strerror(errno)); fprintf(stderr,"Can't load cfg '%s': %s\n",bootcfg.cfgfilename,strerror(errno));
goto errX; goto errX;
}; };
/* open config file */
file = fopen("config.ktv","r");
if (file == NULL){
cw_log(LOG_ERR,"Cant open config file '%s': %s",
bootcfg.cfgfilename, strerror(errno));
exit(EXIT_FAILURE);
}
/* create types tree with default types */
types_tree = cw_ktv_create_types_tree();
for (ti=CW_KTV_STD_TYPES;*ti;ti++){
mavl_insert_ptr(types_tree,*ti);
}
acglobal_cfg = cw_ktv_create();
if (acglobal_cfg == NULL){
cw_log(LOG_ERR,"Can't create local_cfg: %s",strerror(errno));
exit(EXIT_FAILURE);
}
cw_ktv_read_file(file,acglobal_cfg,types_tree);
fclose(file);
actube_global_cfg = acglobal_cfg;
cw_dbg_ktv_dump(acglobal_cfg,DBG_INFO,NULL,"CFG:",NULL);
cw_log_name = "AC-Tube"; cw_log_name = "AC-Tube";
if (!read_config ("ac.conf"))
return 1;
start_shell();
/* Show debug options if there are any set */
if (cw_dbg_opt_level)
cw_log (LOG_INFO, "Debug Options: %08X", cw_dbg_opt_level);
/* XXX Hard coded debug settigns, set it by config in the future */
// cw_dbg_opt_display = DBG_DISP_ASC_DMP | DBG_DISP_COLORS;
/* Warn, if the "secret" debugging feature for
developers is turned on ;) */
/* /*
// DBGX("Attention! %s", "DBG X is ON!");
// cw_mod_set_mod_path("../../lib/actube"); {
//cw_mod_load("capwap"); int rc;
cw_Cfg_t * cfg = global_cfg;
struct cw_Cfg_entry e, *result;
e.key="hi";
rc = cw_cfg_base_exists(cfg,"ac-descriptor");
if (!rc ){
printf("No!\n");
return 0;
}
printf("RESULT: %d\n",rc);
cw_cfg_set(tcfg,"tube.0","hallo");
cw_cfg_set(tcfg,"tube.1","welt");
cw_cfg_set(tcfg,"tube.2","der guten laune");
cw_cfg_dump(tcfg);
printf("Next Index: %d\n",cw_cfg_get_next_index(tcfg,"kinder"));
exit(0);
}
*/ */
start_shell();
/* Init DTLS library */ /* Init DTLS library */
dtls_init(); dtls_init();
@ -322,15 +250,20 @@ int main (int argc, char *argv[])
if (!dataman_list_init()) if (!dataman_list_init())
goto errX; goto errX;
ac_conf_init(global_cfg);
cw_cfg_dump(global_cfg);
cw_log (LOG_INFO, "Starting AC-Tube, Name=%s, ID=%s", cw_cfg_get(global_cfg,"capwap/ac-name",NULL), conf_acid);
rc = ac_run(global_cfg);
cw_log (LOG_INFO, "Starting AC-Tube, Name=%s, ID=%s", conf_acname, conf_acid);
rc = ac_run();
errX: errX:
if (global_cfg) if (global_cfg)
mavl_destroy(global_cfg); mavl_destroy(global_cfg);
if (discovery_cache)
discovery_cache_destroy(discovery_cache);
/* XXX There is more cleanup to do */
wtplist_destroy(); wtplist_destroy();
socklist_destroy(); socklist_destroy();
return rc; return rc;
@ -339,21 +272,17 @@ errX:
void process_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len); void process_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len);
void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len); void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len);
int ac_run()
{
if (!conf_listen_addrs_len) { int ac_run(cw_Cfg_t * cfg)
cw_log (LOG_ERR, "Fatal error: No listen addresses found."); {
return 1; struct cw_Cfg_iter cfi;
} const char *s;
int i;
@ -362,16 +291,22 @@ int ac_run()
* we will look for already created sockets to find a * we will look for already created sockets to find a
* good unicast reply socket */ * good unicast reply socket */
int i; cw_cfg_iter_init(cfg, &cfi, "actube/listen");
for (i=0; (s = cw_cfg_iter_next(&cfi, NULL)) != NULL; i++) {
for (i = 0; i < conf_listen_addrs_len; i++) {
char addr[100]; char addr[100];
char port[50]; char port[50];
int proto; int proto;
conf_parse_listen_addr (conf_listen_addrs[i], addr, port, &proto); conf_parse_listen_addr (s, addr, port, &proto);
socklist_add_unicast (addr, port, proto,
socklist_add_unicast (addr, port, proto); cw_cfg_get_bool(cfg,"actube/ipv4","true"),
cw_cfg_get_bool(cfg,"actube/ipv6","true")
);
}
if (!i) {
cw_log (LOG_ERR, "Fatal error: No listen addresses found.");
return 1;
} }
if (socklist_len == 0) { if (socklist_len == 0) {
@ -379,6 +314,9 @@ int ac_run()
return 1; return 1;
} }
/* create multicast sockets */ /* create multicast sockets */
for (i = 0; i < conf_mcast_groups_len; i++) { for (i = 0; i < conf_mcast_groups_len; i++) {
@ -395,13 +333,20 @@ int ac_run()
} }
/* broadcast socket ipv4 only */ /* broadcast socket ipv4 only */
for (i = 0; i < conf_bcast_addrs_len; i++) {
//mavl_print(cfg,pcb,180);
cw_cfg_iter_init(cfg, &cfi, "actube/bcast");
for (i=0; (s = cw_cfg_iter_next(&cfi, NULL)) != NULL; i++) {
// for (i = 0; i < conf_bcast_addrs_len; i++) {
char addr[50], port[50]; char addr[50], port[50];
int proto; int proto;
conf_parse_listen_addr (conf_bcast_addrs[i], addr, port, &proto); conf_parse_listen_addr (s, addr, port, &proto);
socklist_add_broadcast (addr, port, proto); socklist_add_broadcast (addr, port, proto);
#ifdef WITH_LWAPP #ifdef WITH_LWAPP
// printf("Adding %d\n",socklist_len); // printf("Adding %d\n",socklist_len);
@ -517,7 +462,7 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer,
dataman_list_unlock(); dataman_list_unlock();
dataman_add_packet (dm, buffer, len); //dataman_add_packet (dm, buffer, len);
return; return;
@ -561,7 +506,7 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer,
if (!wtpman) { if (!wtpman) {
wtpman = wtpman_create (index, addr, preamble & 0xf); wtpman = wtpman_create (index, addr, preamble & 0xf, global_cfg);
if (!wtpman) { if (!wtpman) {
@ -581,6 +526,7 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer,
wtpman_start (wtpman, preamble & 0xf); wtpman_start (wtpman, preamble & 0xf);
} }
//printf("Got Packet with len: %d\n",len);
wtpman_addpacket (wtpman, buffer, len); wtpman_addpacket (wtpman, buffer, len);
wtplist_unlock(); wtplist_unlock();

View File

@ -19,7 +19,6 @@
#include <string.h> #include <string.h>
#include <sys/utsname.h> #include <sys/utsname.h>
#include <confuse.h>
#include "cw/capwap.h" #include "cw/capwap.h"
#include "cw/sock.h" #include "cw/sock.h"
@ -36,12 +35,13 @@
#include "conf.h" #include "conf.h"
#include "ac.h" #include "ac.h"
#include "cw/cfg.h"
#include "cw/mavltypes.h" #include "cw/mavltypes.h"
uint8_t conf_macaddress[12]; /*uint8_t conf_macaddress[12];
uint8_t conf_macaddress_len = 0; uint8_t conf_macaddress_len = 0;
*/
long conf_strict_capwap = 1; long conf_strict_capwap = 1;
long conf_strict_headers = 0; long conf_strict_headers = 0;
@ -49,9 +49,6 @@ long conf_strict_headers = 0;
const char *conf_acname = NULL;
int conf_acname_len = 0;
char *conf_acid = NULL; char *conf_acid = NULL;
char *conf_primary_if = NULL; char *conf_primary_if = NULL;
@ -60,16 +57,11 @@ long conf_max_wtps = CONF_DEFAULT_MAXWTPS;
char *conf_logfilename = CONF_DEFAULT_LOGFILENAME; char *conf_logfilename = CONF_DEFAULT_LOGFILENAME;
struct sockaddr_storage *conf_salist = NULL; struct sockaddr_storage *conf_salist = NULL;
char **conf_listen_addrs;
int conf_listen_addrs_len = 0;
char **conf_mcast_groups = 0; char **conf_mcast_groups = 0;
int conf_mcast_groups_len = 0; int conf_mcast_groups_len = 0;
char **conf_bcast_addrs = 0;
int conf_bcast_addrs_len;
struct sockaddr_storage *conf_bsalist = NULL; struct sockaddr_storage *conf_bsalist = NULL;
@ -120,14 +112,45 @@ char *conf_control_port = 0;
int conf_dtls_verify_peer = 1; int conf_dtls_verify_peer = 1;
static int init_acname() static int init_ac_name(cw_Cfg_t * cfg)
{ {
if (conf_acname == NULL) { char *s;
char *s = malloc(strlen(CONF_DEFAULT_ACNAME) + strlen(conf_acid) + 1); char *primary_if=NULL;
sprintf(s, "%s%s", CONF_DEFAULT_ACNAME, conf_acid); char ac_name[CAPWAP_MAX_AC_NAME_LEN+1];
conf_acname = s; uint8_t macaddress[128];
uint8_t macaddress_len;
char acid[128];
int i;
s= cw_cfg_get(cfg,"capwap/ac-name",NULL);
if (s!=NULL)
return 1;
// primary_if = sock_get_primary_if(AF_INET6);
if (!primary_if)
primary_if = sock_get_primary_if(AF_INET);
acid[0]=0;
if (primary_if) {
macaddress_len=8;
if (!sock_getifhwaddr(primary_if, macaddress, &macaddress_len)) {
cw_dbg(DBG_INFO, "Fatal: Unable to detect link layer address for %s\n",
primary_if);
} }
conf_acname_len = strlen(conf_acname); else{
s=acid;
for (i = 0; i < macaddress_len; i++) {
s += sprintf(s, "%02X", macaddress[i]);
}
}
free(primary_if);
}
sprintf(ac_name,"actube%s",acid);
cw_cfg_set(cfg,"capwap/ac-name",ac_name);
return 1; return 1;
} }
@ -136,49 +159,6 @@ static int init_acname()
static int init_acid()
{
int i;
char *s;
if (conf_acid != NULL)
return 1;
#ifdef WITH_IPV6
conf_primary_if = sock_get_primary_if(AF_INET6);
if (!conf_primary_if)
conf_primary_if = sock_get_primary_if(AF_INET);
#else
conf_primary_if = get_primary_if(AF_INET);
#endif
if (!conf_primary_if) {
cw_log(LOG_ERR,
"Fatal: Unable to detect primary interface, needed to set ac_id. Pleas use confiPleas u to set ac_id");
return 0;
}
if (!sock_getifhwaddr(conf_primary_if, conf_macaddress, &conf_macaddress_len)) {
cw_log(LOG_ERR, "Fatal: Unable to detect link layer address for %s\n",
conf_primary_if);
return 0;
};
conf_acid = malloc(2 * conf_macaddress_len + 1);
s = conf_acid;
for (i = 0; i < conf_macaddress_len; i++) {
s += sprintf(s, "%02X", conf_macaddress[i]);
}
return 1;
}
static int init_dtls() static int init_dtls()
{ {
if (conf_dtls_psk != NULL) { if (conf_dtls_psk != NULL) {
@ -215,41 +195,25 @@ static int init_control_port()
#include <ifaddrs.h> #include <ifaddrs.h>
static int init_listen_addrs() static int init_listen_addrs(cw_Cfg_t * cfg)
{ {
char key[CW_CFG_MAX_KEY_LEN];
struct ifaddrs *ifap, *ifa; struct ifaddrs *ifap, *ifa;
int rc; int rc;
int ctr; int ctr;
struct cw_Cfg_iter cfi;
if (conf_listen_addrs != 0)
return 1;
cw_cfg_iter_init(cfg, &cfi, "actube/listen");
if (cw_cfg_iter_next(&cfi,NULL) != NULL)
return 0;
rc = getifaddrs(&ifap); rc = getifaddrs(&ifap);
if (rc == -1) if (rc == -1)
return 0; return 0;
/* count the addresses */
ctr = 0;
for (ifa = ifap; ifa != 0; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr)
continue;
if (ifa->ifa_addr->sa_family == AF_INET && conf_ipv4)
ctr++;
if (ifa->ifa_addr->sa_family == AF_INET6 && conf_ipv6)
ctr++;
}
conf_listen_addrs = malloc(sizeof(char *) * ctr);
if (!conf_listen_addrs) {
rc = 0;
goto errX;
}
memset(conf_listen_addrs, 0, sizeof(char *) * ctr);
ctr = 0; ctr = 0;
/* get the addresses */ /* get the addresses */
for (ifa = ifap; ifa != 0; ifa = ifa->ifa_next) { for (ifa = ifap; ifa != 0; ifa = ifa->ifa_next) {
@ -267,12 +231,9 @@ static int init_listen_addrs()
if (ifa->ifa_addr->sa_family == AF_INET && conf_ipv4) { if (ifa->ifa_addr->sa_family == AF_INET && conf_ipv4) {
sock_addrtostr(ifa->ifa_addr, str, 100,0); sock_addrtostr(ifa->ifa_addr, str, 100,0);
conf_listen_addrs[ctr] =
(char *) cw_setstr((uint8_t **) & conf_listen_addrs[ctr],
(uint8_t *) str, strlen(str));
if (conf_listen_addrs[ctr])
ctr++;
sprintf(key,"actube/listen.%d",ctr++);
cw_cfg_set(cfg,key,str);
} }
if (ifa->ifa_addr->sa_family == AF_INET6 && conf_ipv6) { if (ifa->ifa_addr->sa_family == AF_INET6 && conf_ipv6) {
sock_addrtostr(ifa->ifa_addr, str, 100,0); sock_addrtostr(ifa->ifa_addr, str, 100,0);
@ -281,14 +242,10 @@ static int init_listen_addrs()
strcat(str, "%"); strcat(str, "%");
strcat(str, ifa->ifa_name); strcat(str, ifa->ifa_name);
} }
conf_listen_addrs[ctr] = sprintf(key,"actube/listen.%d",ctr++);
(char *) cw_setstr((uint8_t **) & conf_listen_addrs[ctr], cw_cfg_set(cfg,key,str);
(uint8_t *) str, strlen(str));
if (conf_listen_addrs[ctr])
ctr++;
} }
} }
conf_listen_addrs_len = ctr;
rc = 1; rc = 1;
errX: errX:
freeifaddrs(ifap); freeifaddrs(ifap);
@ -336,18 +293,24 @@ static int add_bcast_addr(void *priv, void *addr)
/* /*
* Initialize broadcast addresses (ipv4 only) * Initialize broadcast addresses (ipv4 only)
*/ */
int init_bcast_addrs() int init_bcast_addrs(cw_Cfg_t *cfg)
{ {
int rc; int rc;
char str[100]; char str[100];
char key[100];
struct ifaddrs *ifa0, *ifa; struct ifaddrs *ifa0, *ifa;
mavl_t t; mavl_t t;
mavliter_t it; mavliter_t it;
struct cw_Cfg_iter cfi;
int i;
if (conf_bcast_addrs) //printf("BCAST INIT\n");
return 1; cw_cfg_iter_init(cfg, &cfi, "actube/bcast");
if (cw_cfg_iter_next(&cfi,NULL) != NULL)
return 0;
if (!conf_ipv4)
if (!cw_cfg_get_bool(cfg,"actube/ipv4", "true"))
return 1; return 1;
/*t = mavl_create_ptr(); */ /*t = mavl_create_ptr(); */
@ -385,22 +348,34 @@ int init_bcast_addrs()
if (ifa->ifa_broadaddr) { if (ifa->ifa_broadaddr) {
char *s,*sr;
sock_addrtostr(ifa->ifa_broadaddr, str, 100,1); sock_addrtostr(ifa->ifa_broadaddr, str, 100,1);
*strchr(str, ':') = 0; *strchr(str, ':') = 0;
mavl_add_str(t, cw_strdup(str));
s = cw_strdup(str);
sr = mavl_add_str(t, s);
printf("BCAST = %p --- %p: %s\n",str,s,str);
} }
} }
conf_bcast_addrs = malloc(t->count * sizeof(char *)); // conf_bcast_addrs = malloc(t->count * sizeof(char *));
i=0;
mavliter_init(&it,t); mavliter_init(&it,t);
mavliter_foreach(&it){ mavliter_foreach(&it){
char * d; char * d;
d = mavliter_get_str(&it); d = mavliter_get_str(&it);
conf_bcast_addrs[conf_bcast_addrs_len] = cw_strdup(d); // conf_bcast_addrs[conf_bcast_addrs_len] = cw_strdup(d);
if (conf_bcast_addrs[conf_bcast_addrs_len] != 0) // if (conf_bcast_addrs[conf_bcast_addrs_len] != 0)
conf_bcast_addrs_len++; // conf_bcast_addrs_len++;
sprintf(key,"actube/bcast.%d",i++);
cw_cfg_set(cfg,key,d);
} }
@ -412,7 +387,7 @@ int init_bcast_addrs()
return 1; return 1;
} }
int init_mcast_groups() int init_mcast_groups(cw_Cfg_t * cfg)
{ {
int ctr; int ctr;
int i; int i;
@ -466,6 +441,7 @@ int init_mcast_groups()
} }
/*
static int conf_read_strings(cfg_t * cfg, char *name, char ***dst, int *len) static int conf_read_strings(cfg_t * cfg, char *name, char ***dst, int *len)
{ {
@ -491,8 +467,9 @@ static int conf_read_strings(cfg_t * cfg, char *name, char ***dst, int *len)
return 1; return 1;
} }
*/
/*
static int conf_read_dbg_level(cfg_t * cfg) static int conf_read_dbg_level(cfg_t * cfg)
{ {
const char *name = "dbg"; const char *name = "dbg";
@ -510,6 +487,7 @@ static int conf_read_dbg_level(cfg_t * cfg)
} }
return 1; return 1;
} }
*/
struct cw_Mod ** conf_mods; struct cw_Mod ** conf_mods;
char *conf_mods_dir = NULL; char *conf_mods_dir = NULL;
@ -517,19 +495,28 @@ char *conf_mods_dir = NULL;
/* /*
* Read the module names from config file * Read the module names from config file
*/ */
static int conf_read_mods(cfg_t *cfg){ static int init_mods(cw_Cfg_t *cfg){
int n, i; int n, i;
n = cfg_size(cfg,CFG_ENTRY_MODS); const char * modname;
conf_mods = malloc(sizeof(struct cw_Mod *)*(n+1)); struct cw_Cfg_iter cfi;
cw_cfg_iter_init(cfg, &cfi, "actube/mod");
if (cw_cfg_iter_next(&cfi,NULL) == NULL){
cw_cfg_set(cfg,"actube/mod.0","capwap");
cw_cfg_set(cfg,"actube/mod.1","capwap80211");
}
cw_dbg(DBG_INFO,"Mods directory: %s",conf_mods_dir); // cw_dbg(DBG_INFO,"Mods directory: %s",conf_mods_dir);
cw_mod_set_path(conf_mods_dir); // cw_mod_set_path(conf_mods_dir);
for (i=0; i < n; i++){ cw_cfg_iter_init(cfg, &cfi, "actube/mod");
char *modname = cfg_getnstr(cfg, CFG_ENTRY_MODS, i); printf("iter mods\n");
struct cw_Mod * mod = cw_mod_load(modname, actube_global_cfg, CW_ROLE_AC); for (i=0; (modname = cw_cfg_iter_next(&cfi, NULL)) != NULL; i++) {
printf("init mod name: %s\n",modname);
struct cw_Mod * mod = cw_mod_load(modname, cfg, CW_ROLE_AC);
if (!mod) if (!mod)
return 0; return 0;
@ -630,148 +617,19 @@ static void errfunc(cfg_t *cfg, const char *fmt, va_list ap){
fprintf(stderr,"\n"); fprintf(stderr,"\n");
} }
int read_config(const char *filename)
{
int i, n;
cfg_opt_t opts[] = {
CFG_STR_LIST("mods", "{}", CFGF_NONE),
CFG_SIMPLE_STR("mods_dir", &conf_mods_dir),
CFG_STR_LIST("dbg", "{}", CFGF_NONE),
CFG_STR_LIST("listen", "{}", CFGF_NONE),
CFG_STR_LIST("mcast_groups", "{}", CFGF_NONE),
CFG_STR_LIST("broadcast_listen", "{}", CFGF_NONE),
CFG_STR_LIST("ac_ips", "{}", CFGF_NONE),
CFG_SIMPLE_STR("control_port", &conf_control_port),
CFG_SIMPLE_BOOL("strict_capwap", &conf_strict_capwap),
CFG_SIMPLE_BOOL("strict_headers", &conf_strict_headers),
CFG_SIMPLE_BOOL("use_loopback", &conf_use_loopback),
/*// CFG_SIMPLE_STR("capwap_mode", &conf_capwap_mode_str),*/
#ifdef WITH_LWAPP
CFG_SIMPLE_STR("lw_control_port", &conf_lw_control_port),
CFG_SIMPLE_BOOL("lwapp", &conf_lwapp),
#endif
CFG_SIMPLE_INT("max_wtps", &conf_max_wtps),
CFG_SIMPLE_INT("debug_level", &conf_debug_level),
CFG_SIMPLE_INT("vendor_id", &conf_vendor_id),
CFG_SIMPLE_STR("ac_id", &conf_acid),
CFG_SIMPLE_STR("ac_name", &conf_acname),
CFG_SIMPLE_STR("hardware_version", &conf_hardware_version),
CFG_SIMPLE_STR("software_version", &conf_software_version),
CFG_SIMPLE_STR("cisco_hardware_version", &conf_cisco_hardware_version),
CFG_SIMPLE_STR("cisco_software_version", &conf_cisco_software_version),
CFG_SIMPLE_STR("ssl_cert", &conf_sslcertfilename),
CFG_SIMPLE_STR("ssl_key", &conf_sslkeyfilename),
CFG_SIMPLE_STR("ssl_key_pass", &conf_sslkeypass),
CFG_SIMPLE_STR("dtls_psk", &conf_dtls_psk),
CFG_SIMPLE_BOOL("dtls_verify_peer", &conf_dtls_verify_peer),
CFG_SIMPLE_BOOL("ipv4", &conf_ipv4),
CFG_SIMPLE_BOOL("ipv6", &conf_ipv6),
CFG_SIMPLE_STR("db_file", &conf_db_file),
CFG_SIMPLE_STR("image_dir", &conf_image_dir),
CFG_END()
};
cfg_t *cfg;
conf_mods_dir=cw_strdup("");
if (!init_control_port())
return 0;
cfg = cfg_init(opts, CFGF_NONE);
cfg_set_error_function(cfg, errfunc);
if (cfg_parse(cfg, filename))
return 0;
/* read debug options */
conf_read_dbg_level(cfg);
/* read the listen addresses */
conf_read_strings(cfg, "listen", &conf_listen_addrs, &conf_listen_addrs_len);
/* read multi cast groups */
conf_read_strings(cfg, "mcast_groups", &conf_mcast_groups,
&conf_mcast_groups_len);
/* read ipv4 broadcast addresses */
conf_read_strings(cfg, "broadcast_listen", &conf_bcast_addrs, &conf_bcast_addrs_len);
/* read ac_ips */
n = cfg_size(cfg, "ac_ips");
if (!(conf_ac_ips = malloc(sizeof(struct sockaddr) * n)))
return 0;
conf_ac_ips_len = n;
for (i = 0; i < n; i++) {
struct sockaddr sa;
char *str = cfg_getnstr(cfg, "ac_ips", i);
if (sock_strtoaddr(cfg_getnstr(cfg, "ac_ips", i), &sa))
conf_ac_ips[i] = sa;
else {
perror(str);
}
}
if (!conf_read_mods(cfg)){
cfg_free(cfg);
return 0;
}
cfg_free(cfg);
if (!init_acid())
return 0;
if (!init_acname())
return 0;
/* if (!init_version())
return 0;
*/
if (!init_vendor_id())
return 0;
if (!init_dtls())
return 0;
/* if (!conf_sslcipher)
conf_sslcipher = CAPWAP_CIPHER;
*/ if (!conf_image_dir)
conf_image_dir = CONF_DEFAULT_IMAGE_DIR;
init_listen_addrs();
init_mcast_groups();
init_bcast_addrs();
return 1;
}
void free_config() void free_config()
{ {
} }
void ac_conf_init(cw_Cfg_t *cfg)
{
printf("ac conf\n");
init_listen_addrs(cfg);
init_bcast_addrs(cfg);
init_ac_name(cfg);
init_mods(cfg);
}

View File

@ -31,7 +31,7 @@
#include "cw/bstr.h" #include "cw/bstr.h"
#include "cw/mod.h" #include "cw/mod.h"
#include "cw/vendors.h" #include "cw/vendors.h"
#include "cw/cfg.h"
extern struct cw_Mod ** conf_mods; extern struct cw_Mod ** conf_mods;
@ -94,8 +94,6 @@ extern bstr_t conf_cisco_software_version;
extern char **conf_listen_addrs;
extern int conf_listen_addrs_len;
extern struct sockaddr *conf_ac_ips; extern struct sockaddr *conf_ac_ips;
extern int conf_ac_ips_len; extern int conf_ac_ips_len;
@ -141,5 +139,8 @@ extern int conf_parse_listen_addr(const char *addr, char *saddr, char *port, int
#define CFG_ENTRY_MODS "mods" #define CFG_ENTRY_MODS "mods"
#define CONF_PREFIX "actube"
void ac_conf_init(cw_Cfg_t *cfg);
#endif #endif

69
src/ac/config.ckv Normal file
View File

@ -0,0 +1,69 @@
#Cfg
#
# AC Name
# Deafults to actube + mac address of primary interface
#
#capwap/ac-name
#
capwap/ac-name: actube
capwap/ssl-cipher: DHE-RSA:RSA:AES-256-CBC:AES-128-CBC:SHA1:PSK
capwap/ssl-psk-enable: false
capwap/ssl-psk: 123456
capwap/ssl-dhbits: 1024
cisco/ssl-keyfile: "../../ssl/intermediate-ca/int-ca.key"
cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt"
cisco/ssl-cipher: DEFAULT
cisco/ssl-dhbits: 2048
#
# Whether or not to use IPv4/IPv6
#
#actube/ipv4: true
#actube/ipv6: true
#
actube/ipv6: false
#
# List of Mods
#
#actube/mod.1: capwap
#actube/mod.2: capwap80211
#
actube/mod.0: cisco
actube/mod.1: capwap
actube/mod.2: capwap80211
ac-descriptor/dtls-policy: 1
ac-descriptor/hardware/vendor: 4232704
ac-descriptor/hardware/version: .x01000001
ac-descriptor/max-wtps : 200
ac-descriptor/active-wtps: 2
ac-descriptor/r-mac-field: 1
ac-descriptor/reserved1 : 0
ac-descriptor/security : 2
ac-descriptor/software/vendor : 0
ac-descriptor/software/version: v0.0.1
ac-descriptor/station-limit: 1000
ac-descriptor/stations: 0
capwap-control-ip-address/address.0: 192.168.0.14
#
# CAPWAP Timers
#
capwap-timers/change-state-pending-timer: Word: 3
capwap-timers/data-check-timer: Word: 10
capwap-timers/echo-interval :Byte: 30
capwap-timers/max-discovery-interval :Byte: 10

View File

@ -32,6 +32,9 @@ void discovery_cache_destroy(struct cw_DiscoveryCache * c)
if (c->byaddrp) if (c->byaddrp)
mavl_destroy(c->byaddrp); mavl_destroy(c->byaddrp);
if (c->queue)
free(c->queue);
free(c); free(c);
} }

View File

@ -3,7 +3,7 @@
#include "cw/mod.h"
struct cw_DiscoveryCache * discovery_cache_create(int len); struct cw_DiscoveryCache * discovery_cache_create(int len);
@ -14,4 +14,5 @@ void discovery_cache_add(struct cw_DiscoveryCache *cache,
int discovery_cache_get(struct cw_DiscoveryCache * cache,struct sockaddr *addr, int discovery_cache_get(struct cw_DiscoveryCache * cache,struct sockaddr *addr,
struct cw_Mod ** modcapwap, struct cw_Mod **modbindings); struct cw_Mod ** modcapwap, struct cw_Mod **modbindings);
void discovery_cache_destroy(struct cw_DiscoveryCache * c);
#endif #endif

View File

@ -36,7 +36,7 @@ void wlan0_cmd(struct shelldata *sd, const char * cmd);
void show_cfg (FILE *out, mavl_t ktv); void show_cfg (FILE *out, mavl_t ktv);
void show_aps (FILE *out); void show_aps (FILE *out);
struct conn * find_ap(const char *name); struct cw_Conn * find_ap(const char *name);
struct command{ struct command{
char * cmd; char * cmd;
@ -72,7 +72,7 @@ void list_cmd(struct shelldata *sd, const char *cmd)
void cfg_cmd(struct shelldata *sd, const char *cmd) void cfg_cmd(struct shelldata *sd, const char *cmd)
{ {
struct conn * conn; struct cw_Conn * conn;
wtplist_lock(); wtplist_lock();
conn = find_ap(sd->prompt); conn = find_ap(sd->prompt);
if (conn==NULL){ if (conn==NULL){
@ -86,7 +86,7 @@ void cfg_cmd(struct shelldata *sd, const char *cmd)
void ucfg_cmd(struct shelldata *sd, const char *cmd) void ucfg_cmd(struct shelldata *sd, const char *cmd)
{ {
struct conn * conn; struct cw_Conn * conn;
show_cfg(sd->out,sd->update_cfg); show_cfg(sd->out,sd->update_cfg);
} }
@ -96,7 +96,7 @@ void ucfg_cmd(struct shelldata *sd, const char *cmd)
void void
send_cmd(struct shelldata * sd, const char *cmd) send_cmd(struct shelldata * sd, const char *cmd)
{ {
struct conn * conn; struct cw_Conn * conn;
wtplist_lock(); wtplist_lock();
conn = find_ap(sd->prompt); conn = find_ap(sd->prompt);
if (conn==NULL){ if (conn==NULL){
@ -111,7 +111,9 @@ send_cmd(struct shelldata * sd, const char *cmd)
void void
wlan0_cmd(struct shelldata * sd, const char *cmd) wlan0_cmd(struct shelldata * sd, const char *cmd)
{ {
struct conn * conn; stop();
struct cw_Conn * conn;
wtplist_lock(); wtplist_lock();
conn = find_ap(sd->prompt); conn = find_ap(sd->prompt);
if (conn==NULL){ if (conn==NULL){
@ -119,7 +121,7 @@ wlan0_cmd(struct shelldata * sd, const char *cmd)
} }
else { else {
FILE *f=fopen("wlan0.ktv","r"); FILE *f=fopen("wlan0.ktv","r");
cw_ktv_read_file(f,sd->update_cfg,conn->msgset->types_tree); // cw_ktv_read_file(f,sd->update_cfg,conn->msgset->types_tree);
//conn->update_cfg=sd->update_cfg; //conn->update_cfg=sd->update_cfg;
fclose(f); fclose(f);
} }
@ -129,12 +131,15 @@ wlan0_cmd(struct shelldata * sd, const char *cmd)
void set_cmd(struct shelldata *sd, const char *str) void set_cmd(struct shelldata *sd, const char *str)
{ {
struct conn * conn; struct cw_Conn * conn;
struct cw_Val_Reader r; struct cw_Val_Reader r;
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
char type[CW_KTV_MAX_KEY_LEN]; char type[CW_CFG_MAX_KEY_LEN];
char val[2048]; char val[2048];
cw_ktv_init_str_reader(&r,str,strlen(str));
stop();
// cw_ktv_init_str_reader(&r,str,strlen(str));
cw_ktv_parse_string(&r,key,type,val); cw_ktv_parse_string(&r,key,type,val);
/*cw_ktv_parse_string(key,type,val, 2048);*/ /*cw_ktv_parse_string(key,type,val, 2048);*/
@ -145,9 +150,10 @@ void set_cmd(struct shelldata *sd, const char *str)
void del_cmd(struct shelldata *sd, const char *str) void del_cmd(struct shelldata *sd, const char *str)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
sscanf(str,"%s",key); sscanf(str,"%s",key);
cw_ktv_del_sub(sd->update_cfg,key); stop();
// cw_ktv_del_sub(sd->update_cfg,key);
} }
@ -189,7 +195,7 @@ void show_aps (FILE *out)
cw_Val_t * result; cw_Val_t * result;
char addr[SOCK_ADDR_BUFSIZE]; char addr[SOCK_ADDR_BUFSIZE];
char wtp_name[CAPWAP_MAX_WTP_NAME_LEN]; char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
struct conn * conn; struct cw_Conn * conn;
conn = mavliter_get_ptr (&it); conn = mavliter_get_ptr (&it);
sock_addr2str_p (&conn->addr, addr); sock_addr2str_p (&conn->addr, addr);
@ -211,7 +217,7 @@ void show_aps (FILE *out)
struct conn * find_ap(const char *name) struct cw_Conn * find_ap(const char *name)
{ {
struct connlist * cl; struct connlist * cl;
mavliter_t it; mavliter_t it;
@ -224,7 +230,7 @@ struct conn * find_ap(const char *name)
mavliter_foreach (&it) { mavliter_foreach (&it) {
cw_Val_t * result; cw_Val_t * result;
char wtp_name[CAPWAP_MAX_WTP_NAME_LEN]; char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
struct conn * conn; struct cw_Conn * conn;
conn = mavliter_get_ptr (&it); conn = mavliter_get_ptr (&it);
result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL); result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL);
@ -266,7 +272,7 @@ void con (FILE *out)
cw_Val_t * result; cw_Val_t * result;
char addr[SOCK_ADDR_BUFSIZE]; char addr[SOCK_ADDR_BUFSIZE];
char wtp_name[CAPWAP_MAX_WTP_NAME_LEN]; char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
struct conn * conn; struct cw_Conn * conn;
conn = mavliter_get_ptr (&it); conn = mavliter_get_ptr (&it);
sock_addr2str_p (&conn->addr, addr); sock_addr2str_p (&conn->addr, addr);
@ -342,7 +348,7 @@ void execute_cmd (struct shelldata * sd, const char *str)
return; return;
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
char type[128]; char type[128];
char val[2048]; char val[2048];

View File

@ -335,7 +335,7 @@ static int socklist_check_size()
} }
int socklist_add_unicast(const char *addr, const char *port, int ac_proto) int socklist_add_unicast(const char *addr, const char *port, int ac_proto, int ipv4, int ipv6)
{ {
char sock_buf[SOCK_ADDR_BUFSIZE]; char sock_buf[SOCK_ADDR_BUFSIZE];
struct addrinfo hints; struct addrinfo hints;
@ -365,6 +365,14 @@ int socklist_add_unicast(const char *addr, const char *port, int ac_proto)
struct sockaddr *sa; struct sockaddr *sa;
int sockfd; int sockfd;
if (res->ai_addr->sa_family == AF_INET && !ipv4){
continue;
}
if (res->ai_addr->sa_family == AF_INET6 && !ipv6){
continue;
}
ifname[0] = 0; ifname[0] = 0;
rc = sock_getifinfo(res->ai_addr, ifname, &broadcast, &netmask); rc = sock_getifinfo(res->ai_addr, ifname, &broadcast, &netmask);
if (!rc) { if (!rc) {
@ -372,6 +380,7 @@ int socklist_add_unicast(const char *addr, const char *port, int ac_proto)
continue; continue;
} }
/* Bind the control port */ /* Bind the control port */
sa = res->ai_addr; sa = res->ai_addr;
sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0); sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0);

View File

@ -40,7 +40,7 @@ struct socklistelem{
extern int socklist_add_multicast(const char * addr, const char * port, int ac_proto); extern int socklist_add_multicast(const char * addr, const char * port, int ac_proto);
extern int socklist_add_unicast(const char *addr, const char * port, int ac_proto); extern int socklist_add_unicast(const char *addr, const char * port, int ac_proto, int ipv4, int ipv6);
extern int socklist_add_broadcast(const char *addr, const char * port,int ac_proto); extern int socklist_add_broadcast(const char *addr, const char * port,int ac_proto);
extern int socklist_init(); extern int socklist_init();
extern void socklist_destroy(); extern void socklist_destroy();

137
src/ac/statemachine.c Normal file
View File

@ -0,0 +1,137 @@
#include <stdint.h>
#include <mavl.h>
#include "cw/capwap.h"
#include "cw/dbg.h"
#include "statemachine.h"
static cw_StateMachineState_t statemachine_states[];
int cw_statemachine_run(struct cw_StateMachine * mach)
{
struct mavl * st = cw_statemachine_load_states(NULL,statemachine_states);
mavl_destroy(st);
return 0;
}
static cw_StateMachineState_t statemachine_states[]={
{ CW_STATE_NONE, CAPWAP_STATE_DISCOVERY, /* transition */
NULL,0 /* timer */
}
,
{
CAPWAP_STATE_DTLS_SETUP, CAPWAP_STATE_JOIN, /* transition */
"wait-join",CAPWAP_WAIT_JOIN, /* timer */
1 /* retval */
}
,
{
CAPWAP_STATE_JOIN,CAPWAP_STATE_TIMEOUT,
NULL,0,
0, "WTP Join timeout"
}
,
{
CAPWAP_STATE_JOIN, CAPWAP_STATE_JOIN,
NULL,0,
1, "WTP has joined"
}
,
{
CAPWAP_STATE_JOIN, CAPWAP_STATE_CONFIGURE,
"capwap-timers/change-state-pending-timer",CAPWAP_TIMER_CHANGE_STATE_PENDING_TIMER,
1, NULL
}
,
{
CAPWAP_STATE_CONFIGURE,CAPWAP_STATE_TIMEOUT,
NULL,0,
0, "WTP change state timeout"
}
,
{
CAPWAP_STATE_CONFIGURE,CAPWAP_STATE_DATA_CHECK,
"capwap-timers/data-check-timer",CAPWAP_TIMER_DATA_CHECK_TIMER,
1, NULL
}
,
{
CAPWAP_STATE_DATA_CHECK,CAPWAP_STATE_TIMEOUT,
NULL,0,
0, "WTP data check timeout"
}
,
{
CAPWAP_STATE_DATA_CHECK,CAPWAP_STATE_RUN,
"capwap-timers/echo-interval",CAPWAP_ECHO_INTERVAL,
1, NULL
}
,
{
CAPWAP_STATE_RUN,CAPWAP_STATE_RUN,
"capwap-timers/echo-interval",CAPWAP_ECHO_INTERVAL,
1, NULL
}
,
{
CAPWAP_STATE_RUN,CAPWAP_STATE_TIMEOUT,
NULL,0,
0, "WTP echo timout"
}
,
{0,0,0}
};
static int cmp_statemachine_state(const void *state1, const void *state2)
{
const struct cw_StateMachineState *s1 = state1;
const struct cw_StateMachineState *s2 = state2;
int rc;
rc = s1->state - s2->state;
if (rc!=0)
return rc;
return s1->prevstate-s2->prevstate;
}
struct mavl * cw_statemachine_load_states (struct mavl * statemachine_states, cw_StateMachineState_t * states)
{
cw_StateMachineState_t * s;
int replaced;
cw_dbg(DBG_STATE,"Loading State Machine States");
if (statemachine_states == NULL){
statemachine_states = mavl_create(cmp_statemachine_state,NULL,sizeof(cw_StateMachineState_t));
if (statemachine_states == NULL)
return NULL;
}
s=states;
while (s->state != 0){
const char * repstr;
mavl_replace(statemachine_states,s,&replaced);
if (replaced){
repstr = "Replacing";
}
else{
repstr = "Adding";
}
cw_dbg(DBG_STATE," %s: [%s->%s]",repstr,
cw_strstate(s->prevstate),
cw_strstate(s->state));
s++;
}
return 1;
}

13
src/ac/statemachine.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef STATEMACHINE_H
#define STATEMACHINE_H
struct cw_StateMachine{
uint8_t prevstate,currentstate;
};
struct mavl * cw_statemachine_load_states (struct mavl * statemachine_states, cw_StateMachineState_t * states);
int cw_statemachine_run(struct cw_StateMachine * mach);
#endif

View File

@ -71,7 +71,7 @@ void wtplist_destroy()
struct wtpman * wtplist_get(const struct sockaddr * addr) struct wtpman * wtplist_get(const struct sockaddr * addr)
{ {
struct conn * conn = connlist_get(connlist,addr); struct cw_Conn * conn = connlist_get(connlist,addr);
if (!conn) if (!conn)
return 0; return 0;
return conn->data; return conn->data;
@ -80,8 +80,8 @@ struct wtpman * wtplist_get(const struct sockaddr * addr)
struct wtpman * wtplist_get_by_session_id(bstr16_t *session_id) struct wtpman * wtplist_get_by_session_id(bstr16_t *session_id)
{ {
struct conn search; struct cw_Conn search;
struct conn * conn; struct cw_Conn * conn;
search.session_id = session_id; search.session_id = session_id;
/*memcpy (search.session_id, session_id,16);*/ /*memcpy (search.session_id, session_id,16);*/

View File

@ -37,7 +37,6 @@
#include "ac.h" #include "ac.h"
#include "conf.h" #include "conf.h"
#include "db.h"
#include "socklist.h" #include "socklist.h"
#include "wtpman.h" #include "wtpman.h"
#include "wtplist.h" #include "wtplist.h"
@ -45,34 +44,6 @@
#include "actube.h" #include "actube.h"
static void reset_echointerval_timer(struct wtpman *wtpman)
{
/* char sock_buf[SOCK_ADDR_BUFSIZE];*/
/* uint16_t ct = mbag_get_word(wtpman->conn->local, CW_ITEM_CAPWAP_TIMERS,
CW_MAX_DISCOVERY_INTERVAL << 8 |
CAPWAP_ECHO_INTERVAL);
*/
/* start echinterval timer and put 2 seconds for "safety" on it */
/*
// wtpman->echointerval_timer = cw_timer_start(2+ (ct & 0xff));
// db_ping_wtp(sock_addr2str_p(&wtpman->conn->addr,sock_buf), conf_acname);
// cw_dbg(DBG_X, "Starting capwap timer: %d", wtpman->echointerval_timer);
*/
}
static int msg_start_handler(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len, struct sockaddr *from)
{
struct wtpman *wtpman = conn->data;
reset_echointerval_timer(wtpman);
return 0;
}
static void wtpman_remove(struct wtpman *wtpman) static void wtpman_remove(struct wtpman *wtpman)
{ {
@ -86,26 +57,30 @@ static void wtpman_remove(struct wtpman *wtpman)
static void wtpman_run_discovery(void *arg) static void wtpman_run_discovery(void *arg)
{ {
struct wtpman *wtpman = (struct wtpman *) arg; struct wtpman *wtpman = (struct wtpman *) arg;
time_t timer = cw_timer_start(10); time_t timer = cw_timer_start(10);
wtpman->conn->capwap_state = CAPWAP_STATE_DISCOVERY; wtpman->conn->capwap_state = CAPWAP_STATE_DISCOVERY;
while (!cw_timer_timeout(timer) while (!cw_timer_timeout(timer)
&& wtpman->conn->capwap_state == CAPWAP_STATE_DISCOVERY) { && wtpman->conn->capwap_state == CAPWAP_STATE_DISCOVERY) {
int rc; int rc;
rc = cw_read_messages(wtpman->conn); rc = cw_read_messages(wtpman->conn);
if (cw_result_is_ok(rc)) { if (cw_result_is_ok(rc)) {
wtpman->conn->capwap_state = CAPWAP_STATE_JOIN; wtpman->conn->capwap_state = CAPWAP_STATE_JOIN;
cw_dbg(DBG_INFO, "Discovery has detected mods: %s %s", cw_dbg(DBG_INFO, "Discovery has detected mods: %s %s",
wtpman->conn->cmod->name,wtpman->conn->bmod->name); wtpman->conn->cmod->name,
wtpman->conn->bmod->name);
wtplist_lock(); wtplist_lock();
discovery_cache_add(discovery_cache,(struct sockaddr*)&wtpman->conn->addr, discovery_cache_add(discovery_cache,
wtpman->conn->cmod,wtpman->conn->bmod); (struct sockaddr *) &wtpman->conn->
addr, wtpman->conn->cmod,
wtpman->conn->bmod);
wtplist_unlock(); wtplist_unlock();
} }
@ -129,28 +104,32 @@ static int wtpman_dtls_setup(void *arg)
} }
cw_dbg(DBG_DTLS, "DTLS session established with %s, %s", cw_dbg(DBG_DTLS, "DTLS session established with %s, %s",
sock_addr2str_p(&wtpman->conn->addr,sock_buf), dtls_get_cipher(wtpman->conn,cipherstr)); sock_addr2str_p(&wtpman->conn->addr, sock_buf),
dtls_get_cipher(wtpman->conn, cipherstr));
return 1; return 1;
} }
/*
static int wtpman_join(void *arg) static int wtpman_join(void *arg)
{ {
int rc; int rc;
char sock_buf[SOCK_ADDR_BUFSIZE]; char sock_buf[SOCK_ADDR_BUFSIZE];
struct wtpman *wtpman = (struct wtpman *) arg; struct wtpman *wtpman = (struct wtpman *) arg;
struct conn *conn = wtpman->conn; struct cw_Conn *conn = wtpman->conn;
time_t timer, wait_join; time_t timer, wait_join;
cw_dbg(DBG_INFO, "Join State - %s", sock_addr2str(&conn->addr,sock_buf)); cw_dbg(DBG_INFO, "Join State - %s",
sock_addr2str(&conn->addr, sock_buf));
wait_join = cw_ktv_get_word(conn->global_cfg,"wait-join",CAPWAP_WAIT_JOIN); wait_join =
cw_ktv_get_word(conn->global_cfg, "wait-join", CAPWAP_WAIT_JOIN);
timer = cw_timer_start(wait_join); timer = cw_timer_start(wait_join);
while (!cw_timer_timeout(timer) && wtpman->conn->capwap_state == CAPWAP_STATE_JOIN) { while (!cw_timer_timeout(timer)
&& wtpman->conn->capwap_state == CAPWAP_STATE_JOIN) {
rc = cw_read_messages(wtpman->conn); rc = cw_read_messages(wtpman->conn);
if (rc < 0) { if (rc < 0) {
if (errno == EAGAIN) if (errno == EAGAIN)
@ -170,7 +149,8 @@ static int wtpman_join(void *arg)
if (wtpman->conn->capwap_state != CAPWAP_STATE_JOIN_COMPLETE) { if (wtpman->conn->capwap_state != CAPWAP_STATE_JOIN_COMPLETE) {
cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.", cw_dbg(DBG_MSG_ERR,
"No join request from %s after %d seconds, WTP died.",
sock_addr2str(&wtpman->conn->addr, sock_buf), wait_join); sock_addr2str(&wtpman->conn->addr, sock_buf), wait_join);
return 0; return 0;
@ -181,11 +161,14 @@ static int wtpman_join(void *arg)
} }
*/
static void wtpman_image_data(struct wtpman *wtpman) static void wtpman_image_data(struct wtpman *wtpman)
{ {
/* char sock_buf[SOCK_ADDR_BUFSIZE]; /* char sock_buf[SOCK_ADDR_BUFSIZE];
struct conn *conn = wtpman->conn; struct cw_Conn *conn = wtpman->conn;
// Image upload // Image upload
const char *filename = mbag_get_str(conn->outgoing, CW_ITEM_IMAGE_FILENAME, NULL); const char *filename = mbag_get_str(conn->outgoing, CW_ITEM_IMAGE_FILENAME, NULL);
@ -247,7 +230,7 @@ void * wtpman_run_data(void *wtpman_arg)
return NULL; return NULL;
/* /*
struct wtpman *wtpman = (struct wtpman *) wtpman_arg; struct wtpman *wtpman = (struct wtpman *) wtpman_arg;
struct conn *conn = wtpman->conn; struct cw_Conn *conn = wtpman->conn;
uint8_t data[1001]; uint8_t data[1001];
@ -263,7 +246,9 @@ void * wtpman_run_data(void *wtpman_arg)
} }
int cw_run_state_machine(struct conn * conn, time_t *timer)
int cw_run_state_machine(struct cw_Conn *conn, time_t * timer)
{ {
int timerval; int timerval;
@ -273,7 +258,7 @@ int cw_run_state_machine(struct conn * conn, time_t *timer)
while (1) { while (1) {
search.state = conn->capwap_state; search.state = conn->capwap_state;
search.prevstate = conn->capwap_prevstate; search.prevstate = conn->capwap_prevstate;
result = mavl_get(conn->msgset->state_machine,&search); result = mavl_get(conn->msgset->statemachine_states, &search);
cw_dbg(DBG_STATE, "State transition: [%s -> %s]", cw_dbg(DBG_STATE, "State transition: [%s -> %s]",
cw_strstate(conn->capwap_prevstate), cw_strstate(conn->capwap_prevstate),
@ -298,9 +283,12 @@ int cw_run_state_machine(struct conn * conn, time_t *timer)
} }
if (result->timer_key) { if (result->timer_key) {
timerval = cw_ktv_get_word(conn->local_cfg,result->timer_key,result->timer_default); timerval =
cw_cfg_get_word(conn->local_cfg, result->timer_key,
result->timer_default);
*timer = cw_timer_start(timerval); *timer = cw_timer_start(timerval);
cw_dbg(DBG_STATE,"Starting timer: [%s] - %d seconds.",result->timer_key,timerval); cw_dbg(DBG_STATE, "Starting timer: [%s] - %d seconds.",
result->timer_key, timerval);
} }
return result->retval; return result->retval;
} }
@ -315,20 +303,19 @@ static void * wtpman_main(void *arg)
int rc; int rc;
time_t timer; time_t timer;
char sock_buf[SOCK_ADDR_BUFSIZE]; char sock_buf[SOCK_ADDR_BUFSIZE];
struct conn *conn; struct cw_Conn *conn;
int last_state; int last_state;
struct wtpman *wtpman = (struct wtpman *) arg; struct wtpman *wtpman = (struct wtpman *) arg;
wtpman->conn->seqnum = 0; wtpman->conn->seqnum = 0;
conn = wtpman->conn; conn = wtpman->conn;
wtpman->conn->remote_cfg = cw_ktv_create(); wtpman->conn->remote_cfg = cw_cfg_create();
if (!wtpman->dtlsmode) {
/* We were invoked with an unencrypted packet, /* We were invoked with an unencrypted packet,
* so assume, it is a discovery request */ * so assume, it is a discovery request */
if (!wtpman->dtlsmode){
wtpman_run_discovery(arg); wtpman_run_discovery(arg);
wtpman_remove(wtpman); wtpman_remove(wtpman);
return NULL; return NULL;
@ -377,7 +364,7 @@ static void * wtpman_main(void *arg)
tmp = conn->local_cfg; tmp = conn->local_cfg;
mavl_merge(conn->default_cfg, conn->local_cfg); /* mavl_merge(conn->default_cfg, conn->local_cfg);*/
/* mavl_merge(conn->default_cfg, conn->remote_cfg);*/ /* mavl_merge(conn->default_cfg, conn->remote_cfg);*/
conn->local_cfg = conn->update_cfg; conn->local_cfg = conn->update_cfg;
@ -386,9 +373,11 @@ static void * wtpman_main(void *arg)
cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr,sock_buf)); cw_dbg(DBG_INFO, "Updating WTP %s",
sock_addr2str(&conn->addr, sock_buf));
rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST); rc = cw_send_request(conn,
CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
mavl_merge(conn->remote_cfg, conn->update_cfg); mavl_merge(conn->remote_cfg, conn->update_cfg);
conn->update_cfg = NULL; conn->update_cfg = NULL;
@ -469,7 +458,9 @@ exit(0);
} }
} }
cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP","---------end dump --------"); cw_dbg_ktv_dump(conn->remote_cfg, DBG_INFO,
"-------------dump------------", "DMP",
"---------end dump --------");
if (!cw_result_is_ok(rc)) { if (!cw_result_is_ok(rc)) {
cw_dbg(DBG_INFO, "WTP Problem: %s", cw_strrc(rc)); cw_dbg(DBG_INFO, "WTP Problem: %s", cw_strrc(rc));
@ -526,16 +517,19 @@ cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP",
r = db_get_update_tasks(conn, sock_addr2str(&conn->addr,sock_buf)); r = db_get_update_tasks(conn,
sock_addr2str(&conn->addr, sock_buf));
if (r) { if (r) {
/* /*
// if (!conn->outgoing->count) // if (!conn->outgoing->count)
// continue; // continue;
*/ */
cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr,sock_buf)); cw_dbg(DBG_INFO, "Updating WTP %s",
sock_addr2str(&conn->addr, sock_buf));
rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST); rc = cw_send_request(conn,
CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
/* /*
// mavl_merge(conn->config, conn->outgoing); // mavl_merge(conn->config, conn->outgoing);
@ -547,15 +541,18 @@ cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP",
*/ */
} }
r = db_get_radio_tasks(conn, sock_addr2str(&conn->addr,sock_buf)); r = db_get_radio_tasks(conn,
sock_addr2str(&conn->addr, sock_buf));
if (r) { if (r) {
/* /*
// if (!conn->radios_upd->count) // if (!conn->radios_upd->count)
// continue; // continue;
*/ */
cw_dbg(DBG_INFO, "Updating Radios for %s",sock_addr2str(&conn->addr,sock_buf)); cw_dbg(DBG_INFO, "Updating Radios for %s",
rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST); sock_addr2str(&conn->addr, sock_buf));
rc = cw_send_request(conn,
CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
/* /*
// conn_clear_upd(conn,1); // conn_clear_upd(conn,1);
@ -596,7 +593,8 @@ static void wtpman_run_dtls(void *arg)
/* reject connections to our multi- or broadcast sockets */ /* reject connections to our multi- or broadcast sockets */
if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET) { if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
cw_dbg(DBG_DTLS, "Dropping connection from %s to non-unicast socket.", cw_dbg(DBG_DTLS,
"Dropping connection from %s to non-unicast socket.",
sock_addr2str_p(&wtpman->conn->addr, sock_buf)); sock_addr2str_p(&wtpman->conn->addr, sock_buf));
wtpman_remove(wtpman); wtpman_remove(wtpman);
return; return;
@ -618,12 +616,67 @@ void wtpman_destroy(struct wtpman *wtpman)
{ {
if (wtpman->conn) if (wtpman->conn)
conn_destroy(wtpman->conn); conn_destroy(wtpman->conn);
if (wtpman->wtp_cfg)
cw_cfg_destroy(wtpman->wtp_cfg);
free(wtpman); free(wtpman);
} }
static void copy(struct cw_ElemHandlerParams * params)
{
struct wtpman * wtpman;
wtpman = (struct wtpman*)params->conn->data;
struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dtlsmode) cw_dbg(DBG_X,"------------- Here is the config we ve got from WTP ---------------- ");
cw_cfg_dump(params->cfg);
cw_dbg(DBG_X,"------------- This was the config we ve got from WTP ---------------- ");
cw_dbg(DBG_X,"Now copying:");
cw_cfg_copy(params->cfg,wtpman->wtp_cfg);
cw_dbg(DBG_X,"Copying done.");
}
static int discovery_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
cw_dbg(DBG_X,"DISCOVERY Callback");
copy(params);
cw_cfg_clear(params->cfg);
return 0;
}
static int join_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
cw_dbg(DBG_X,"JOIN Callback");
copy(params);
cw_cfg_clear(params->cfg);
return 0;
}
static int update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
cw_dbg(DBG_X,"UPDATE Callback");
copy(params);
cw_cfg_clear(params->cfg);
return 0;
}
static setup_complete(struct cw_Conn *conn)
{
struct wtpman * wtpman = (struct wtpman *)conn->data;
// wtpman->pjoin = cw_msgset_set_postprocess(conn->msgset,CAPWAP_MSG_JOIN_REQUEST,join_cb);
// wtpman->pupdate = cw_msgset_set_postprocess(conn->msgset,CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,update_cb);
cw_dbg(DBG_X,"SETUP COMPLETE");
}
struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
int dtlsmode, cw_Cfg_t * global_cfg)
{ {
struct sockaddr dbgaddr; struct sockaddr dbgaddr;
socklen_t dbgaddrl; socklen_t dbgaddrl;
@ -634,7 +687,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dt
wtpman = malloc(sizeof(struct wtpman)); wtpman = malloc(sizeof(struct wtpman));
if (!wtpman) if (!wtpman)
return 0; return 0;
memset(wtpman, 0, sizeof(struct wtpman));
if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) { if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
@ -642,7 +694,8 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dt
replyfd = socklist_find_reply_socket(srcaddr, port); replyfd = socklist_find_reply_socket(srcaddr, port);
if (replyfd == -1) { if (replyfd == -1) {
cw_log(LOG_ERR, "Can't find reply socket for request from %s", cw_log(LOG_ERR,
"Can't find reply socket for request from %s",
sock_addr2str(srcaddr, sock_buf)); sock_addr2str(srcaddr, sock_buf));
free(wtpman); free(wtpman);
return NULL; return NULL;
@ -654,11 +707,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dt
sockfd = replyfd; /*//socklist[socklistindex].reply_sockfd; */ sockfd = replyfd; /*//socklist[socklistindex].reply_sockfd; */
dbgaddrl = sizeof(dbgaddr); dbgaddrl = sizeof(dbgaddr);
getsockname(sockfd, &dbgaddr, &dbgaddrl); getsockname(sockfd, &dbgaddr, &dbgaddrl);
@ -666,28 +714,48 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dt
sock_addr2str(&dbgaddr, sock_buf), sock_getport(&dbgaddr)); sock_addr2str(&dbgaddr, sock_buf), sock_getport(&dbgaddr));
memset(wtpman, 0, sizeof(struct wtpman));
wtpman->conn = conn_create(sockfd, srcaddr, 100); wtpman->global_cfg = global_cfg;
wtpman->conn->role = CW_ROLE_AC;
wtpman->conn->data_sock = socklist[socklistindex].data_sockfd;
sock_copyaddr(&wtpman->conn->data_addr, (struct sockaddr *) &wtpman->conn->addr);
wtpman->conn = cw_conn_create(sockfd, srcaddr, 5);
if (!wtpman->conn) { if (!wtpman->conn) {
wtpman_destroy(wtpman); wtpman_destroy(wtpman);
return NULL; return NULL;
} }
wtpman->conn->global_cfg = global_cfg;
wtpman->conn->local_cfg = cw_cfg_create();
wtpman->wtp_cfg = cw_cfg_create();
wtpman->conn->role = CW_ROLE_AC;
wtpman->conn->data=wtpman;
wtpman->conn->data_sock = socklist[socklistindex].data_sockfd;
sock_copyaddr(&wtpman->conn->data_addr,
(struct sockaddr *) &wtpman->conn->addr);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_DISCOVERY_REQUEST,
discovery_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_JOIN_REQUEST,
join_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,
update_cb);
// wtpman->conn->mods = conf_mods;
wtpman->conn->mods = conf_mods;
wtpman->conn->strict_capwap = conf_strict_capwap; wtpman->conn->strict_capwap = conf_strict_capwap;
wtpman->conn->strict_hdr = conf_strict_headers; wtpman->conn->strict_hdr = conf_strict_headers;
wtpman->conn->setup_complete = setup_complete;
/* /*
// wtpman->conn->radios = mbag_i_create(); // wtpman->conn->radios = mbag_i_create();
// wtpman->conn->radios_upd = mbag_i_create(); // wtpman->conn->radios_upd = mbag_i_create();
@ -698,9 +766,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dt
*/ */
wtpman->conn->local_cfg = cw_ktv_create();
wtpman->conn->global_cfg = actube_global_cfg;
wtpman->conn->local_cfg = actube_global_cfg;
/* when created caused by a packet in DTLS mode, we try /* when created caused by a packet in DTLS mode, we try
* to find out the modules to load, for detected connection * to find out the modules to load, for detected connection
@ -709,21 +774,31 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dt
int rc; int rc;
struct cw_Mod *cmod, *bmod; struct cw_Mod *cmod, *bmod;
rc = discovery_cache_get(discovery_cache,srcaddr,&cmod,&bmod); rc = discovery_cache_get(discovery_cache, srcaddr, &cmod,
&bmod);
if (rc) { if (rc) {
cw_dbg(DBG_INFO, "Initializing with mod %s %s",cmod->name,bmod->name); cw_dbg(DBG_INFO, "Initializing with mod %s %s",
wtpman->conn->msgset = cw_mod_get_msg_set(wtpman->conn,cmod,bmod); cmod->name, bmod->name);
wtpman->conn->msgset =
cw_mod_get_msg_set(wtpman->conn, cmod, bmod);
wtpman->conn->detected = 1; wtpman->conn->detected = 1;
cmod->setup_cfg(wtpman->conn); cmod->setup_cfg(wtpman->conn);
if (wtpman->conn->setup_complete)
wtpman->conn->setup_complete(wtpman->conn);
} }
} }
cw_dbg(DBG_X,"WTPMAN_CREATED: %p",wtpman);
return wtpman; return wtpman;
} }
void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len) void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len)
{ {
// cw_dbg(DBG_X,"ADD PACKET DETECTED %d",wtpman->conn->detected);
conn_q_add_packet(wtpman->conn, packet, len); conn_q_add_packet(wtpman->conn, packet, len);
} }
@ -731,12 +806,6 @@ void wtpman_start(struct wtpman *wtpman, int dtlsmode)
{ {
cw_dbg(DBG_INFO, "Starting wtpman, DTLS mode = %d", dtlsmode); cw_dbg(DBG_INFO, "Starting wtpman, DTLS mode = %d", dtlsmode);
wtpman->dtlsmode = dtlsmode; wtpman->dtlsmode = dtlsmode;
pthread_create(&wtpman->thread, NULL, wtpman_main, pthread_create(&wtpman->thread, NULL, wtpman_main, (void *) wtpman);
(void *) wtpman);
return; return;
} }

View File

@ -8,13 +8,15 @@
#include "cw/capwap.h" #include "cw/capwap.h"
#include "cw/fragman.h" #include "cw/fragman.h"
#include "cw/timer.h" #include "cw/timer.h"
#include "cw/cfg.h"
#include "cw/capwap.h"
#define WTPMAN_QSIZE 1024 #define WTPMAN_QSIZE 1024
struct wtpman { struct wtpman {
pthread_t thread; pthread_t thread;
struct conn * conn; struct cw_Conn *conn;
/* wtp data */ /* wtp data */
@ -30,6 +32,15 @@ struct wtpman{
cw_timer_t echointerval_timer; cw_timer_t echointerval_timer;
cw_Cfg_t * global_cfg; /**< contains the cfg of AC,
visible to all wtpman threads.
The global cfg was initally read
from a .ckv file on startup.
*/
cw_Cfg_t * wtp_cfg;
}; };
@ -45,7 +56,8 @@ struct wtp{
struct wtpman *wtpman_create(); struct wtpman *wtpman_create();
struct wtpman * wtpman_create(int socklistindex,struct sockaddr * srcaddr, int dtlsmode); struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
int dtlsmode, cw_Cfg_t * global_cfg);
extern void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len); extern void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len);
extern void wtpman_destroy(struct wtpman *wtpman); extern void wtpman_destroy(struct wtpman *wtpman);

View File

@ -1743,7 +1743,7 @@ RTF_EXTENSIONS_FILE =
# classes and files. # classes and files.
# The default value is: NO. # The default value is: NO.
GENERATE_MAN = NO GENERATE_MAN = YES
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a # The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@ -1770,7 +1770,7 @@ MAN_EXTENSION = .3
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_MAN is set to YES. # This tag requires that the tag GENERATE_MAN is set to YES.
MAN_LINKS = NO MAN_LINKS = YES
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the XML output # Configuration options related to the XML output

View File

@ -3,6 +3,7 @@ MFDEPS=../Defs.mak
CWSRC=\ CWSRC=\
cw.c\
cw_check_missing_mand.c\ cw_check_missing_mand.c\
cw_clock_lap.c\ cw_clock_lap.c\
cw_dbg_elem.c\ cw_dbg_elem.c\
@ -16,13 +17,6 @@ CWSRC=\
cw_in_ac_name_with_priority.c\ cw_in_ac_name_with_priority.c\
cw_in_capwap_local_ipv4_address.c\ cw_in_capwap_local_ipv4_address.c\
cw_in_capwap_local_ipv6_address.c\ cw_in_capwap_local_ipv6_address.c\
cw_in_check_cfg_update_req.c\
cw_in_check_disc_req.c\
cw_in_check_img_data_req_ac.c\
cw_in_check_img_data_req_wtp.c\
cw_in_check_join_req.c\
cw_in_check_join_resp.c\
cw_in_generic.c\
cw_in_generic_with_index.c\ cw_in_generic_with_index.c\
cw_in_generic_struct.c\ cw_in_generic_struct.c\
cw_in_radio_generic_struct.c\ cw_in_radio_generic_struct.c\
@ -38,7 +32,6 @@ CWSRC=\
cw_in_wtp_reboot_statistics.c\ cw_in_wtp_reboot_statistics.c\
cw_is_printable.c\ cw_is_printable.c\
cw_load_file.c\ cw_load_file.c\
cw_out_generic.c\
cw_out_generic_with_index.c\ cw_out_generic_with_index.c\
cw_out_radio_administrative_states.c\ cw_out_radio_administrative_states.c\
cw_process_element.c\ cw_process_element.c\
@ -46,7 +39,6 @@ CWSRC=\
cw_put_elem_radio_operational_state.c\ cw_put_elem_radio_operational_state.c\
cw_put_image_data.c\ cw_put_image_data.c\
cw_put_local_ip_address.c\ cw_put_local_ip_address.c\
cw_put_msg.c\
cw_radio_set_admin_state.c\ cw_radio_set_admin_state.c\
cw_rand.c\ cw_rand.c\
cw_randint.c\ cw_randint.c\
@ -68,13 +60,23 @@ CWSRC=\
cw_type_bool.c\ cw_type_bool.c\
cw_type_str.c\ cw_type_str.c\
cw_type_dword.c\ cw_type_dword.c\
cw_type_struct.c\
cw_type_ipaddress.c\ cw_type_ipaddress.c\
cw_type_word.c\ cw_type_word.c\
cw_type_sysptr.c\ cw_type_sysptr.c\
cw_write_descriptor_subelem.c\ cw_write_descriptor_subelem.c\
cw_read_from.c \
cw_write_radio_element.c\ cw_write_radio_element.c\
cw_detect_nat.c\ cw_detect_nat.c\
cw_read_from.c \
# cw_in_check_disc_req.c\
# cw_in_check_img_data_req_ac.c\
# cw_in_check_img_data_req_wtp.c\
# cw_in_check_join_req.c\
# cw_in_check_join_resp.c\
# cw_in_generic.c\
# cw_out_generic.c\
#
KTVSRC=\ KTVSRC=\
cw_ktv_add.c\ cw_ktv_add.c\
@ -101,12 +103,12 @@ KTVSRC=\
cw_ktv_read_struct.c\ cw_ktv_read_struct.c\
cw_ktv_write_struct.c\ cw_ktv_write_struct.c\
cw_ktv_std_types.c\ cw_ktv_std_types.c\
cw_ktv_base_exists.c\
cw_ktv_save.c\ cw_ktv_save.c\
cw_ktv_del_sub.c\
cw_ktv_parser.c\
cfg.c\ cfg.c\
# cw_ktv_parser.c\
# cw_ktv_del_sub.c\
# cw_ktv_base_exists.c\
LWSRC=\ LWSRC=\
lw_addelem.c\ lw_addelem.c\
@ -176,23 +178,17 @@ MISCSRC=\
capwap_strings_result.c\ capwap_strings_result.c\
capwap_strings_state.c\ capwap_strings_state.c\
capwap_strings_vendor.c\ capwap_strings_vendor.c\
conn_create.c\
conn_create_noq.c\ conn_create_noq.c\
conn_destroy.c\
conn_init.c\
connlist.c\ connlist.c\
conn_prepare_image_data_request.c\ conn_prepare_image_data_request.c\
conn_process_packet.c\
cw_decode_msg.c \ cw_decode_msg.c \
conn_q_add_packet.c\ conn_q_add_packet.c\
conn_q_get_packet.c\ conn_q_get_packet.c\
conn_q_wait_packet.c\
conn_q_recv_packet.c\ conn_q_recv_packet.c\
conn_recv_packet.c\ conn_recv_packet.c\
conn_send_data_packet.c\ conn_send_data_packet.c\
conn_send_msg.c\ conn_send_msg.c\
conn_send_packet.c\ conn_send_packet.c\
conn_send_request.c\
dot11.c\ dot11.c\
dot11_inline.c\ dot11_inline.c\
format.c\ format.c\
@ -202,9 +198,21 @@ MISCSRC=\
md5sum.c\ md5sum.c\
mod.c\ mod.c\
msgset.c\ msgset.c\
netconn.c\
send.c\ send.c\
strheap.c\ strheap.c\
netconn.c\
conn.c \
val.c \
discovery.c\
# conn_q_wait_packet.c\
# conn_init.c\
# conn_create.c\
# conn_send_request.c\
# cw_put_msg.c\
# conn_process_packet.c\
# conn_destroy.c\
DTLSSRC+=\ DTLSSRC+=\
dtls_bio.c\ dtls_bio.c\
@ -212,9 +220,10 @@ DTLSSRC+=\
RADIOSRC=\ RADIOSRC=\
cw_out_radio_generic.c\
cw_out_radio_generic_struct.c\ cw_out_radio_generic_struct.c\
cw_read_radio_generic.c\
# cw_in_radio_generic.c\
# cw_out_radio_generic.c\
MAVLSRC=\ MAVLSRC=\
mavl_get_ptr.c\ mavl_get_ptr.c\
@ -265,3 +274,6 @@ dynamic: $(DNAME)
include ../lib.mk include ../lib.mk
depend:
mkdep -c ${CFLAGS} ${SOURCES}

View File

@ -140,7 +140,7 @@ static inline int bstr16_ncpy(uint8_t *dst,uint8_t*src,uint16_t len)
bstr16_t bstr16_create(const uint8_t *data, uint16_t len); bstr16_t bstr16_create(const uint8_t *data, uint16_t len);
uint8_t * bstr16_create_from_str(const char *s); bstr16_t bstr16_create_from_str(const char *s);
extern uint8_t * bstr16_create_from_cfgstr(const char * s); extern uint8_t * bstr16_create_from_cfgstr(const char * s);
#define bstr16_replace bstr_replace #define bstr16_replace bstr_replace

View File

@ -2,7 +2,7 @@
#include "format.h" #include "format.h"
uint8_t * bstr16_create_from_str(const char *s) bstr16_t bstr16_create_from_str(const char *s)
{ {
uint8_t * mem; uint8_t * mem;
int msize; int msize;

View File

@ -1,18 +0,0 @@
#include "bstr.h"
/*
uint8_t * bstrv_create(uint32_t vendor_id, uint8_t *data, uint8_t len)
{
uint8_t * str = malloc(bstrv_size(len));
if (!str)
return 0;
bstrv_set_vendor_id(str,vendor_id);
bstrv_set_len(str,len);
memcpy(bstrv_data(str),data,len);
*(bstrv_data(str)+bstrv_len(str))=0;
return str;
}
*/

View File

@ -641,14 +641,10 @@ struct cw_ac_status {
*/ */
enum capwap_states { enum capwap_states {
CW_STATE_NONE = 0, CW_STATE_NONE = 0,
/** Discovery State */ CAPWAP_STATE_DISCOVERY, /**< Discovery State */
CAPWAP_STATE_DISCOVERY, CAPWAP_STATE_JOIN, /**< Join State */
/** Join State */
CAPWAP_STATE_JOIN,
CAPWAP_STATE_JOIN_COMPLETE, CAPWAP_STATE_JOIN_COMPLETE,
CAPWAP_STATE_CONFIGURE, /**< Config State */
/** Config State */
CAPWAP_STATE_CONFIGURE,
CAPWAP_STATE_DTLS_SETUP, /**< DTLS Setup */ CAPWAP_STATE_DTLS_SETUP, /**< DTLS Setup */
/** Image Data Upload */ /** Image Data Upload */
CW_STATE_IMAGE_DATA, CW_STATE_IMAGE_DATA,

View File

@ -2,6 +2,7 @@
#include "capwap.h" #include "capwap.h"
struct cw_StrListElem capwap_strings_state[] = { struct cw_StrListElem capwap_strings_state[] = {
{ CW_STATE_NONE, "None"},
{ CAPWAP_STATE_DISCOVERY, "Discovery" }, { CAPWAP_STATE_DISCOVERY, "Discovery" },
{ CAPWAP_STATE_JOIN,"Join" }, { CAPWAP_STATE_JOIN,"Join" },
{ CAPWAP_STATE_RUN,"Run" }, { CAPWAP_STATE_RUN,"Run" },
@ -11,6 +12,5 @@ struct cw_StrListElem capwap_strings_state[] = {
{ CAPWAP_STATE_DATA_CHECK, "Data Check" }, { CAPWAP_STATE_DATA_CHECK, "Data Check" },
{ CAPWAP_STATE_TIMEOUT, "Timeout"}, { CAPWAP_STATE_TIMEOUT, "Timeout"},
{ CW_STR_STOP,"Undefined" }, { CW_STR_STOP,"Undefined" },
}; };

View File

@ -3,23 +3,81 @@
#include <mavl.h> #include <mavl.h>
#include "cw.h"
#include "cfg.h"
#include "val.h" #include "val.h"
#include "cfg.h"
static int cmp(const void *k1,const void*k2){
#include "dbg.h"
#include "log.h"
#include "cw.h"
static const char *nextc(const char *s)
{
while (isdigit(*s))
s++;
return s;
}
static int cmp0(const char *s1, const char *s2)
{
const char *d1, *d2;
int i1, i2, i;
d1 = strchr(s1, '.');
if (d1 == NULL)
return strcmp(s1, s2);
d2 = strchr(s2, '.');
if (d2 == NULL)
return strcmp(s1, s2);
if ((d1 - s1) != (d2 - s2))
return strcmp(s1, s2);
if (strncmp(s1, s2, (d1 - s1)) != 0)
return strcmp(s1, s2);
if (isdigit(d1[1])) {
i1 = atoi(d1 + 1);
} else {
return cmp0(d1 + 1, d2 + 1);
}
if (isdigit(d2[1])) {
i2 = atoi(d2 + 1);
} else {
return cmp0(d1 + 1, d2 + 1);
}
i = i1 - i2;
if (i == 0) {
return cmp0(nextc(d1 + 1), nextc(d2 + 1));
}
return i;
}
static int cmp(const void *k1, const void *k2)
{
struct cw_Cfg_entry *e1, *e2; struct cw_Cfg_entry *e1, *e2;
e1 = (struct cw_Cfg_entry *) k1; e1 = (struct cw_Cfg_entry *) k1;
e2 = (struct cw_Cfg_entry *) k2; e2 = (struct cw_Cfg_entry *) k2;
return strcmp(e1->key,e2->key);
return cmp0(e1->key, e2->key);
/* return strcmp(e1->key,e2->key);*/
} }
static void del(void *ptr) static void del(void *ptr)
{ {
struct cw_Cfg_entry *e; struct cw_Cfg_entry *e;
e = (struct cw_Cfg_entry *) ptr; e = (struct cw_Cfg_entry *) ptr;
free(e->key); free((void *) e->key);
free(e->val); free((void *) e->val);
} }
@ -30,6 +88,8 @@ cw_Cfg_t * cw_cfg_create()
int cw_cfg_set(cw_Cfg_t * cfg, const char *key, const char *val) int cw_cfg_set(cw_Cfg_t * cfg, const char *key, const char *val)
{ {
cw_dbg(DBG_CFG_SET, "%s: %s",key,val);
struct cw_Cfg_entry e; struct cw_Cfg_entry e;
int replaced; int replaced;
@ -38,7 +98,7 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val)
return 0; return 0;
e.val = cw_strdup(val); e.val = cw_strdup(val);
if (!e.val) { if (!e.val) {
free(e.key); free((void *) e.key);
return 0; return 0;
} }
void *rc = mavl_replace(cfg, &e, &replaced); void *rc = mavl_replace(cfg, &e, &replaced);
@ -52,21 +112,54 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val)
return -1; return -1;
} }
char * cw_cfg_get(cw_Cfg_t * cfg, char *key) const char *cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def)
{ {
struct cw_Cfg_entry e, *r; struct cw_Cfg_entry e, *r;
e.key = key; e.key = key;
r = mavl_get(cfg, &e); r = mavl_get(cfg, &e);
if (!r) if (!r)
return NULL; return def;
return r->val; return r->val;
} }
const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def)
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key)
{ {
int i;
struct cw_Cfg_entry e, *r;
for(i=0; cfg[i]!=NULL; i++){
e.key = key;
r = mavl_get(cfg[i], &e);
if (r!=NULL)
return r->val;
} }
return def;
}
const char *cw_cfg_get2(cw_Cfg_t *cfg1, cw_Cfg_t *cfg2, const char *key, const char *def)
{
return cw_cfg_get(cfg1, key, cw_cfg_get(cfg2,key,def));
}
bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def)
{
const char *s;
s = cw_cfg_get(cfg,key,def);
if(s==NULL)
return NULL;
return bstr16_create_from_str(s);
}
int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str)
{
CW_TYPE_BSTR16->read(cfg,key,bstr16_data(str),bstr16_len(str),NULL);
return 0;
}
void cw_cfg_dump(cw_Cfg_t * cfg) void cw_cfg_dump(cw_Cfg_t * cfg)
@ -107,13 +200,13 @@ static int get_char(struct parser *p)
return c; return c;
} }
static void unget_char(struct parser *p,int c){ static void unget_char(struct parser *p, int c)
{
ungetc(c, p->f); ungetc(c, p->f);
if (c == '\n') { if (c == '\n') {
p->line--; p->line--;
p->pos = p->prevpos; p->pos = p->prevpos;
} } else
else
p->pos--; p->pos--;
} }
@ -210,7 +303,8 @@ static int read_key (struct parser *p, char *key, int max_len)
n = 0; n = 0;
while (c != EOF && n < max_len) { while (c != EOF && n < max_len) {
if (!p->quote && !isalnum(c) && !strchr("._/-()@#|{}[]\\",c)/*strchr(": \t\n\a",c)*/){ if (!p->quote && !isalnum(c)
&& !strchr("._/-()@#|{}[]\\", c) /*strchr(": \t\n\a",c) */ ) {
unget_char(p, c); unget_char(p, c);
break; break;
} }
@ -233,10 +327,13 @@ static int skip_to_colon(FILE *f,struct parser * p)
if (c != ':') { if (c != ':') {
if (c == '\n') { if (c == '\n') {
unget_char(p, c); unget_char(p, c);
sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL, collon expected.", p->line, p->pos); sprintf(p->error,
"Error at line %d, pos %d: Unexpected EOL, collon expected.",
p->line, p->pos);
return 0; return 0;
} }
sprintf(p->error,"Error at line %d, pos %d: Collon expected.", p->line, p->pos); sprintf(p->error, "Error at line %d, pos %d: Collon expected.",
p->line, p->pos);
return 0; return 0;
} }
return 1; return 1;
@ -244,7 +341,8 @@ static int skip_to_colon(FILE *f,struct parser * p)
static int read_val(struct parser *p, char *val, int max_len){ static int read_val(struct parser *p, char *val, int max_len)
{
int c, n, quote; int c, n, quote;
if (!skip_to_colon(p->f, p)) if (!skip_to_colon(p->f, p))
return -1; return -1;
@ -252,8 +350,7 @@ static int read_val(struct parser *p, char *val, int max_len){
if (c == '"') { if (c == '"') {
quote = 1; quote = 1;
c = get_char(p); c = get_char(p);
} } else {
else{
quote = 0; quote = 0;
} }
n = 0; n = 0;
@ -368,5 +465,242 @@ int cw_cfg_load(const char *filename,cw_Cfg_t * cfg)
return errno; return errno;
errs = cw_cfg_read_from_file(f, cfg); errs = cw_cfg_read_from_file(f, cfg);
fclose(f); fclose(f);
return errs;
if (errs)
errno = EINVAL;
return errno;
}
void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base)
{
struct cw_Cfg_entry search;
search.key = base;
mavliter_init(&(cfi->it), cfg);
mavliter_seek(&(cfi->it), &search, 0);
cfi->base = base;
}
const char *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *key)
{
struct cw_Cfg_entry *e;
int bl, kl;
const char *d;
e = mavliter_get(&(cfi->it));
if (e == NULL)
return NULL;
bl = strlen(cfi->base);
kl = strlen(e->key);
if (bl > kl)
return NULL;
if (bl == kl) {
if (strcmp(cfi->base, e->key) != 0)
return NULL;
else {
mavliter_next(&(cfi->it));
return e->val;
}
}
d = strchr(e->key, '.');
if (d == NULL)
return NULL;
if (d - e->key != bl)
return NULL;
if (strncmp(cfi->base, e->key, bl) != 0)
return NULL;
mavliter_next(&(cfi->it));
return e->val;
}
int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, const char *def)
{
struct cw_Val v;
const char *s = cw_cfg_get(cfg,key,def);
CW_TYPE_BOOL->from_str(&v,s);
return v.val.boolean;
}
uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def)
{
struct cw_Val v;
memset(&v,0,sizeof(struct cw_Val));
const char *s = cw_cfg_get(cfg,key,NULL);
if (s==NULL)
return def;
CW_TYPE_BYTE->from_str(&v,s);
return v.val.byte;
}
uint8_t cw_cfg_get_byte_l(cw_Cfg_t ** cfgs, char *key, uint8_t def)
{
struct cw_Val v;
memset(&v,0,sizeof(struct cw_Val));
const char *s = cw_cfg_get_l(cfgs,key,NULL);
if (s==NULL)
return def;
CW_TYPE_BYTE->from_str(&v,s);
return v.val.byte;
}
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key, uint16_t def)
{
struct cw_Val v;
const char *s = cw_cfg_get(cfg,key,NULL);
if (s==NULL)
return def;
CW_TYPE_WORD->from_str(&v,s);
return v.val.word;
}
/*
int cw_cfg_get_word(cw_Cfg_t * cfg, char *key, const char * def)
{
const char *s;
s=cw_cfg_get(cfg,key,def);
if (s==NULL)
return 0;
}
*/
void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val)
{
char a[128];
sprintf(a,"%d",val);
cw_cfg_set(cfg,key,a);
}
int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key)
{
char ikey[CW_CFG_MAX_KEY_LEN];
struct cw_Cfg_entry search, * result;
char *d;
sprintf(ikey,"%s.%d",key,65536);
search.key=ikey;
/*//result = ktvn(ktv,&search);*/
result = mavl_get_last(cfg,&search);
if (result == NULL){
return 0;
}
d = strchr(result->key,'.');
if (d==NULL){
return 0;
}
if (strncmp(result->key,ikey,d-result->key)!=0)
return 0;
return atoi(d+1)+1;
}
int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *type, const void * valguard, const uint8_t * data, int len)
{
cw_Val_t mdata, *mresult;
char str[2048];
memset(&mdata,0,sizeof(cw_Val_t));
mdata.type=type;
mdata.valguard=valguard;
mresult = type->get(&mdata,data,len);
if (!mresult){
cw_log(LOG_ERR, "Can't create cfg element for key %s of type %s: %s",
key,type->name, strerror(errno));
free(mdata.key);
return 0;
}
type->to_str(&mdata,str,2048);
cw_cfg_set(cfg,key,str);
if (type->del)
type->del(&mdata);
return 1;
}
//int cw_cfg_put(cw_Cfg_t *cfg, const char *key, const struct cw_Type *type,const void
void cw_cfg_copy(cw_Cfg_t *src, cw_Cfg_t *dst)
{
mavliter_t it;
mavliter_init(&it, src);
mavliter_foreach(&it) {
int exists;
struct cw_Cfg_entry * old_elem,*e, new_elem;
e = mavliter_get(&it);
new_elem.key = cw_strdup(e->key);
new_elem.val = cw_strdup(e->val);
old_elem = mavl_insert(dst,&new_elem,&exists);
if (!exists){
cw_dbg(DBG_X, "New: %s: %s",new_elem.key,new_elem.val);
continue;
}
if (strcmp(new_elem.val,old_elem->val)==0){
free((void*)new_elem.key);
free((void*)new_elem.val);
continue;
}
cw_dbg(DBG_X, "Replace: %s: %s (old: %s)",new_elem.key, new_elem.val, old_elem->val);
if(dst->del){
dst->del(old_elem);
}
memcpy(old_elem,&new_elem,dst->data_size);
}
}
void cw_cfg_destroy(cw_Cfg_t *cfg)
{
mavl_destroy(cfg);
}
void cw_cfg_clear(cw_Cfg_t *cfg)
{
mavl_del_all(cfg);
}
int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key)
{
struct cw_Cfg_entry e, *result;
e.key=key;
result = mavl_get_first(cfg,&e);
if (result == NULL)
return 0;
if (strlen(result->key)<strlen(key))
return 0;
if (result->key[strlen(key)]!='/' && result->key[strlen(key)]!='.')
return 0;
if (strncmp(result->key,key,strlen(key))==0)
return 1;
return 0;
} }

View File

@ -2,6 +2,8 @@
#define _CFG_H #define _CFG_H
#include <mavl.h> #include <mavl.h>
#include "val.h"
#include "bstr.h"
#define CW_CFG_MAX_KEY_LEN 1024 #define CW_CFG_MAX_KEY_LEN 1024
@ -14,11 +16,46 @@ int cw_cfg_read_from_file(FILE * file, cw_Cfg_t * cfg);
int cw_cfg_load(const char *filename,cw_Cfg_t * cfg); int cw_cfg_load(const char *filename,cw_Cfg_t * cfg);
struct cw_Cfg_entry{ struct cw_Cfg_entry{
char *key; const char *key;
char *val; const char *val;
}; };
char * cw_cfg_get(cw_Cfg_t * cfg, char *key);
struct cw_Cfg_iter{
struct mavliter it;
const char *base;
};
const char * cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def);
const char *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *key);
void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base);
int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, const char *def);
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key, uint16_t def);
void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val);
uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def);
bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def);
int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str);
int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key);
const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def);
void cw_cfg_copy(cw_Cfg_t *src, cw_Cfg_t *dst);
void cw_cfg_destroy(cw_Cfg_t *cfg);
void cw_cfg_clear(cw_Cfg_t *cfg);
int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key);
uint8_t cw_cfg_get_byte_l(cw_Cfg_t ** cfgs, char *key, uint8_t def);
int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *t, const void * valguard, const uint8_t * data, int len);
#define cw_cfg_get_word2(cfg1,cfg2,key,def) \
cw_cfg_get_word(cfg1,key,cw_cfg_get_word(cfg2,key,def))
#define cw_dget(fun,cfg1,cfg2,key,def)\
fun(cfg1,key,fun(cfg2,key,def))
#endif #endif

963
src/cw/conn.c Normal file
View File

@ -0,0 +1,963 @@
#include <string.h>
#include <stdint.h>
#include "conn.h"
#include "capwap.h"
#include "cw.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "log.h"
#include "capwap.h"
#include "conn.h"
#include "sock.h"
#include "msgset.h"
#include "cw.h"
#include "dbg.h"
#include "msgset.h"
#include "mavltypes.h"
#include "dtls.h"
/**
* Put a message to a buffer
* This functions assumes, that a message header is
* alread initilaized in buffer
* Message alements are taken fom actiondef in #conn->action
*/
int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout)
{
char details[1024];
uint8_t *msgptr,*dst;
int type;
struct cw_MsgData * msg;
struct mlistelem * elem;
int len,l;
/* rawout is already initialized, so we can get
* msg type from buffer */
msgptr = rawout + cw_get_hdr_msg_offset(rawout);
type = cw_get_msg_type(msgptr);
/* look for message data */
msg = cw_msgset_get_msgdata(conn->msgset,type);
if (msg == NULL){
cw_log(LOG_ERR,"Error: Can't create message of type %d (%s) - no definition found.",
type, cw_strmsg(type));
return CAPWAP_RESULT_MSG_UNRECOGNIZED;
}
if (msg->preprocess){
msg->preprocess(conn);
}
cw_dbg(DBG_MSG_ASSEMBLY,"*** Assembling message of type %d (%s) ***",
msg->type, msg->name);
dst = msgptr+8;
len =0;
mlist_foreach(elem,msg->elements_list){
struct cw_ElemData * data;
struct cw_ElemHandler * handler;
struct cw_ElemHandlerParams params;
data = mlistelem_dataptr(elem);
handler = cw_msgset_get_elemhandler(conn->msgset,data->proto,data->vendor,data->id);
cw_dbg(DBG_MSG_ASSEMBLY," Add Elem: %d %d %d %s", data->proto, data->vendor, data->id, handler->name);
if (handler==NULL){
cw_log(LOG_ERR,"Can't put message element %d %d %d, no handler defined.",
data->proto,data->vendor,data->id);
continue;
}
if (handler->put == NULL){
if (data->mand){
cw_log(LOG_ERR,"Error: Can't add mandatory message element %d - %s, no put method defined",
handler->id, handler->name);
}
continue;
}
params.conn=conn;
params.cfg=conn->remote_cfg;
params.cfg_list[0]=params.cfg;
params.cfg_list[1]=conn->local_cfg;
params.cfg_list[2]=conn->global_cfg;
params.cfg_list[3]=NULL;
params.msgset=conn->msgset;
params.elemdata = data;
params.msgdata=msg;
params.debug_details=details;
*details=0;
/* if (strcmp(handler->key,"cisco/ap-led-flash-config")==0){
printf("flash config\n");
cisco/ap-led-flash-config/flash-enable
}*/
if (!data->mand){
if (!cw_cfg_base_exists(params.cfg,handler->key)){
cw_dbg(DBG_X,"nothing todo");
continue;
}
}
l = handler->put(handler,&params,dst+len);
/* if(l>0)
cw_dbg_elem(DBG_ELEM_OUT,conn,type,handler,dst+len,l);
* if (strlen(details)){
cw_dbg(DBG_ELEM_DETAIL," %s",params.debug_details);
}
*/ len += l;
}
cw_set_msg_elems_len(msgptr, len);
cw_dbg(DBG_MSG_ASSEMBLY,"*** Done assenmbling message of type %d (%s) ***",
msg->type, msg->name);
if (type & 1) {
/* It's a request, so we have to set seqnum */
int s = conn_get_next_seqnum(conn);
cw_set_msg_seqnum(msgptr,s);
}
{
printf ("----------------------------------- redecode -----------------------------\n");
uint8_t *elems_ptr;
int offset = cw_get_hdr_msg_offset(rawout);
uint8_t *msg_ptr = rawout + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
cw_Cfg_t * cfg = cw_cfg_create();
struct cw_ElemHandlerParams params;
params.cfg=cfg;
params.msgset=conn->msgset;
params.msgdata=msg;
cw_decode_elements( &params, elems_ptr,elems_len);
cw_cfg_destroy(cfg);
printf ("----------------------------------- end redecode -----------------------------\n");
}
return CAPWAP_RESULT_SUCCESS;
}
struct msg_callback{
int type; /**< message type */
cw_MsgCallbackFun fun;
};
int msg_callback_cmp(const void *v1,const void *v2)
{
struct msg_callback *t1,*t2;
t1=(struct msg_callback*)v1;
t2=(struct msg_callback*)v2;
return t1->type - t2->type;
}
/**
* Basic initialization of a conn object
* @param conn conn object to initialize
*/
void cw_conn_init(struct cw_Conn * conn)
{
memset(conn,0,sizeof(struct cw_Conn ));
conn->retransmit_interval=CAPWAP_RETRANSMIT_INTERVAL;
conn->max_retransmit=CAPWAP_MAX_RETRANSMIT;
conn->wait_dtls=CAPWAP_WAIT_DTLS;
conn->wait_join=CAPWAP_WAIT_JOIN;
conn->mtu_discovery=1;
conn->strict_capwap=1;
conn->process_packet=conn_process_packet;
conn->process_message=process_message;
conn->msg_callbacks = mavl_create(msg_callback_cmp,NULL,sizeof(struct msg_callback));
}
int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun)
{
struct msg_callback cb;
int exists;
cb.type = type;
cb.fun = fun;
mavl_insert(conn->msg_callbacks,&cb,&exists);
return 1;
}
cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type)
{
struct msg_callback cb,*result;
cb.type=type;
result = mavl_get(conn->msg_callbacks,&cb);
if (result == NULL)
return NULL;
return result->fun;
}
/**
* Create a conn object
* @param sock a socket
* @param addr the address associated
* @param qsize size of packet queue
* @return A pointer to the created object
* This function creates a conn obnject with queueing functionality
* for asynchronous operation.
* To create a conn object without queue functionallity use #conn_create_noq.
*/
struct cw_Conn * cw_conn_create(int sock, struct sockaddr * addr, int qsize)
{
struct cw_Conn * conn;
conn = malloc(sizeof (struct cw_Conn ));
if (!conn)
return NULL;
cw_conn_init(conn);
conn->sock=sock;
if (addr)
sock_copyaddr(&conn->addr,addr);
conn->fragman = fragman_create();
if (conn->fragman==NULL){
conn_destroy(conn);
return NULL;
}
conn->qsize=qsize;
if (qsize != 0){
if (!(conn->q=malloc( sizeof(uint8_t *) * qsize))){
conn_destroy(conn);
return NULL;
}
conn->qrpos=-1;
if (sem_init(&conn->q_sem,0,0)!=0){
cw_log(LOG_ERR,"Fatal- Can't init semaphore for conn object: %s",strerror(errno));
conn_destroy(conn);
return NULL;
};
conn->recv_packet=conn_q_recv_packet;
conn->recv_packet_peek=conn_q_recv_packet_peek;
}
else{
conn->recv_packet = conn_recv_packet;
conn->recv_packet_peek = conn_recv_packet_peek;
}
conn->send_packet = conn_send_packet;
/* conn->send_data_packet = conn_send_data_packet;*/
conn->last_seqnum_received=-1;
conn->mtu=600;
conn->cur_packet=0;
conn->recv_timeout=1;
conn->seqnum=-1;
conn->write = conn->send_packet;
conn->read = conn->recv_packet;
conn->dtls_mtu = 600;
return conn;
}
/**
* Init response message header
*/
void cw_init_response(struct cw_Conn *conn, uint8_t * req)
{
uint8_t *buffer;
int shbytes, dhbytes;
uint8_t *msgptr, *dmsgptr;
buffer = conn->resp_buffer;
shbytes = cw_get_hdr_msg_offset(req);
memcpy(buffer, req, shbytes);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
// cw_set_hdr_hlen(buffer, 2);
// cw_set_hdr_flags(buffer, CW_FLAG_HDR_M, 1);
*/
dhbytes = cw_get_hdr_msg_offset(buffer);
msgptr = req + shbytes;
dmsgptr = buffer + dhbytes;
cw_set_msg_type(dmsgptr, cw_get_msg_type(msgptr) + 1);
cw_set_msg_seqnum(dmsgptr, cw_get_msg_seqnum(msgptr));
cw_set_msg_flags(dmsgptr, 0);
}
void cw_init_request(struct cw_Conn *conn, int msg_id)
{
uint8_t *buffer = conn->req_buffer;
uint8_t *msgptr;
/* zero the first 8 bytes */
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
//cw_set_hdr_hlen(buffer, 2);
*/
cw_set_hdr_wbid(buffer, conn->wbid);
cw_set_hdr_rid(buffer, 0);
msgptr = cw_get_hdr_msg_offset(buffer) + buffer;
cw_set_msg_type(msgptr, msg_id);
cw_set_msg_flags(msgptr, 0);
cw_set_msg_elems_len(msgptr, 0);
}
void cw_init_data_msg(struct cw_Conn *conn)
{
uint8_t *buffer = conn->req_buffer;
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
}
/**
* send a response
*/
int cw_send_response(struct cw_Conn *conn, uint8_t * rawmsg, int len)
{
int rc;
cw_init_response(conn, rawmsg);
rc = cw_assemble_message(conn, conn->resp_buffer);
if (!cw_result_is_ok(rc))
return 0;
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
/**
* Special case error message, which is sent when an unexpected messages
* was received or something else happened.
* @param conn conection
* @param rawmsg the received request message, which the response belongs to
* @param result_code result code to send
* @return 1
*/
int cw_send_error_response(struct cw_Conn *conn, uint8_t * rawmsg,
uint32_t result_code)
{
uint8_t *out, *dst;
int l;
cw_init_response(conn, rawmsg);
out = conn->resp_buffer;
dst = cw_get_hdr_msg_elems_ptr(out);
l = cw_put_elem_result_code(dst, result_code);
cw_set_msg_elems_len(out + cw_get_hdr_msg_offset(out), l);
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
static struct cw_MsgSet *load_msg_set(struct cw_Conn *conn, uint8_t * rawmsg,
int len, int elems_len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
struct cw_Mod *cmod, *bmod;
cmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from,
CW_MOD_MODE_CAPWAP);
if (cmod == MOD_NULL) {
cw_dbg(DBG_MSG_ERR,
"Can't find mod to handle connection from %s, discarding message",
sock_addr2str_p(from, sock_buf));
return NULL;
}
bmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from,
CW_MOD_MODE_BINDINGS);
cw_dbg(DBG_INFO, "Mods deteced: %s,%s", cmod->name, bmod->name);
conn->cmod = cmod;
conn->bmod = bmod;
return cw_mod_get_msg_set(conn, cmod, bmod);
}
/*
int cw_in_check_generic(struct cw_Conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
// if (cw_is_request(a->msg_id)){
// return cw_in_check_generic_req(conn,a,data,len,from);
// }
// return cw_in_check_generic_resp(conn,a,data,len,from);
}
*/
static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
mavl_t mand_found;
mlist_t unrecognized;
struct cw_MsgData search;
struct cw_MsgData *message;
int result_code;
cw_State_t *ui;
uint8_t *elems_ptr;
struct cw_ElemHandlerParams params;
char sock_buf[SOCK_ADDR_BUFSIZE]; /**< to hold str from sockaddr2str */
/*struct cw_action_in as, *af, *afm; */
int offset = cw_get_hdr_msg_offset(rawmsg);
uint8_t *msg_ptr = rawmsg + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
int payloadlen = len - offset;
/* pre-check message */
if (payloadlen - 8 != elems_len) {
if (conn->strict_hdr) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, msgelems len=%d, payload len=%d, (Strict CAPWAP) ",
sock_addr2str(&conn->addr, sock_buf), elems_len,
payloadlen - 8);
errno = EAGAIN;
return -1;
}
if (elems_len < payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has %d bytes of extra data, ignoring.",
sock_addr2str(&conn->addr, sock_buf),
payloadlen - 8 - elems_len);
elems_len = len - 8;
}
if (elems_len > payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has msgelems len of %d bytes, but has only %d bytes of data, truncating.",
sock_addr2str(&conn->addr, sock_buf), elems_len,
payloadlen - 8);
elems_len = payloadlen - 8;
}
}
/* Detect the connecting WTP type */
if (!conn->detected) {
struct cw_MsgSet *set =
load_msg_set(conn, rawmsg, len, elems_len, from);
if (!set) {
/*
//cw_log(LOG_ERR, "Error");
*/
errno = EAGAIN;
return -1;
}
conn->cmod->setup_cfg(conn);
conn->msgset = set;
conn->detected = 1;
if (conn->setup_complete)
conn->setup_complete(conn);
}
/** debug the received message */
cw_dbg_msg(DBG_MSG_IN, conn, rawmsg, len, from);
/* prepare struct for search operation */
search.type = cw_get_msg_id(msg_ptr);
/* Search message */
message = mavl_get(conn->msgset->msgdata, &search);
result_code = 0;
if (!message) {
/* Message is unknown */
if (search.type & 1) {
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_UNRECOGNIZED;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Throw away unexpected messages */
/* maybe we have to check this too: if (!(message->type & 1))
* means unexpected response message
* */
if (!(message->receiver & conn->role)) {
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) unexpected/illegal in %s State, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Check if current state is in state of message */
ui = message->states;
for (ui = message->states; ui->state; ui++) {
/* printf("Comparing %d and %d\n", conn->capwap_state, ui->state);*/
if (ui->state == conn->capwap_state) {
break;
}
}
if (!ui->state) {
/* Message found, but it was in wrong state */
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) not allowed in %s State, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_INVALID_IN_CURRENT_STATE;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
mand_found = mavl_create_conststr();
unrecognized = mlist_create(NULL, NULL, sizeof(uint8_t *));
cw_dbg(DBG_MSG_PARSING, "*** Parsing message of type %d - (%s) ***",
message->type, message->name);
params.cfg = cw_cfg_create();
params.cfg_list[0]=params.cfg;
params.cfg_list[1]=conn->local_cfg;
params.cfg_list[2]=conn->global_cfg;
params.cfg_list[3]=NULL;
params.from = from;
params.msgdata = message;
params.mand_found = mand_found;
params.msgset=conn->msgset;
params.conn = conn;
cw_decode_elements(&params,elems_ptr, elems_len);
/* all message elements are processed, do now after processing
by calling the "end" function for the message */
cw_check_missing_mand(message, mand_found);
cw_dbg(DBG_MSG_PARSING, "*** End parsing message of type %d (%s) ***",
message->type, message->name);
mavl_destroy(mand_found);
if (message->postprocess) {
message->postprocess(&params,elems_ptr, elems_len);
}
cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type);
if (cb_fun != NULL){
result_code = cb_fun(&params,elems_ptr, elems_len);
}
else{
cw_cfg_clear(params.cfg);
}
conn->remote_cfg=params.cfg;
/* if we've got a request message, we always have to send a response message */
if (message->type & 1) {
if (result_code > 0) {
/* the end method gave us an result code>0, so
send an error message */
cw_send_error_response(conn, rawmsg, result_code);
} else if (result_code == 0) {
cw_cfg_set_int(params.cfg, "result-code",
result_code);
if (ui->next) {
conn->capwap_prevstate = conn->capwap_state;
conn->capwap_state = ui->next;
}
/* All is ok, send regular response message */
cw_send_response(conn, rawmsg, len);
} else {
/* the request message is ignored, no response
will be sent */
errno = EAGAIN;
}
} else {
/*
* Whe have got a response message.
* Put further actions here, if needed.
*/
}
mlist_destroy(unrecognized);
cw_cfg_destroy(params.cfg);
conn->remote_cfg=NULL;
return result_code;
}
int process_message(struct cw_Conn *conn, uint8_t * rawmsg, int rawlen,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
uint8_t seqnum;
int s1, s2, sd;
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. */
return process_elements(conn, rawmsg, rawlen, from);
}
/* It's a request message, check if seqnum is right and if
* we have already sent a response message*/
seqnum = cw_get_msg_seqnum(msgptr);
s1 = conn->last_seqnum_received;
s2 = seqnum;
sd = s2 - s1;
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, from);
}
if (sd != 0) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2, s1);
errno = EAGAIN;
return -1;
}
/* the received request message was retransmittet by our peer,
* let's retransmit our response message if we have one*/
cw_dbg(DBG_MSG_ERR,
"Retransmitted request message from %s detected, seqnum=%d, type=%d",
sock_addr2str(&conn->addr, sock_buf), s2, type);
if (cw_get_hdr_msg_type(conn->resp_buffer) - 1 != type) {
/* cw_dbg(DBG_MSG_ERR,
"No cached response for retransmission, request seqnum=%d,in cache=%d",
s2, conn->resp_msg.type);*/
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR, "Retransmitting response message to %s, seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2);
/*// XXX untested */
conn_send_msg(conn, conn->resp_buffer);
errno = EAGAIN;
return -1;
}
/*
* Process an incomming CAPWAP packet, assuming the packet is already decrypted
* @param conn conection object
* @param packet pointer to packet data
* @param len lenght of packet data
*/
int conn_process_packet2(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
int preamble;
int offs;
int payloadlen;
if (len < 8) {
/* packet too short */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, packet too short, len=%d, at least 8 expected.",
sock_addr2str(&conn->addr, sock_buf), len);
errno = EAGAIN;
return -1;
}
preamble = cw_get_hdr_preamble(packet);
if ((preamble & 0xf0) != (CAPWAP_VERSION << 4)) {
/* wrong version */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong version, version=%d, version %d expected.",
sock_addr2str(&conn->addr, sock_buf),
(preamble & 0xf0) >> 4, CAPWAP_VERSION);
errno = EAGAIN;
return -1;
}
if (preamble & 0xf) {
/* Encrypted data, this shuold never happen here */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, encrypted data after decryption ...",
sock_addr2str(&conn->addr, sock_buf));
errno = EAGAIN;
return -1;
}
offs = cw_get_hdr_msg_offset(packet);
payloadlen = len - offs;
if (payloadlen < 0) {
/* Eleminate messages with wrong header size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, header length (%d) greater than packet len (%d).",
sock_addr2str(&conn->addr, sock_buf), offs, len);
errno = EAGAIN;
return -1;
}
/* Check if Radio MAC is present */
if (cw_get_hdr_flag_m(packet)) {
if (cw_get_hdr_rmac_len(packet) + 8 > offs) {
/* wrong rmac size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong R-MAC size, size=%d",
sock_addr2str(&conn->addr, sock_buf),
*(packet + 8));
errno = EAGAIN;
return -1;
}
}
if (cw_get_hdr_flag_f(packet)) {
/* fragmented, add the packet to fragman */
uint8_t *f;
int rc;
f = fragman_add(conn->fragman, packet, offs, payloadlen);
if (f == NULL) {
errno = EAGAIN;
return -1;
}
cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from);
/*// cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/
/* // XXX: Modify fragman to not throw away CAPWAP headers*/
rc = conn->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, from);*/
return conn->process_message(conn, packet, len, from);
}
int conn_process_packet(struct cw_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, from);
return conn_process_packet2(conn, packet, len, from);
}
int conn_process_data_packet(struct cw_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, from);
return conn_process_packet2(conn, packet, len, from);
}
/**
* Used as main message loop
*/
int cw_read_messages(struct cw_Conn *conn)
{
uint8_t buf[2024];
int len = 2024;
int n = conn->read(conn, buf, len);
if (n < 0)
return n;
if (n > 0) {
return conn->process_packet(conn, buf, n,
(struct sockaddr *) &conn->addr);
}
errno = EAGAIN;
return -1;
}
/**
* Destroy a conn object
* @param object to destroy
*/
void conn_destroy(struct cw_Conn * conn)
{
dtls_shutdown(conn);
if (conn->fragman)
fragman_destroy(conn->fragman);
if (conn->q)
free (conn->q);
if (conn->msg_callbacks)
mavl_destroy(conn->msg_callbacks);
if (conn->base_rmac)
free(conn->base_rmac);
if (conn->remote_cfg)
cw_cfg_destroy(conn->remote_cfg);
if (conn->local_cfg)
cw_cfg_destroy(conn->local_cfg);
free(conn);
}

View File

@ -30,7 +30,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include "fragman.h" #include "fragman.h"
#include "cwmsg.h" //#include "cwmsg.h"
@ -56,7 +56,7 @@ struct cw_action_in;
/** /**
* Connection Object * Connection Object
*/ */
struct conn { struct cw_Conn {
int sock; int sock;
struct sockaddr_storage addr; struct sockaddr_storage addr;
@ -73,26 +73,11 @@ struct conn {
mavl_t remote_cfg; mavl_t remote_cfg;
mavl_t default_cfg; // mavl_t default_cfg;
mavl_t update_cfg; mavl_t update_cfg;
mavl_t local_cfg; mavl_t local_cfg;
mavl_t global_cfg; mavl_t global_cfg;
int (*write_header)(struct cw_ElemHandler * handler, uint8_t * dst, int len);
int (*header_len)(struct cw_ElemHandler *handler);
/* mbag_t outgoing;
mbag_t incomming;
mbag_t remote;
mbag_t local;
mbag_t radios;
mbag_t radios_upd;
mbag_t config;
mbag_t config_upd;
*/
/* uint8_t session_id[16];*/
bstr16_t session_id; bstr16_t session_id;
@ -106,7 +91,7 @@ struct conn {
/** Counter for mandatory message elements */ /** Counter for mandatory message elements */
struct avltree *mand; /* struct avltree *mand;*/
/** Actionsdefs - this defines the possible actions for /** Actionsdefs - this defines the possible actions for
@ -114,7 +99,6 @@ struct conn {
of the protocoll */ of the protocoll */
struct cw_MsgSet * msgset;
uint8_t capwap_prevstate; uint8_t capwap_prevstate;
@ -136,8 +120,8 @@ struct conn {
int last_message_id_received; int last_message_id_received;
struct cwmsg req_msg; // struct cwmsg req_msg;
struct cwmsg resp_msg; // struct cwmsg resp_msg;
/** Buffer for outgoing request messages */ /** Buffer for outgoing request messages */
uint8_t req_buffer[CONN_MAX_MSG_LENGTH]; uint8_t req_buffer[CONN_MAX_MSG_LENGTH];
@ -154,19 +138,19 @@ struct conn {
/* receive and send methods */ /* receive and send methods */
int (*recv_packet) (struct conn *, uint8_t *, int); int (*recv_packet) (struct cw_Conn*, uint8_t *, int);
int (*recv_packet_peek) (struct conn *, uint8_t *, int); int (*recv_packet_peek) (struct cw_Conn*, uint8_t *, int);
int (*send_packet) (struct conn *, const uint8_t *, int); int (*send_packet) (struct cw_Conn*, const uint8_t *, int);
/* /*
// int (*recv_data_packet) (struct conn *, uint8_t *,int); // int (*recv_data_packet) (struct cw_Conn*, uint8_t *,int);
// int (*send_data_packet) (struct conn *, const uint8_t *, int); // int (*send_data_packet) (struct cw_Conn*, const uint8_t *, int);
*/ */
int (*readfrom) (struct conn *, uint8_t *, int, struct sockaddr_storage *); int (*readfrom) (struct cw_Conn*, uint8_t *, int, struct sockaddr_storage *);
int (*read) (struct conn *, uint8_t *, int); int (*read) (struct cw_Conn*, uint8_t *, int);
int (*write) (struct conn *, const uint8_t *, int); int (*write) (struct cw_Conn*, const uint8_t *, int);
/* /*
// int (*write_data) (struct conn *, const uint8_t *, int); // int (*write_data) (struct cw_Conn*, const uint8_t *, int);
*/ */
/* optional packet queue */ /* optional packet queue */
uint8_t **q; uint8_t **q;
@ -179,23 +163,23 @@ struct conn {
int cur_packet_pos; int cur_packet_pos;
/* dtls stuff */ /* dtls stuff */
int (*dtls_start) (struct conn *); int (*dtls_start) (struct cw_Conn*);
int (*dtls_accept) (struct conn *); int (*dtls_accept) (struct cw_Conn*);
bstr16_t dtls_psk; bstr16_t dtls_psk;
int dtls_psk_enable; int dtls_psk_enable;
int dtls_dhbits; int dtls_dhbits;
int (*dtls_get_psk)(struct conn *,const char *user,uint8_t**psk, int *len); int (*dtls_get_psk)(struct cw_Conn*,const char *user,uint8_t**psk, int *len);
struct cw_Mod *cmod, *bmod; struct cw_Mod *cmod, *bmod;
char *dtls_cert_file; const char *dtls_cert_file;
char *dtls_key_file; const char *dtls_key_file;
char *dtls_key_pass; const char *dtls_key_pass;
void *dtls_data; void *dtls_data;
char *dtls_cipher; const char *dtls_cipher;
int dtls_error; int dtls_error;
uint8_t dtls_cookie[8]; uint8_t dtls_cookie[8];
@ -219,7 +203,7 @@ struct conn {
void *data; void *data;
/** Mode */ /** Mode */
int capwap_mode; // int capwap_mode;
/** CAWAP mode for outgoing messages */ /** CAWAP mode for outgoing messages */
int capwap_mode_out; int capwap_mode_out;
@ -229,25 +213,27 @@ struct conn {
int strict_hdr; int strict_hdr;
int (*process_packet)(struct conn *conn, uint8_t * packet, int len,struct sockaddr *from); int (*process_packet)(struct cw_Conn*conn, uint8_t * packet, int len,struct sockaddr *from);
int (*process_message)(struct conn *conn, uint8_t * rawmsg, int rawlen, int (*process_message)(struct cw_Conn*conn, uint8_t * rawmsg, int rawlen,
struct sockaddr *from); struct sockaddr *from);
int detected; int detected;
void * mods; struct cw_MsgSet * msgset;
void (*setup_complete)(struct cw_Conn *conn);
struct mavl * msg_callbacks;
int (*msg_start)(struct conn *conn,struct cw_action_in *a,uint8_t*data,int len,struct sockaddr *from);
int (*msg_end)(struct conn *conn,struct cw_action_in *a,uint8_t*elem,int len,struct sockaddr *from);
int (*elem_end)(struct conn *conn,struct cw_action_in *a,int afrc,uint8_t*elem,int len,struct sockaddr *from);
/* /*
// void (*actions_registered)(struct conn *conn); int (*msg_start)(struct cw_Conn*conn,struct cw_action_in *a,uint8_t*data,int len,struct sockaddr *from);
int (*msg_end)(struct cw_Conn*conn,struct cw_action_in *a,uint8_t*elem,int len,struct sockaddr *from);
int (*elem_end)(struct cw_Conn*conn,struct cw_action_in *a,int afrc,uint8_t*elem,int len,struct sockaddr *from);
*/ */
}; };
typedef struct cw_Conn cw_Conn_t;
@ -255,76 +241,86 @@ struct conn {
struct conn *conn_create(int sock, struct sockaddr *addr, int qsize); struct cw_Conn* cw_conn_create(int sock, struct sockaddr *addr, int qsize);
struct conn *conn_create_noq(int sock, struct sockaddr *addr); struct cw_Conn* conn_create_noq(int sock, struct sockaddr *addr);
extern int conn_send_cwmsg(struct conn *conn, struct cwmsg *cwmsg); //extern int conn_send_cwmsg(struct cw_Conn*conn, struct cwmsg *cwmsg);
/* /*
//extern int conn_process_packet(struct conn *conn, uint8_t * packet, int len, //extern int conn_process_packet(struct cw_Conn*conn, uint8_t * packet, int len,
// int (*cb) (void *, uint8_t *,int len), void *cbarg); // int (*cb) (void *, uint8_t *,int len), void *cbarg);
*/ */
extern int conn_process_packet(struct conn *conn, uint8_t * packet, int len,struct sockaddr *from); extern int conn_process_packet(struct cw_Conn*conn, uint8_t * packet, int len,struct sockaddr *from);
extern int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen, extern int process_message(struct cw_Conn*conn, uint8_t * rawmsg, int rawlen,
struct sockaddr *from); struct sockaddr *from);
extern uint8_t *conn_get_message(struct conn *conn); extern uint8_t *conn_get_message(struct cw_Conn*conn);
extern int conn_send_packet(struct conn *conn, const uint8_t * buffer, int len); extern int conn_send_packet(struct cw_Conn*conn, const uint8_t * buffer, int len);
extern int conn_send_data_packet(struct conn * conn, const uint8_t * buffer, int len); extern int conn_send_data_packet(struct cw_Conn* conn, const uint8_t * buffer, int len);
extern void conn_destroy(struct conn *conn); extern void conn_destroy(struct cw_Conn*conn);
uint8_t *conn_q_get_packet(struct conn *conn); uint8_t *conn_q_get_packet(struct cw_Conn*conn);
extern int conn_q_recv_packet(struct conn *conn, uint8_t * buffer, int len); extern int conn_q_recv_packet(struct cw_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_q_recv_packet_peek(struct cw_Conn*conn, uint8_t * buffer, int len);
extern int conn_recv_packet(struct conn *conn, uint8_t * buf, int len); extern int conn_recv_packet(struct cw_Conn*conn, uint8_t * buf, int len);
extern int conn_recv_packet_peek(struct conn *conn, uint8_t * buf, int len); extern int conn_recv_packet_peek(struct cw_Conn*conn, uint8_t * buf, int len);
extern int conn_send_response(struct conn *conn, struct cwmsg *cwmsg, int seqnum); //extern int conn_send_response(struct cw_Conn*conn, struct cwmsg *cwmsg, int seqnum);
extern struct cwrmsg *conn_get_response(struct conn *conn); extern struct cwrmsg *conn_get_response(struct cw_Conn*conn);
#define conn_get_next_seqnum(conn) (conn->seqnum=((conn->seqnum+1)&0xff)) #define conn_get_next_seqnum(conn) (conn->seqnum=((conn->seqnum+1)&0xff))
#define conn_get_last_seqnum(conn) (conn->seqnum&0xff) #define conn_get_last_seqnum(conn) (conn->seqnum&0xff)
void conn_q_add_packet(struct conn *conn, uint8_t * packet, int len); void conn_q_add_packet(struct cw_Conn*conn, uint8_t * packet, int len);
struct image_identifier; struct image_identifier;
struct cwimage_data; struct cwimage_data;
extern void conn_prepare_request(struct conn *conn, int type); extern void conn_prepare_request(struct cw_Conn*conn, int type);
extern int conn_prepare_image_data_request(struct conn *conn, struct cwimage_data *, extern int conn_prepare_image_data_request(struct cw_Conn*conn, struct cwimage_data *,
struct image_identifier *id); struct image_identifier *id);
/* /*
//extern void conn_detect_capwap(struct conn *conn, struct wtpinfo *wtpinfo); //extern void conn_detect_capwap(struct cw_Conn*conn, struct wtpinfo *wtpinfo);
*/ */
struct cwrmsg *conn_send_request(struct conn *conn); struct cwrmsg *conn_send_request(struct cw_Conn*conn);
struct cwrmsg *conn_wait_for_message(struct conn *conn, time_t timer); struct cwrmsg *conn_wait_for_message(struct cw_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 cw_Conn*conn, int *msglist, time_t timer);
int conn_q_wait_packet(struct conn * conn, int seconds); //int conn_q_wait_packet(struct cw_Conn* conn, int seconds);
#define conn_is_error(conn) (conn->dtls_error) #define conn_is_error(conn) (conn->dtls_error)
void conn_init(struct conn *conn); void cw_conn_init(struct cw_Conn*conn);
extern int cw_read_messages(struct conn *conn); extern int cw_read_messages(struct cw_Conn*conn);
extern int conn_recvfrom_packet(struct conn *conn, uint8_t * buf, int len, extern int conn_recvfrom_packet(struct cw_Conn*conn, uint8_t * buf, int len,
struct sockaddr_storage *from); struct sockaddr_storage *from);
int conn_send_msg(struct conn * conn, uint8_t *rawmsg); int conn_send_msg(struct cw_Conn* conn, uint8_t *rawmsg);
int cw_read_from(struct conn * conn, struct sockaddr_storage * from); int cw_read_from(struct cw_Conn* conn, struct sockaddr_storage * from);
int conn_send_msg(struct conn *conn, uint8_t * rawmsg); int conn_send_msg(struct cw_Conn *conn, uint8_t * rawmsg);
void conn_clear_upd(struct cw_Conn*conn, int merge);
int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun);
cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type);
int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,
int vendor, int elem_id, uint8_t * data, int len);
int cw_decode_elements(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
void conn_clear_upd(struct conn *conn, int merge);
#endif /* __CONN_H */ #endif /* __CONN_H */

View File

@ -35,76 +35,4 @@
/**
* Create a conn object
* @param sock a socket
* @param addr the address associated
* @param qsize size of packet queue
* @return A pointer to the created object
* This function creates a conn obnject with queueing functionality
* for asynchronous operation.
* To create a conn object without queue functionallity use #conn_create_noq.
*/
struct conn * conn_create(int sock, struct sockaddr * addr, int qsize)
{
struct conn * conn;
conn = malloc(sizeof (struct conn));
if (!conn)
return NULL;
conn_init(conn);
conn->sock=sock;
if (addr)
sock_copyaddr(&conn->addr,addr);
conn->fragman = fragman_create();
if (conn->fragman==NULL){
conn_destroy(conn);
return NULL;
}
conn->qsize=qsize;
if (qsize != 0){
if (!(conn->q=malloc( sizeof(uint8_t *) * qsize))){
conn_destroy(conn);
return NULL;
}
conn->qrpos=-1;
if (sem_init(&conn->q_sem,0,0)!=0){
cw_log(LOG_ERR,"Fatal- Can't init semaphore for conn object: %s",strerror(errno));
conn_destroy(conn);
return NULL;
};
conn->recv_packet=conn_q_recv_packet;
conn->recv_packet_peek=conn_q_recv_packet_peek;
}
else{
conn->recv_packet = conn_recv_packet;
conn->recv_packet_peek = conn_recv_packet_peek;
}
conn->send_packet = conn_send_packet;
/* conn->send_data_packet = conn_send_data_packet;*/
conn->last_seqnum_received=-1;
conn->mtu=600;
conn->cur_packet=0;
conn->recv_timeout=1;
conn->seqnum=-1;
conn->write = conn->send_packet;
conn->read = conn->recv_packet;
/* conn->write_data = conn->send_data_packet; */
conn->dtls_mtu = 600;
return conn;
}

View File

@ -36,14 +36,14 @@
* @retval 1 Success * @retval 1 Success
* @retval 0 failure, conslt errno for more details * @retval 0 failure, conslt errno for more details
*/ */
struct conn * conn_create_noq(int sock, struct sockaddr * addr) struct cw_Conn * conn_create_noq(int sock, struct sockaddr * addr)
{ {
struct conn * conn; struct cw_Conn * conn;
conn = malloc(sizeof (struct conn)); conn = malloc(sizeof (struct cw_Conn ));
if (!conn) if (!conn)
return NULL; return NULL;
conn_init(conn); cw_conn_init(conn);
conn->sock=sock; conn->sock=sock;

View File

@ -1,41 +0,0 @@
/*
This file is part of actube.
actube 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 <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Implements conn_destroy
*/
#include <stdlib.h>
#include "conn.h"
/**
* Destroy a conn object
* @param object to destroy
*/
void conn_destroy(struct conn * conn)
{
if (conn->fragman)
fragman_destroy(conn->fragman);
if (conn->q)
free (conn->q);
free(conn);
}

View File

@ -29,6 +29,7 @@
#include "capwap.h" #include "capwap.h"
#include "cw.h" #include "cw.h"
/*
static int write_header(struct cw_ElemHandler * handler, uint8_t * dst, int len) static int write_header(struct cw_ElemHandler * handler, uint8_t * dst, int len)
{ {
if (handler->vendor) if (handler->vendor)
@ -42,30 +43,31 @@ static int header_len(struct cw_ElemHandler * handler)
return handler->vendor ? 10 : 4; return handler->vendor ? 10 : 4;
} }
*/
/** /**
* Basic initialization of a conn object * Basic initialization of a conn object
* @param conn conn object to initialize * @param conn conn object to initialize
*/ */
void conn_init(struct conn * conn) void conn_init(struct cw_Conn * conn)
{ {
memset(conn,0,sizeof(struct conn)); memset(conn,0,sizeof(struct cw_Conn ));
conn->retransmit_interval=CAPWAP_RETRANSMIT_INTERVAL; conn->retransmit_interval=CAPWAP_RETRANSMIT_INTERVAL;
conn->max_retransmit=CAPWAP_MAX_RETRANSMIT; conn->max_retransmit=CAPWAP_MAX_RETRANSMIT;
conn->wait_dtls=CAPWAP_WAIT_DTLS; conn->wait_dtls=CAPWAP_WAIT_DTLS;
conn->wait_join=CAPWAP_WAIT_JOIN; conn->wait_join=CAPWAP_WAIT_JOIN;
conn->mtu_discovery=1; conn->mtu_discovery=1;
conn->capwap_mode = 0; // conn->capwap_mode = 0;
conn->strict_capwap=1; conn->strict_capwap=1;
conn->process_packet=conn_process_packet; conn->process_packet=conn_process_packet;
conn->process_message=process_message; conn->process_message=process_message;
/*
conn->write_header = write_header; conn->write_header = write_header;
conn->header_len = header_len; conn->header_len = header_len;
*/
} }

View File

@ -38,671 +38,3 @@
/**
* Init response message header
*/
void cw_init_response(struct conn *conn, uint8_t * req)
{
uint8_t *buffer;
int shbytes, dhbytes;
uint8_t *msgptr, *dmsgptr;
buffer = conn->resp_buffer;
shbytes = cw_get_hdr_msg_offset(req);
memcpy(buffer, req, shbytes);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
// cw_set_hdr_hlen(buffer, 2);
// cw_set_hdr_flags(buffer, CW_FLAG_HDR_M, 1);
*/
dhbytes = cw_get_hdr_msg_offset(buffer);
msgptr = req + shbytes;
dmsgptr = buffer + dhbytes;
cw_set_msg_type(dmsgptr, cw_get_msg_type(msgptr) + 1);
cw_set_msg_seqnum(dmsgptr, cw_get_msg_seqnum(msgptr));
cw_set_msg_flags(dmsgptr, 0);
}
void cw_init_request(struct conn *conn, int msg_id)
{
uint8_t *buffer = conn->req_buffer;
uint8_t *msgptr;
/* zero the first 8 bytes */
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
//cw_set_hdr_hlen(buffer, 2);
*/
cw_set_hdr_wbid(buffer, conn->wbid);
cw_set_hdr_rid(buffer, 0);
msgptr = cw_get_hdr_msg_offset(buffer) + buffer;
cw_set_msg_type(msgptr, msg_id);
cw_set_msg_flags(msgptr, 0);
cw_set_msg_elems_len(msgptr, 0);
}
void cw_init_data_msg(struct conn *conn)
{
uint8_t *buffer = conn->req_buffer;
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
}
/**
* send a response
*/
int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len)
{
int rc;
cw_init_response(conn, rawmsg);
rc = cw_put_msg(conn, conn->resp_buffer);
if (!cw_result_is_ok(rc))
return 0;
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
/**
* Special case error message, which is sent when an unexpected messages
* was received or something else happened.
* @param conn conection
* @param rawmsg the received request message, which the response belongs to
* @param result_code result code to send
* @return 1
*/
int cw_send_error_response(struct conn *conn, uint8_t * rawmsg, uint32_t result_code)
{
uint8_t *out,*dst;
int l;
cw_init_response(conn, rawmsg);
out = conn->resp_buffer;
dst = cw_get_hdr_msg_elems_ptr(out);
l = cw_put_elem_result_code(dst, result_code);
cw_set_msg_elems_len(out + cw_get_hdr_msg_offset(out), l);
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
static struct cw_MsgSet *load_msg_set(struct conn *conn, uint8_t * rawmsg, int len,
int elems_len, struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
struct cw_Mod *cmod, *bmod;
cmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from, CW_MOD_MODE_CAPWAP);
if (cmod == MOD_NULL) {
cw_dbg(DBG_MSG_ERR,
"Can't find mod to handle connection from %s, discarding message",
sock_addr2str_p(from,sock_buf));
return NULL;
}
bmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from, CW_MOD_MODE_BINDINGS);
cw_dbg(DBG_INFO, "Mods deteced: %s,%s", cmod->name, bmod->name);
conn->cmod = cmod;
conn->bmod = bmod;
return cw_mod_get_msg_set(conn,cmod,bmod);
}
/*
int cw_in_check_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
// if (cw_is_request(a->msg_id)){
// return cw_in_check_generic_req(conn,a,data,len,from);
// }
// return cw_in_check_generic_resp(conn,a,data,len,from);
}
*/
/*
void cw_read_elem(struct cw_ElemHandler * handler, struct conn * conn,
uint8_t * elem_data, int elem_len, struct sockaddr * from){
mavldata_t data, *result;
char str[30];
result = handler->type->get(&data,elem_data,elem_len);
handler->type->to_str(result,str,30);
printf("Read %d-%s: %s %s\n", handler->id, handler->name, handler->key, str);
//mavl_insert(conn->remote_cfg
}
*/
static int process_elements(struct conn *conn, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
mavl_t mand_found;
mlist_t unrecognized;
struct cw_MsgData search;
struct cw_MsgData * message;
int result_code;
cw_State_t *ui;
uint8_t *elems_ptr;
uint8_t *elem;
char sock_buf[SOCK_ADDR_BUFSIZE]; /**< to hold str from sockaddr2str */
/*struct cw_action_in as, *af, *afm;*/
int offset = cw_get_hdr_msg_offset(rawmsg);
uint8_t *msg_ptr = rawmsg + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
int payloadlen = len - offset;
/* pre-check message */
if (payloadlen - 8 != elems_len) {
if (conn->strict_hdr) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, msgelems len=%d, payload len=%d, (Strict CAPWAP) ",
sock_addr2str(&conn->addr,sock_buf), elems_len, payloadlen - 8);
errno = EAGAIN;
return -1;
}
if (elems_len < payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has %d bytes of extra data, ignoring.",
sock_addr2str(&conn->addr,sock_buf), payloadlen - 8 - elems_len);
elems_len = len - 8;
}
if (elems_len > payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has msgelems len of %d bytes, but has only %d bytes of data, truncating.",
sock_addr2str(&conn->addr, sock_buf), elems_len, payloadlen - 8);
elems_len = payloadlen - 8;
}
}
/* Detect the connecting AC type */
if (!conn->detected) {
struct cw_MsgSet *set = load_msg_set(conn, rawmsg, len, elems_len, from);
if (!set) {
/*
//cw_log(LOG_ERR, "Error");
*/
errno = EAGAIN;
return -1;
}
conn->cmod->setup_cfg(conn);
conn->msgset= set;
conn->detected = 1;
}
/** debug the received message */
cw_dbg_msg(DBG_MSG_IN, conn, rawmsg, len, from);
/* prepare struct for search operation */
search.type = cw_get_msg_id(msg_ptr);
/* Search message */
message = mavl_get(conn->msgset->msgdata,&search);
result_code = 0;
if (!message){
/* Message is unknown */
if (search.type & 1){
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_UNRECOGNIZED;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Throw away unexpected messages */
/* maybe we have to check this too: if (!(message->type & 1))
* means unexpected response message
* */
if (!(message->receiver & conn->role)) {
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) unexpected/illegal in %s State, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Check if current state is in state of message */
ui = message->states;
for (ui=message->states; ui->state; ui++){
/* printf("Comparing %d and %d\n", conn->capwap_state, ui->state);*/
if(ui->state==conn->capwap_state){
break;
}
}
if (!ui->state){
/* Message found, but it was in wrong state */
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) not allowed in %s State, sending response.",
search.type,cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_INVALID_IN_CURRENT_STATE;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
/* if (conn->msg_start){
conn->msg_start(conn, afm, rawmsg, len, from);
}
*/
/* Execute start processor for message */
/*
// if (afm->start) {
// afm->start(conn, afm, rawmsg, len, from);
// }
*/
elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
/* Create an avltree to catch the found mandatory elements */
/* //conn->mand = stravltree_create();*/
mand_found = mavl_create_conststr();
unrecognized = mlist_create(NULL,NULL,sizeof(uint8_t*));
cw_dbg(DBG_MSG_PARSING ,"*** Parsing message of type %d - (%s) ***",
message->type,message->name);
/* iterate through message elements */
cw_foreach_elem(elem, elems_ptr, elems_len) {
int rc;
struct cw_ElemHandlerParams params;
int elem_len, elem_id, max_len;
uint8_t * elem_data;
elem_len = cw_get_elem_len(elem);
elem_data=cw_get_elem_data(elem);
elem_id = cw_get_elem_id(elem);
max_len=elems_len-(elem_data-elems_ptr);
if (elem_len > max_len){
cw_dbg(DBG_RFC,
"Messag element claims size of %d bytes, but only %d bytes are left in the payload, truncating.",
elem_len,max_len-4);
}
/* params.conn=conn;*/
params.local_cfg=conn->local_cfg;
params.remote_cfg=conn->remote_cfg;
params.default_cfg=conn->default_cfg;
params.global_cfg=conn->global_cfg;
params.msgset=conn->msgset;
params.from=from;
params.msgdata=message;
params.mand_found=mand_found;
rc = cw_process_element(&params,0,0,elem_id,elem_data,elem_len);
if (cw_result_is_ok(rc))
continue;
if (rc == CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT){
mlist_append(unrecognized,&elem);
continue;
}
if (rc < 0 ){
continue;
}
}
/* all message elements are processed, do now after processing
by calling the "end" function for the message */
cw_check_missing_mand(message,mand_found);
cw_dbg(DBG_MSG_PARSING," *** Done parsing message of type %d (%s) ***",
message->type,message->name);
mavl_destroy(mand_found);
/* cw_dbg_ktv_dump(conn->remote_cfg,DBG_CFG_DMP,
" *** Remote CFG dump ***", "CFG:", " *** End of remote CFG dump");
*/
if (message->postprocess){
message->postprocess(conn);
}
/* if we've got a request message, we always have to send a response message */
if (message->type & 1) {
if (result_code > 0) {
/* the end method gave us an result code>0, so
send an error message */
cw_send_error_response(conn, rawmsg, result_code);
} else if (result_code == 0) {
cw_ktv_set_dword(conn->local_cfg,"result-code",result_code);
if (ui->next){
conn->capwap_prevstate = conn->capwap_state;
conn->capwap_state = ui->next;
}
/* All is ok, send regular response message */
cw_send_response(conn, rawmsg, len);
} else {
/* the request message is ignored, no response
will be sent */
errno = EAGAIN;
}
} else {
/*
* Whe have got a response message.
* Put further actions here, if needed.
*/
}
/*stravltree_destroy(conn->mand);*/
return result_code;
}
int process_message(struct conn *conn, uint8_t * rawmsg, int rawlen,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
uint8_t seqnum;
int s1,s2,sd;
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. */
return process_elements(conn, rawmsg, rawlen, from);
}
/* It's a request message, check if seqnum is right and if
* we have already sent a response message*/
seqnum = cw_get_msg_seqnum(msgptr);
s1 = conn->last_seqnum_received;
s2 = seqnum;
sd = s2 - s1;
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, from);
}
if (sd != 0) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d",
sock_addr2str(&conn->addr,sock_buf), s2, s1);
errno = EAGAIN;
return -1;
}
/* the received request message was retransmittet by our peer,
* let's retransmit our response message if we have one*/
cw_dbg(DBG_MSG_ERR,
"Retransmitted request message from %s detected, seqnum=%d, type=%d",
sock_addr2str(&conn->addr,sock_buf), s2, type);
if (cw_get_hdr_msg_type(conn->resp_buffer) - 1 != type) {
cw_dbg(DBG_MSG_ERR,
"No cached response for retransmission, request seqnum=%d,in cache=%d",
s2, conn->resp_msg.type);
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR, "Retransmitting response message to %s, seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2);
/*// XXX untested*/
conn_send_msg(conn, conn->resp_buffer);
errno = EAGAIN;
return -1;
}
/*
* Process an incomming CAPWAP packet, assuming the packet is already decrypted
* @param conn conection object
* @param packet pointer to packet data
* @param len lenght of packet data
*/
int conn_process_packet2(struct conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
int preamble;
int offs;
int payloadlen;
if (len < 8) {
/* packet too short */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, packet too short, len=%d, at least 8 expected.",
sock_addr2str(&conn->addr, sock_buf), len);
errno = EAGAIN;
return -1;
}
preamble = cw_get_hdr_preamble(packet);
if ((preamble & 0xf0) != (CAPWAP_VERSION << 4)) {
/* wrong version */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong version, version=%d, version %d expected.",
sock_addr2str(&conn->addr,sock_buf), (preamble & 0xf0) >> 4,
CAPWAP_VERSION);
errno = EAGAIN;
return -1;
}
if (preamble & 0xf) {
/* Encrypted data, this shuold never happen here */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, encrypted data after decryption ...",
sock_addr2str(&conn->addr,sock_buf));
errno = EAGAIN;
return -1;
}
offs = cw_get_hdr_msg_offset(packet);
payloadlen = len - offs;
if (payloadlen < 0) {
/* Eleminate messages with wrong header size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, header length (%d) greater than packet len (%d).",
sock_addr2str(&conn->addr,sock_buf), offs, len);
errno = EAGAIN;
return -1;
}
/* Check if Radio MAC is present */
if (cw_get_hdr_flag_m(packet)) {
if (cw_get_hdr_rmac_len(packet) + 8 > offs) {
/* wrong rmac size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong R-MAC size, size=%d",
sock_addr2str(&conn->addr,sock_buf), *(packet + 8));
errno = EAGAIN;
return -1;
}
}
if (cw_get_hdr_flag_f(packet)) {
/* fragmented, add the packet to fragman */
uint8_t *f;
int rc;
f = fragman_add(conn->fragman, packet, offs, payloadlen);
if (f == NULL) {
errno = EAGAIN;
return -1;
}
cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from);
/*// cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/
/* // XXX: Modify fragman to not throw away CAPWAP headers*/
rc = conn->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, from);*/
return conn->process_message(conn, packet, len, from);
}
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, from);
return conn_process_packet2(conn,packet,len,from);
}
int conn_process_data_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, from);
return conn_process_packet2(conn,packet,len,from);
}
/**
* Used as main message loop
*/
int cw_read_messages(struct conn *conn)
{
uint8_t buf[2024];
int len = 2024;
int n = conn->read(conn, buf, len);
if (n < 0)
return n;
if (n > 0) {
return conn->process_packet(conn, buf, n,
(struct sockaddr *) &conn->addr);
}
errno = EAGAIN;
return -1;
}

View File

@ -25,7 +25,7 @@
#include "sock.h" #include "sock.h"
void conn_q_add_packet(struct conn * conn,uint8_t *packet,int len) void conn_q_add_packet(struct cw_Conn * conn,uint8_t *packet,int len)
{ {
char sock_buf[SOCK_ADDR_BUFSIZE]; char sock_buf[SOCK_ADDR_BUFSIZE];
int qwpos = conn->qwpos; int qwpos = conn->qwpos;

View File

@ -19,7 +19,7 @@
#include <time.h> #include <time.h>
#include "conn.h" #include "conn.h"
uint8_t * conn_q_get_packet(struct conn * conn) uint8_t * conn_q_get_packet(struct cw_Conn * conn)
{ {
int qrpos; int qrpos;
struct timespec timespec; struct timespec timespec;

View File

@ -22,7 +22,7 @@
#include "conn.h" #include "conn.h"
static int conn_q_recv_packet_(struct conn * conn, uint8_t * buffer,int len,int peek) static int conn_q_recv_packet_(struct cw_Conn * conn, uint8_t * buffer,int len,int peek)
{ {
if ( !conn->cur_packet) if ( !conn->cur_packet)
{ {
@ -58,12 +58,12 @@ static int conn_q_recv_packet_(struct conn * conn, uint8_t * buffer,int len,int
return conn->cur_packet_len; return conn->cur_packet_len;
} }
int conn_q_recv_packet(struct conn * conn, uint8_t * buffer,int len) int conn_q_recv_packet(struct cw_Conn * conn, uint8_t * buffer,int len)
{ {
return conn_q_recv_packet_(conn,buffer,len,0); return conn_q_recv_packet_(conn,buffer,len,0);
} }
int conn_q_recv_packet_peek(struct conn * conn, uint8_t * buffer,int len) int conn_q_recv_packet_peek(struct cw_Conn * conn, uint8_t * buffer,int len)
{ {
return conn_q_recv_packet_(conn,buffer,len,1); return conn_q_recv_packet_(conn,buffer,len,1);
} }

View File

@ -3,7 +3,7 @@
#include "conn.h" #include "conn.h"
int conn_q_wait_packet(struct conn * conn, int seconds) int conn_q_wait_packet(struct cw_Conn * conn, int seconds)
{ {
struct timespec timespec; struct timespec timespec;

View File

@ -27,7 +27,7 @@
#include "sock.h" #include "sock.h"
int conn_recv_packet_(struct conn *conn, uint8_t * buf, int len, int flags) int conn_recv_packet_(struct cw_Conn *conn, uint8_t * buf, int len, int flags)
{ {
int n; int n;
while ((n = recv(conn->sock, (char *) buf, len, flags)) < 0) { while ((n = recv(conn->sock, (char *) buf, len, flags)) < 0) {
@ -41,7 +41,7 @@ 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, int conn_recvfrom_packet(struct cw_Conn *conn, uint8_t * buf, int len,
struct sockaddr_storage *from) struct sockaddr_storage *from)
{ {
int n; int n;
@ -65,7 +65,7 @@ int conn_recvfrom_packet(struct conn *conn, uint8_t * buf, int len,
#include "log.h" #include "log.h"
int conn_recv_packet_x(struct conn *conn, uint8_t * buf, int len, int flags) int conn_recv_packet_x(struct cw_Conn *conn, uint8_t * buf, int len, int flags)
{ {
int port; int port;
socklen_t al; socklen_t al;
@ -104,12 +104,12 @@ int conn_recv_packet_x(struct conn *conn, uint8_t * buf, int len, int flags)
/* yes, these functions could be better defined as macros in a .h file */ /* 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 cw_Conn *conn, uint8_t * buf, int len)
{ {
return conn_recv_packet_x(conn, buf, len, 0); return conn_recv_packet_x(conn, buf, len, 0);
} }
int conn_recv_packet_peek(struct conn *conn, uint8_t * buf, int len) int conn_recv_packet_peek(struct cw_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; return rc;

View File

@ -29,7 +29,7 @@
#include "dbg.h" #include "dbg.h"
int conn_send_data_packet(struct conn * conn, const uint8_t * buffer, int len) int conn_send_data_packet(struct cw_Conn * conn, const uint8_t * buffer, int len)
{ {
char sock_buf[SOCK_ADDR_BUFSIZE]; char sock_buf[SOCK_ADDR_BUFSIZE];
int n; int n;

View File

@ -3,9 +3,9 @@
#include "dbg.h" #include "dbg.h"
#define CW_MODE_ZYXEL 7 #define CW_MODE_ZYXEL 7
extern cw_send_msg(struct conn * conn,uint8_t * msg); extern int cw_send_msg(struct cw_Conn * conn,uint8_t * msg);
int conn_send_msg(struct conn * conn, uint8_t *rawmsg) int conn_send_msg(struct cw_Conn * conn, uint8_t *rawmsg)
{ {
uint8_t * ptr; uint8_t * ptr;
int packetlen; int packetlen;
@ -18,9 +18,9 @@ int conn_send_msg(struct conn * conn, uint8_t *rawmsg)
/* Zyxel doesn't count msg element length from /* Zyxel doesn't count msg element length from
behind seqnum */ behind seqnum */
if (conn->capwap_mode == CW_MODE_ZYXEL){ // if (conn->capwap_mode == CW_MODE_ZYXEL){
/* // XXX val-=3; */ /* // XXX val-=3; */
} // }
ptr = rawmsg; ptr = rawmsg;
@ -34,7 +34,7 @@ mtu = 9440;
mtu = mtu >> 3; mtu = mtu >> 3;
mtu = mtu << 3; mtu = mtu << 3;
printf("packetlenX = %d (%d)\n",packetlen,hlen); // printf("packetlenX = %d (%d)\n",packetlen,hlen);
int offset = cw_get_hdr_msg_offset(rawmsg); int offset = cw_get_hdr_msg_offset(rawmsg);
return cw_send_msg(conn,rawmsg+offset); return cw_send_msg(conn,rawmsg+offset);

View File

@ -27,7 +27,7 @@
int conn_send_packet(struct conn * conn, const uint8_t * buffer, int len) int conn_send_packet(struct cw_Conn * conn, const uint8_t * buffer, int len)
{ {
int n; int n;
while((n=sendto( conn->sock, buffer, len, 0, while((n=sendto( conn->sock, buffer, len, 0,

View File

@ -1,64 +0,0 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/**
*@file
*@brief conn_send_request
*/
#include "capwap.h"
#include "cw_util.h"
#include "log.h"
/**
* Send a request message and wait for its response
* @param conn the connection
*
* The message has to be prepared and put to conn->req_msg
*
*/
/*
struct cwrmsg * conn_send_request(struct conn * conn)
{
int i;
struct cwrmsg * cwrmsg;
struct cwmsg * cwmsg = &conn->req_msg;
for (i=0; i<conn->max_retransmit; i++) {
time_t r_timer = cw_timer_start(conn->retransmit_interval);
if (i!=0)
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);
if (cwrmsg){
if (cwrmsg->type == conn->req_msg.type+1){
return cwrmsg;
}
}
}
cw_dbg(DBG_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
return 0;
}
*/

View File

@ -39,24 +39,24 @@
static int cmp_by_addr_p ( const void * d1, const void *d2 ) static int cmp_by_addr_p ( const void * d1, const void *d2 )
{ {
struct conn * c1 = * ( void ** ) d1 ; struct cw_Conn * c1 = * ( void ** ) d1 ;
struct conn * c2 = * ( void ** ) d2 ; struct cw_Conn * c2 = * ( void ** ) d2 ;
return sock_cmpaddr ( ( struct sockaddr* ) &c1->addr, ( struct sockaddr* ) &c2->addr, 1 ); return sock_cmpaddr ( ( struct sockaddr* ) &c1->addr, ( struct sockaddr* ) &c2->addr, 1 );
} }
static int cmp_by_addr ( const void * d1, const void *d2 ) static int cmp_by_addr ( const void * d1, const void *d2 )
{ {
struct conn * c1 = * ( void ** ) d1 ; struct cw_Conn * c1 = * ( void ** ) d1 ;
struct conn * c2 = * ( void ** ) d2 ; struct cw_Conn * c2 = * ( void ** ) d2 ;
return sock_cmpaddr ( ( struct sockaddr* ) &c1->addr, ( struct sockaddr* ) &c2->addr, 0 ); return sock_cmpaddr ( ( struct sockaddr* ) &c1->addr, ( struct sockaddr* ) &c2->addr, 0 );
} }
static int cmp_by_session_id ( const void *d1, const void *d2 ) static int cmp_by_session_id ( const void *d1, const void *d2 )
{ {
struct conn * c1 = *( void ** ) d1; struct cw_Conn * c1 = *( void ** ) d1;
struct conn * c2 = *( void ** ) d2; struct cw_Conn * c2 = *( void ** ) d2;
int len1,len2; int len1,len2;
if (c1->session_id==NULL && c2->session_id==NULL) if (c1->session_id==NULL && c2->session_id==NULL)
@ -133,6 +133,9 @@ void connlist_destroy ( struct connlist * cl )
if ( cl->by_addr ) if ( cl->by_addr )
mavl_destroy ( cl->by_addr ); mavl_destroy ( cl->by_addr );
if ( cl->by_session_id)
mavl_destroy ( cl->by_session_id );
pthread_mutex_destroy ( &cl->connlist_mutex ); pthread_mutex_destroy ( &cl->connlist_mutex );
free ( cl ); free ( cl );
@ -140,15 +143,15 @@ void connlist_destroy ( struct connlist * cl )
} }
struct conn * connlist_get ( struct connlist * cl, const struct sockaddr * addr ) struct cw_Conn * connlist_get ( struct connlist * cl, const struct sockaddr * addr )
{ {
struct conn search; struct cw_Conn search;
sock_copyaddr ( &search.addr, addr ); sock_copyaddr ( &search.addr, addr );
return mavl_get_ptr ( cl->by_addr, &search ); return mavl_get_ptr ( cl->by_addr, &search );
} }
struct conn * connlist_add ( struct connlist * cl, struct conn * conn ) struct cw_Conn * connlist_add ( struct connlist * cl, struct cw_Conn * conn )
{ {
if ( cl->len != 0 ) if ( cl->len != 0 )
if ( cl->by_addr->count >= cl->len ) if ( cl->by_addr->count >= cl->len )
@ -158,17 +161,17 @@ struct conn * connlist_add ( struct connlist * cl, struct conn * conn )
return mavl_insert_ptr ( cl->by_addr, conn ); return mavl_insert_ptr ( cl->by_addr, conn );
} }
struct conn * connlist_get_by_session_id ( struct connlist *cl, struct conn * conn ) struct cw_Conn * connlist_get_by_session_id ( struct connlist *cl, struct cw_Conn * conn )
{ {
return mavl_get_ptr ( cl->by_session_id, conn ); return mavl_get_ptr ( cl->by_session_id, conn );
} }
struct conn * connlist_add_by_session_id ( struct connlist * cl, struct conn * conn ) struct cw_Conn * connlist_add_by_session_id ( struct connlist * cl, struct cw_Conn * conn )
{ {
return mavl_insert_ptr ( cl->by_session_id, conn ); return mavl_insert_ptr ( cl->by_session_id, conn );
} }
void connlist_remove ( struct connlist *cl, struct conn * conn ) void connlist_remove ( struct connlist *cl, struct cw_Conn * conn )
{ {
void * md; void * md;
md = conn; md = conn;

View File

@ -7,7 +7,7 @@
#include "pthread.h" #include "pthread.h"
struct connlist { struct connlist {
/* struct conn ** connlist; */ /* struct cw_Conn ** connlist; */
struct mavl *by_addr; struct mavl *by_addr;
struct mavl *by_session_id; struct mavl *by_session_id;
@ -22,12 +22,12 @@ struct connlist *connlist_create(int len, int cmpports);
void connlist_lock(struct connlist *cl); void connlist_lock(struct connlist *cl);
void connlist_unlock(struct connlist *cl); void connlist_unlock(struct connlist *cl);
void conlist_destroy(struct connlist *cl); void conlist_destroy(struct connlist *cl);
struct conn *connlist_get(struct connlist *cl, const struct sockaddr *addr); struct cw_Conn *connlist_get(struct connlist *cl, const struct sockaddr *addr);
struct conn *connlist_add(struct connlist *cl, struct conn *conn); struct cw_Conn *connlist_add(struct connlist *cl, struct cw_Conn *conn);
void connlist_remove(struct connlist *cl, struct conn *conn); void connlist_remove(struct connlist *cl, struct cw_Conn *conn);
void connlist_destroy(struct connlist *cl); void connlist_destroy(struct connlist *cl);
struct conn * connlist_get_by_session_id(struct connlist *cl, struct conn * conn); struct cw_Conn * connlist_get_by_session_id(struct connlist *cl, struct cw_Conn * conn);
struct conn * connlist_add_by_session_id(struct connlist * cl, struct conn * conn); struct cw_Conn * connlist_add_by_session_id(struct connlist * cl, struct cw_Conn * conn);
#endif #endif

136
src/cw/cw.c Normal file
View File

@ -0,0 +1,136 @@
#include "cw.h"
#include "log.h"
#include "dbg.h"
int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
cw_Type_t * type;
type = (cw_Type_t*)handler->type;
char mkey[CW_CFG_MAX_KEY_LEN];
const char *key;
if (!type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
}
if (handler->mkkey != NULL){
handler->mkkey(handler->key,elem_data,elem_len, mkey);
key = mkey;
}
else{
key = handler->key;
}
/* cw_dbg(DBG_X, "READ: %s / %s",type->name,key);*/
type->read(params->cfg, key,elem_data,elem_len,handler->param);
return CAPWAP_RESULT_SUCCESS;
}
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
int start, len, l;
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// cw_cfg_dump(params->cfg);
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!! ENDDUMP");
start = params->msgset->header_len(handler);
len = ((const cw_Type_t*)(handler->type))->
write(params->cfg_list,handler->key,dst+start,handler->param);
if (len == -1) {
const char *vendor="";
if ( handler->vendor ) {
vendor=cw_strvendor(handler->vendor);
}
if ( params->elemdata->mand) {
cw_log(LOG_ERR,
"Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.",
vendor, handler->id, handler->name, params->msgdata->name
, handler->key
);
}
else{
/* cw_dbg(DBG_WARN,"No output for element %s%d -(%s) in %s. Item %s not found.",
vendor,
a->elem_id, cw_strelemp(conn->actions, a->elem_id)
, cw_strmsg(a->msg_id),a->item_id);
*/
}
return 0;
}
l = params->msgset->write_header(handler,dst,len);
return l;
}
int cw_in_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
char key[CW_CFG_MAX_KEY_LEN];
int radio;
struct cw_Type *type;
type = (struct cw_Type*)handler->type;
if (!type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
}
radio=cw_get_byte(elem_data);
sprintf(key,"radio.%d/%s",radio,handler->key);
/*cw_cfg_set_val(params->cfg, key,
handler->type, handler->param, elem_data+1,elem_len-1);*/
type->read(params->cfg, key,elem_data+1,elem_len-1,handler->param);
return CAPWAP_RESULT_SUCCESS;
}
int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
char key[CW_CFG_MAX_KEY_LEN];
struct cw_Type * type;
int len,i,l,start;
int radios;
len =0;
radios = cw_cfg_get_byte(params->cfg,"wtp-descriptor/max-radios",0);
for(i=0;i<radios;i++){
l=0;
type = (struct cw_Type*)handler->type;
start = params->msgset->header_len(handler)+len;
sprintf(key,"radio.%d/%s",i,handler->key);
cw_dbg(DBG_X,"KEY: %s",key);
l += cw_put_byte(dst+start+l,i);
l += type->write(params->cfg_list, key,dst+start+l,handler->param);
l = params->msgset->write_header(handler,dst+len,l);
len+=l;
}
return len;
}

View File

@ -327,7 +327,7 @@ int cw_put_elem_result_code(uint8_t * dst, uint32_t code);
/*extern int cw_put_ac_status(uint8_t * dst, struct cw_ac_status *s, struct conn *conn);*/ /*extern int cw_put_ac_status(uint8_t * dst, struct cw_ac_status *s, struct cw_Conn *conn);*/
struct cw_DescriptorSubelemDef { struct cw_DescriptorSubelemDef {
@ -356,12 +356,12 @@ extern int cw_read_descriptor_subelems(mavl_t store, const char * key, uint8_t *
struct cw_DescriptorSubelemDef *elems); struct cw_DescriptorSubelemDef *elems);
/* /*
int cw_read_wtp_descriptor(mavl_t mbag, struct conn *conn, int cw_read_wtp_descriptor(mavl_t mbag, struct cw_Conn *conn,
struct cw_ElemHandler *eh, uint8_t * data, int len, struct cw_ElemHandler *eh, uint8_t * data, int len,
struct cw_DescriptorSubelemDef *allowed); struct cw_DescriptorSubelemDef *allowed);
*/ */
int cw_read_wtp_descriptor(mavl_t mbag, struct conn *conn, int cw_read_wtp_descriptor(mavl_t mbag, struct cw_Conn *conn,
struct cw_ElemHandler *eh, uint8_t * data, int len, struct cw_ElemHandler *eh, uint8_t * data, int len,
struct cw_DescriptorSubelemDef *allowed); struct cw_DescriptorSubelemDef *allowed);
@ -372,7 +372,7 @@ int cw_write_radio_element(struct cw_ElemHandler * handler, struct cw_ElemHandle
uint8_t * dst); uint8_t * dst);
extern int cw_read_wtp_descriptor_7(mavl_t mbag, struct conn *conn, extern int cw_read_wtp_descriptor_7(mavl_t mbag, struct cw_Conn *conn,
struct cw_ElemHandler *eh, uint8_t * data, int len, struct cw_ElemHandler *eh, uint8_t * data, int len,
struct cw_DescriptorSubelemDef *allowed); struct cw_DescriptorSubelemDef *allowed);
@ -384,7 +384,7 @@ int cw_read_ac_descriptor(mavl_t store,
struct cw_DescriptorSubelemDef *allowed); struct cw_DescriptorSubelemDef *allowed);
int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * default_cipher); int cw_setup_dtls(struct cw_Conn * conn, mavl_t cfg, const char *prefix, char * default_cipher);
@ -444,11 +444,11 @@ int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerP
int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst); , uint8_t * dst);
extern int cw_in_wtp_reboot_statistics(struct conn *conn, struct cw_action_in *a, extern int cw_in_wtp_reboot_statistics(struct cw_Conn *conn, struct cw_action_in *a,
uint8_t * data, int len, struct sockaddr *from); uint8_t * data, int len, struct sockaddr *from);
extern int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, extern int cw_in_wtp_board_data(struct cw_Conn *conn, struct cw_action_in *a, uint8_t * data,
int len, struct sockaddr *from); int len, struct sockaddr *from);
/* /*
@ -457,24 +457,24 @@ int cw_in_vendor_specific_payload(struct cw_ElemHandler *handler,
uint8_t * data, int len); uint8_t * data, int len);
*/ */
extern int cw_in_capwap_control_ip_address(struct conn *conn, struct cw_action_in *a, extern int cw_in_capwap_control_ip_address(struct cw_Conn *conn, struct cw_action_in *a,
uint8_t * data, int len, uint8_t * data, int len,
struct sockaddr *from); struct sockaddr *from);
extern int cw_in_capwap_local_ipv4_address(struct conn *conn, struct cw_action_in *a, extern int cw_in_capwap_local_ipv4_address(struct cw_Conn *conn, struct cw_action_in *a,
uint8_t * data, int len, uint8_t * data, int len,
struct sockaddr *from); struct sockaddr *from);
extern int cw_in_capwap_local_ipv6_address(struct conn *conn, struct cw_action_in *a, extern int cw_in_capwap_local_ipv6_address(struct cw_Conn *conn, struct cw_action_in *a,
uint8_t * data, int len, uint8_t * data, int len,
struct sockaddr *from); struct sockaddr *from);
extern int cw_in_radio_operational_state(struct conn *conn, struct cw_action_in *a, extern int cw_in_radio_operational_state(struct cw_Conn *conn, struct cw_action_in *a,
uint8_t * data, int len, struct sockaddr *from); uint8_t * data, int len, struct sockaddr *from);
/* /*
int cw_process_element(struct conn * conn, int cw_process_element(struct cw_Conn * conn,
struct cw_MsgData * msgdata, int proto, int vendor, struct cw_MsgData * msgdata, int proto, int vendor,
uint8_t * elem, int max_len); uint8_t * elem, int max_len);
*/ */
@ -502,7 +502,7 @@ int cw_process_element(struct cw_ElemHandlerParams *params,
#define cw_out_capwap_local_ip_address_7 cw_out_wtp_ip_address #define cw_out_capwap_local_ip_address_7 cw_out_wtp_ip_address
void cw_init_request(struct conn *conn, int msg_id); void cw_init_request(struct cw_Conn *conn, int msg_id);
/** /**
@ -527,16 +527,16 @@ int cw_put_elem_radio_administrative_state(uint8_t * dst, int rid, int state);
int cw_put_local_ip_address(uint8_t *dst, int id, int ipv_id, int ipv6_id, int cw_put_local_ip_address(uint8_t *dst, int id, int ipv_id, int ipv6_id,
uint8_t *src, int len); uint8_t *src, int len);
int cw_detect_nat(struct conn *conn); int cw_detect_nat(struct cw_ElemHandlerParams *conn);
uint8_t *cw_init_data_keep_alive_msg(uint8_t * buffer,uint8_t *rmac); uint8_t *cw_init_data_keep_alive_msg(uint8_t * buffer,uint8_t *rmac);
/*int cw_out_radio_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst);*/ /*int cw_out_radio_generic(struct cw_Conn *conn, struct cw_action_out *a, uint8_t * dst);*/
int cw_put_elem_session_id(uint8_t *dst, uint8_t *session_id, int len); int cw_put_elem_session_id(uint8_t *dst, uint8_t *session_id, int len);
int cw_result_is_ok( int rc ); int cw_result_is_ok( int rc );
int cw_put_msg(struct conn *conn, uint8_t * rawout); int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout);
/** /**
* @} * @}

View File

@ -11,7 +11,7 @@ int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,
struct cw_ElemData *elem_data, elem_data_search; struct cw_ElemData *elem_data, elem_data_search;
int rc; int rc;
params->elem = NULL; //params->elem = NULL;
/* try to retrieve a handler for this message element */ /* try to retrieve a handler for this message element */
handler = handler =
@ -66,10 +66,8 @@ int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
} }
printf ("USING HANDLERi TO DECODE: %d %s\n",handler->id,handler->name);
rc = handler->get(handler, params, data, len); rc = handler->get(handler, params, data, len);
return rc; return rc;
} }
@ -123,4 +121,7 @@ int cw_decode_elements(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr
} }
mavl_destroy(mand_found);
mlist_destroy(unrecognized);
return 0;
} }

View File

@ -10,15 +10,13 @@
* @retval 1 NAT detected * @retval 1 NAT detected
* @retval 0 no NAT was detected * @retval 0 no NAT was detected
*/ */
int cw_detect_nat(struct conn *conn) int cw_detect_nat(struct cw_ElemHandlerParams *params)
{ {
cw_Val_t * result; const char * remote_str;
char local_str[128]; char local_str[128];
char remote_str[128];
result = cw_ktv_get(conn->remote_cfg,"capwap-local-ip-address",CW_TYPE_IPADDRESS); remote_str = cw_cfg_get(params->cfg,"capwap-local-ip-address",NULL);
if (result == NULL){ if (remote_str == NULL){
cw_dbg(DBG_WARN,"Can't detect NAT. No local IP from peer received."); cw_dbg(DBG_WARN,"Can't detect NAT. No local IP from peer received.");
return 0; return 0;
} }
@ -26,8 +24,7 @@ int cw_detect_nat(struct conn *conn)
/* convert remote connected and sent ip addresse to /* convert remote connected and sent ip addresse to
* strings */ * strings */
sock_addrtostr((struct sockaddr*)&conn->addr,local_str,128,0); sock_addrtostr((struct sockaddr*)&(params->conn->addr),local_str,128,0);
result->type->to_str(result,remote_str,128);
/* if connected and sent address is the same, there is /* if connected and sent address is the same, there is
@ -37,3 +34,4 @@ int cw_detect_nat(struct conn *conn)
/* otherwise ther must be something between AC and WTP */ /* otherwise ther must be something between AC and WTP */
return 1; return 1;
} }

View File

@ -35,10 +35,6 @@ int cw_format_version(char *s, const uint8_t * version, int len)
} }
rs += sprintf(s + rs, ")"); rs += sprintf(s + rs, ")");
} }
/*
vendor = bstrv_get_vendor_id(ver);
rs += sprintf(s + rs, ", Vendor Id: %d, %s", vendor, cw_strvendor(vendor));
*/
return rs; return rs;
} }

View File

@ -9,7 +9,7 @@
int cw_in_capwap_local_ipv6_address(struct conn *conn, struct cw_action_in *a, int cw_in_capwap_local_ipv6_address(struct cw_Conn *conn, struct cw_action_in *a,
uint8_t * data, int len,struct sockaddr *from) uint8_t * data, int len,struct sockaddr *from)
{ {
struct sockaddr_in6 addr; struct sockaddr_in6 addr;

View File

@ -1,32 +0,0 @@
#include "capwap.h"
#include "intavltree.h"
#include "dbg.h"
#include "log.h"
int cw_in_check_cfg_update_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
/*cw_action_in_t * mlist[60];*/
/* Check for mandatory elements */
/* int n = cw_check_missing_mand(mlist,conn,a);
if (n) {
if ( conn->strict_capwap ){
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
conn->capwap_state=CAPWAP_STATE_JOIN;
return CW_RESULT_MISSING_MAND_ELEM;
}
cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a);
}
*/
/* set result code to ok and change to configure state */
/*mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0);*/
return 0;
}

View File

@ -3,19 +3,35 @@
#include "msgset.h" #include "msgset.h"
#include "val.h" #include "val.h"
#include "log.h" #include "log.h"
#include "dbg.h"
int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len) uint8_t * elem_data, int elem_len)
{ {
cw_Val_t * result; cw_Type_t * type;
type = (cw_Type_t*)handler->type;
char mkey[CW_CFG_MAX_KEY_LEN];
const char *key;
if (!handler->type){
if (!type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
} }
result = cw_ktv_add(params->remote_cfg, handler->key, if (handler->mkkey != NULL){
handler->type,NULL, elem_data,elem_len); handler->mkkey(handler->key,elem_data,elem_len, mkey);
params->elem=result; key = mkey;
}
else{
key = handler->key;
}
/* cw_dbg(DBG_X, "READ: %s / %s",type->name,key);*/
type->read(params->cfg, key,elem_data,elem_len,handler->param);
return CAPWAP_RESULT_SUCCESS; return CAPWAP_RESULT_SUCCESS;
} }

View File

@ -17,7 +17,7 @@ int cw_in_generic_enum(struct cw_ElemHandler * handler, struct cw_ElemHandlerPar
{ {
int val; int val;
const cw_ValEnum_t * e; const cw_ValEnum_t * e;
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
struct cw_ElemHandler thandler; struct cw_ElemHandler thandler;
val = cw_get_byte(elem_data+1); val = cw_get_byte(elem_data+1);

View File

@ -1,6 +1,8 @@
#include "cw.h" #include "cw.h"
#include "cfg.h"
static const cw_ValEnum_t * get_enum(const cw_ValEnum_t * e, int val){ static const cw_ValEnum_t * get_enum(const cw_ValEnum_t * e, int val){
@ -21,7 +23,7 @@ int cw_in_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemHa
const cw_ValEnum_t * e; const cw_ValEnum_t * e;
const cw_ValIndexed_t * ie; const cw_ValIndexed_t * ie;
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
struct cw_ElemHandler thandler; struct cw_ElemHandler thandler;
ie = handler->type; ie = handler->type;
@ -46,8 +48,11 @@ int cw_in_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemHa
} }
memset(&thandler,0,sizeof(thandler)); memset(&thandler,0,sizeof(thandler));
thandler.type=e->type;
thandler.key=key; thandler.key=key;
thandler.type=e->type;
thandler.param=e->param;
return e->fun_in(&thandler,params,elem_data+f,elem_len-l); return e->fun_in(&thandler,params,elem_data+f,elem_len-l);
} }

View File

@ -3,12 +3,16 @@
#include "msgset.h" #include "msgset.h"
#include "val.h" #include "val.h"
#include "log.h" #include "log.h"
#include "dbg.h"
int cw_in_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int cw_in_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len) uint8_t * elem_data, int elem_len)
{ {
cw_dbg(DBG_X,"STRUCT KEY: %s",handler->key);
stop();
const char * key; const char * key;
char tmpkey[CW_KTV_MAX_KEY_LEN]; char tmpkey[CW_CFG_MAX_KEY_LEN];
if (handler->mkkey != NULL){ if (handler->mkkey != NULL){
handler->mkkey(key,elem_data,elem_len, tmpkey); handler->mkkey(key,elem_data,elem_len, tmpkey);
@ -29,7 +33,7 @@ printf("CW_IN_GENERIC STRUCT: %s\n",key);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
} }
cw_ktv_read_struct(params->remote_cfg,handler->type,key,elem_data,elem_len); cw_ktv_read_struct(params->cfg,handler->type,key,elem_data,elem_len);
return CAPWAP_RESULT_SUCCESS; return CAPWAP_RESULT_SUCCESS;
} }

View File

@ -1,14 +1,18 @@
#include "cw.h" #include "cw.h"
#include "dbg.h"
int cw_in_generic_with_index(struct cw_ElemHandler *eh, int cw_in_generic_with_index(struct cw_ElemHandler *eh,
struct cw_ElemHandlerParams *params, struct cw_ElemHandlerParams *params,
uint8_t * data, int len) uint8_t * data, int len)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
int idx; int idx;
cw_dbg(DBG_X,"Fix cw_in_generic_with_index");
stop();
idx = cw_get_byte(data); idx = cw_get_byte(data);
sprintf(key,"%s.%d",eh->key,idx); sprintf(key,"%s.%d",eh->key,idx);
cw_ktv_add(params->remote_cfg,key,eh->type,NULL,data+1,len-1); // cw_cfg_add(params->cfg,key,eh->type,NULL,data+1,len-1);
return 1; return 1;
} }

View File

@ -1,9 +1,12 @@
#include "cw.h" #include "cw.h"
#include "log.h" #include "log.h"
#include "dbg.h"
int cw_in_idx_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int cw_in_idx_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len) uint8_t * elem_data, int elem_len)
{ {
stop();
/*
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_KTV_MAX_KEY_LEN];
cw_Val_t * result; cw_Val_t * result;
int idx; int idx;
@ -16,10 +19,10 @@ int cw_in_idx_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerPara
idx=cw_get_byte(elem_data); idx=cw_get_byte(elem_data);
sprintf(key,handler->key,idx); sprintf(key,handler->key,idx);
result = cw_ktv_add(params->remote_cfg, key, result = cw_ktv_add(params->cfg, key,
handler->type, NULL, elem_data+1,elem_len-1); handler->type, NULL, elem_data+1,elem_len-1);
params->elem=result; // params->elem=result;
*/
return CAPWAP_RESULT_SUCCESS; return CAPWAP_RESULT_SUCCESS;
} }

View File

@ -4,13 +4,19 @@
#include "val.h" #include "val.h"
#include "log.h" #include "log.h"
#include "cw.h" #include "cw.h"
#include "dbg.h"
int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len) uint8_t * elem_data, int elem_len)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
int idx; int idx;
cw_dbg(DBG_X,"Fix cw_in_idx_generic_struct");
stop();
if (!handler->type){ if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
@ -19,7 +25,7 @@ int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHand
idx = cw_get_byte(elem_data); idx = cw_get_byte(elem_data);
sprintf(key, handler->key, idx); sprintf(key, handler->key, idx);
cw_ktv_read_struct(params->remote_cfg,handler->type,key,elem_data+1,elem_len-1); cw_ktv_read_struct(params->cfg,handler->type,key,elem_data+1,elem_len-1);
return CAPWAP_RESULT_SUCCESS; return CAPWAP_RESULT_SUCCESS;
} }

View File

@ -5,10 +5,15 @@
#include "log.h" #include "log.h"
#include "cw.h" #include "cw.h"
#include "dbg.h"
int cw_in_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int cw_in_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len) uint8_t * elem_data, int elem_len)
{ {
char key[CW_KTV_MAX_KEY_LEN];
stop();
char key[CW_CFG_MAX_KEY_LEN];
int radio; int radio;
if (!handler->type){ if (!handler->type){
@ -19,7 +24,7 @@ int cw_in_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHa
radio = cw_get_byte(elem_data); radio = cw_get_byte(elem_data);
sprintf(key,"radio.%d/%s",radio,handler->key); sprintf(key,"radio.%d/%s",radio,handler->key);
cw_ktv_read_struct(params->remote_cfg,handler->type,key,elem_data+1,elem_len-1); cw_ktv_read_struct(params->cfg,handler->type,key,elem_data+1,elem_len-1);
/*params->elem=result;*/ /*params->elem=result;*/

View File

@ -21,7 +21,7 @@
#include "log.h" #include "log.h"
int cw_in_wtp_reboot_statistics(struct conn *conn, struct cw_action_in *a, uint8_t * data, int cw_in_wtp_reboot_statistics(struct cw_Conn *conn, struct cw_action_in *a, uint8_t * data,
int len, struct sockaddr *from) int len, struct sockaddr *from)
{ {
/* /*

View File

@ -10,7 +10,6 @@ cw_Val_t * cw_ktv_add(mavl_t kvtstore, const char *key, const struct cw_Type *ty
{ {
cw_Val_t mdata, *mresult; cw_Val_t mdata, *mresult;
int exists; int exists;
mdata.key=cw_strdup(key); mdata.key=cw_strdup(key);
mdata.valguard=valguard; mdata.valguard=valguard;

View File

@ -1,22 +0,0 @@
#include "val.h"
void cw_ktv_del_sub(mavl_t ktvstore, const char *basekey)
{
cw_Val_t * result, search;
while (1){
search.key=(char*)basekey;
result = mavl_get_first(ktvstore,&search);
if (result == NULL)
return;
if (strncmp(result->key,basekey,strlen(basekey))!=0)
break;
search.key = result->key;
mavl_del(ktvstore,&search);
}
}

View File

@ -1,4 +1,5 @@
#include "val.h" #include "val.h"
#include "cfg.h"
void * ktvn(struct mavl *t ,const void *search) void * ktvn(struct mavl *t ,const void *search)
{ {
@ -45,7 +46,7 @@ void * ktvn(struct mavl *t ,const void *search)
int cw_ktv_idx_get(mavl_t ktv, const char *key) int cw_ktv_idx_get(mavl_t ktv, const char *key)
{ {
char ikey[CW_KTV_MAX_KEY_LEN]; char ikey[CW_CFG_MAX_KEY_LEN];
cw_Val_t search, * result; cw_Val_t search, * result;
char *d; char *d;
@ -75,7 +76,7 @@ int cw_ktv_idx_get(mavl_t ktv, const char *key)
int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n) int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n)
{ {
char ikey[CW_KTV_MAX_KEY_LEN]; char ikey[CW_CFG_MAX_KEY_LEN];
cw_Val_t search, * result; cw_Val_t search, * result;
char *d; char *d;
int i; int i;

View File

@ -1,10 +1,10 @@
#include "val.h" #include "val.h"
#include "cfg.h"
int cw_ktv_read_file(FILE * file, mavl_t ktv, mavl_t types) int cw_ktv_read_file(FILE * file, mavl_t ktv, mavl_t types)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
char type[256]; char type[256];
char val[2048]; char val[2048];

View File

@ -1,10 +1,11 @@
#include "val.h" #include "val.h"
#include "dbg.h" #include "dbg.h"
#include "cfg.h"
int cw_ktv_read_struct(mavl_t ktv,const cw_ValStruct_t * stru, const char *pkey, int cw_ktv_read_struct(mavl_t ktv,const cw_ValStruct_t * stru, const char *pkey,
uint8_t * data, int len) uint8_t * data, int len)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
int pos, i,l; int pos, i,l;
cw_Val_t * result; cw_Val_t * result;

View File

@ -1,6 +1,7 @@
#include <ctype.h> #include <ctype.h>
#include "val.h" #include "val.h"
#include "cfg.h"
struct parser { struct parser {
int line; int line;
@ -10,13 +11,14 @@ struct parser {
int quote; int quote;
FILE *f; FILE *f;
int (*getc)(struct parser *); int (*getc)(struct parser *);
void (*ungetc)(struct parser *) void (*ungetc)(struct parser *);
}; };
/*
static int pgetc(struct parser *parser) static int pgetc(struct parser *parser)
{ {
return fgetc(parser->f); return fgetc(parser->f);
} }*/
static int get_char(struct parser *p) static int get_char(struct parser *p)
{ {
@ -290,13 +292,13 @@ int cw_ktv_read_line (FILE *f, char * key, char * type, char *val)
p.quote=0; p.quote=0;
p.f=f; p.f=f;
n = read_key (&p,key,CW_KTV_MAX_KEY_LEN); n = read_key (&p,key,CW_CFG_MAX_KEY_LEN);
n = read_type (&p,type,CW_KTV_MAX_KEY_LEN); n = read_type (&p,type,CW_CFG_MAX_KEY_LEN);
if (n==-1){ if (n==-1){
return -1; return -1;
} }
n = read_val (&p,val,CW_KTV_MAX_KEY_LEN); n = read_val (&p,val,CW_CFG_MAX_KEY_LEN);
if (n==-1){ if (n==-1){
return -1; return -1;
} }

View File

@ -1,11 +1,12 @@
#include "val.h" #include "val.h"
#include "dbg.h" #include "dbg.h"
#include "log.h" #include "log.h"
#include "cfg.h"
int cw_ktv_write_struct(mavl_t ktv, mavl_t def, const cw_ValStruct_t * stru, const char *pkey, int cw_ktv_write_struct(mavl_t ktv, mavl_t def, const cw_ValStruct_t * stru, const char *pkey,
uint8_t * dst) uint8_t * dst)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
int pos, i; int pos, i;
cw_Val_t * result; cw_Val_t * result;

View File

@ -1,80 +0,0 @@
#include "cw.h"
#include "dbg.h"
#include "log.h"
#include "msgset.h"
#include "val.h"
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
struct cw_Val * elem;
int start, len, l;
/* Get the element */
/* search.key=(char*)handler->key;
elem = mavl_get(params->conn->local_cfg, &search);
*/
elem = cw_ktv_get(params->local_cfg,handler->key,NULL);
/* if (elem == NULL && params->conn->default_cfg !=NULL)
elem = mavl_get(params->conn->default_cfg, &search);
*/
if (elem == NULL) {
const char *vendor="";
if ( handler->vendor ) {
vendor=cw_strvendor(handler->vendor);
}
if ( params->elemdata->mand) {
cw_log(LOG_ERR,
"Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.",
vendor, handler->id, handler->name, params->msgdata->name
, handler->key
);
}
else{
/* cw_dbg(DBG_WARN,"No output for element %s%d -(%s) in %s. Item %s not found.",
vendor,
a->elem_id, cw_strelemp(conn->actions, a->elem_id)
, cw_strmsg(a->msg_id),a->item_id);
*/
}
return 0;
}
/* Size for msg elem header depends on
vendor specific payload */
/* start = handler->vendor ? 10 : 4; */
start = params->msgset->header_len(handler);
if (cw_ktv_cast(elem,handler->type)==NULL){
cw_log(LOG_ERR,"Can't put element '%s'- can't cast from %s to %s for key: %s", handler->name,
elem->type->name, ((const cw_Type_t*)handler->type)->name, handler->key);
return 0;
}
len = ((const cw_Type_t*)(handler->type))->put(elem,dst+start);
/* ((const cw_Type_t*)(handler->type))->to_str(elem,detail,120);
sprintf(params->debug_details, " Value = %s", detail);
params->elem = elem;*/
/* if (handler->vendor)
return len + cw_put_elem_vendor_hdr(dst, handler->vendor, handler->id, len);
l = len + cw_put_elem_hdr(dst, handler->id, len); */
l = params->msgset->write_header(handler,dst,len);
cw_dbg_elem(DBG_ELEM_OUT,NULL,params->msgdata->type,handler,dst,l);
/* cw_dbg_elem(DBG_ELEM_OUT,params->conn,params->msgdata->type,handler,dst,l);*/
return l;
}

View File

@ -1,9 +1,15 @@
#include "cw.h" #include "cw.h"
#include"dbg.h"
int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst) , uint8_t * dst)
{ {
char key[CW_KTV_MAX_KEY_LEN]; cw_dbg(DBG_X,"Fix: cw_out_generic_indexed_enum");
stop();
/*
char key[CW_CFG_MAX_KEY_LEN];
int i; int i;
cw_Val_t * result; cw_Val_t * result;
int len,start; int len,start;
@ -24,7 +30,7 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
//printf("Her is the Key: %s - %s\n",key, ); //printf("Her is the Key: %s - %s\n",key, );
result = cw_ktv_base_exists(params->local_cfg,key); result = cw_ktv_base_exists(params->cfg,key);
if (result==NULL) if (result==NULL)
continue; continue;
start = params->msgset->header_len(handler); start = params->msgset->header_len(handler);
@ -35,7 +41,7 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
if (e[i].fun_out==NULL) if (e[i].fun_out==NULL)
len += result->type->put(result,ob+start+len); len += result->type->put(result,ob+start+len);
else else
len += cw_ktv_write_struct(params->local_cfg, len += cw_ktv_write_struct(params->cfg,
NULL,e[i].type,key,ob+start+len); NULL,e[i].type,key,ob+start+len);
cw_set_byte(ob+start+ie->idxpos,e[i].value); cw_set_byte(ob+start+ie->idxpos,e[i].value);
@ -47,5 +53,7 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
} }
return ob-dst; return ob-dst;
*/
return 0;
} }

View File

@ -4,9 +4,16 @@
#include "log.h" #include "log.h"
#include "cw.h" #include "cw.h"
#include "dbg.h"
int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst) , uint8_t * dst)
{ {
cw_dbg(DBG_X,"Key: %s",handler->key);
stop();
int start; int start;
int len; int len;
cw_Val_t search, *result; cw_Val_t search, *result;
@ -17,7 +24,7 @@ int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandler
} }
search.key = (char*)handler->key; search.key = (char*)handler->key;
result = mavl_get_first(params->local_cfg,&search); result = mavl_get_first(params->cfg,&search);
if (result == NULL ){ if (result == NULL ){
if (params->elemdata->mand) if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name); cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
@ -32,8 +39,8 @@ int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandler
start = params->msgset->header_len(handler); start = params->msgset->header_len(handler);
len = cw_ktv_write_struct(params->local_cfg, len = cw_ktv_write_struct(params->cfg,
params->default_cfg, params->cfg,
handler->type,handler->key,dst+start); handler->type,handler->key,dst+start);
return params->msgset->write_header(handler,dst,len); return params->msgset->write_header(handler,dst,len);

View File

@ -1,11 +1,13 @@
#include "cw.h" #include "cw.h"
#include "dbg.h"
int cw_out_generic_with_index(struct cw_ElemHandler * eh, int cw_out_generic_with_index(struct cw_ElemHandler * eh,
struct cw_ElemHandlerParams * params, uint8_t * dst) struct cw_ElemHandlerParams * params, uint8_t * dst)
{ {
char key[CW_KTV_MAX_KEY_LEN]; stop();
char key[CW_CFG_MAX_KEY_LEN];
int idx; int idx;
cw_Val_t * result, search; cw_Val_t * result, search;
int len,start; int len,start;
@ -18,7 +20,7 @@ int cw_out_generic_with_index(struct cw_ElemHandler * eh,
do { do {
sprintf(key,"%s.%d",eh->key,idx); sprintf(key,"%s.%d",eh->key,idx);
search.key=key; search.key=key;
result = mavl_get_first(params->local_cfg,&search); result = mavl_get_first(params->cfg,&search);
if (result==NULL) if (result==NULL)
break; break;
if (strncmp(result->key,key,strlen(key))!=0) if (strncmp(result->key,key,strlen(key))!=0)

View File

@ -5,7 +5,10 @@
int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst) , uint8_t * dst)
{ {
char key[CW_KTV_MAX_KEY_LEN];
stop();
char key[CW_CFG_MAX_KEY_LEN];
struct cw_Val * elem, search; struct cw_Val * elem, search;
int i; int i;
int idx, sr; int idx, sr;
@ -24,7 +27,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
sprintf(key,handler->key,i); sprintf(key,handler->key,i);
search.key=key; search.key=key;
/*elem = mavl_get(params->conn->local_cfg, &search);*/ /*elem = mavl_get(params->conn->local_cfg, &search);*/
elem = mavl_get_first(params->local_cfg,&search); elem = mavl_get_first(params->cfg,&search);
if(elem != NULL){ if(elem != NULL){
printf("Elem key: %s\n",elem->key); printf("Elem key: %s\n",elem->key);
} }
@ -41,7 +44,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
start = mdst + params->msgset->header_len(handler); start = mdst + params->msgset->header_len(handler);
len += cw_put_byte(start+len,idx); len += cw_put_byte(start+len,idx);
len += cw_ktv_write_struct(params->local_cfg,NULL, handler->type,key,start+len); len += cw_ktv_write_struct(params->cfg,NULL, handler->type,key,start+len);
mdst += params->msgset->write_header(handler,mdst,len); mdst += params->msgset->write_header(handler,mdst,len);

View File

@ -1,32 +0,0 @@
#include "cw.h"
#include "dbg.h"
int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n);
int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
int len,i,l;
int radios;
len =0;
/* int idx=0;*/
/* while(1){
char key[CW_KTV_MAX_KEY_LEN];
sprintf(key,"radio.%d",idx);
idx = cw_ktv_idx_get_next(params->conn->local_cfg,key,idx);
idx++;
}
*/
radios = cw_ktv_get_byte(params->local_cfg,"wtp-descriptor/max-radios",0);
for(i=0;i<radios;i++){
l = cw_write_radio_element(handler,params,i,dst+len);
cw_dbg_elem(DBG_ELEM_OUT,NULL,params->msgdata->type,handler,dst,l);
len+=l;
}
return len;
}

View File

@ -7,6 +7,9 @@ int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n);
int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst) , uint8_t * dst)
{ {
cw_dbg(DBG_X,"KEY: %s",handler->key);
stop();
/*
int i,l, offset; int i,l, offset;
uint8_t * cdst; uint8_t * cdst;
@ -18,15 +21,15 @@ int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemH
i=-1; i=-1;
while(1){ while(1){
char basekey[CW_KTV_MAX_KEY_LEN]; char basekey[CW_CFG_MAX_KEY_LEN];
cw_Val_t * result; cw_Val_t * result;
i = cw_ktv_idx_get_next(params->local_cfg,"radio",i+1); i = cw_ktv_idx_get_next(params->cfg,"radio",i+1);
if (i==-1) if (i==-1)
break; break;
sprintf(basekey,"radio.%d/%s",i,handler->key); sprintf(basekey,"radio.%d/%s",i,handler->key);
result = cw_ktv_base_exists(params->local_cfg,basekey); result = cw_ktv_base_exists(params->cfg,basekey);
if (result == NULL){ if (result == NULL){
continue; continue;
} }
@ -34,7 +37,7 @@ int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemH
l=0; l=0;
l+=cw_put_byte(cdst+offset+l,i); l+=cw_put_byte(cdst+offset+l,i);
l+= cw_ktv_write_struct(params->local_cfg,NULL, handler->type,basekey,cdst+offset+l); l+= cw_ktv_write_struct(params->cfg,NULL, handler->type,basekey,cdst+offset+l);
cdst+=params->msgset->write_header(handler,cdst,l); cdst+=params->msgset->write_header(handler,cdst,l);
@ -49,7 +52,7 @@ int cw_out_traverse0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParam
{ {
char *sl; char *sl;
int l; int l;
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
int len; int len;
len = 0; len = 0;
@ -59,7 +62,7 @@ printf("Next: %s\n", next);
if (sl==NULL){ if (sl==NULL){
cw_Val_t * result; cw_Val_t * result;
sprintf(key,"%s/%s",current,next); sprintf(key,"%s/%s",current,next);
result = cw_ktv_base_exists(params->local_cfg,key); result = cw_ktv_base_exists(params->cfg,key);
if (result != NULL){ if (result != NULL){
int offset; int offset;
int i,l; int i,l;
@ -68,7 +71,7 @@ printf("Next: %s\n", next);
for (i=0;i<stack[0];i++){ for (i=0;i<stack[0];i++){
printf("I=%i\n",stack[i+1]); printf("I=%i\n",stack[i+1]);
} }
l= cw_ktv_write_struct(params->local_cfg,params->default_cfg, l= cw_ktv_write_struct(params->cfg,params->cfg,
handler->type,key,dst+offset); handler->type,key,dst+offset);
printf("Write struct len %i\n",l); printf("Write struct len %i\n",l);
@ -96,19 +99,19 @@ printf("current is %s\n", current);
printf("Here we are %s\n",key); printf("Here we are %s\n",key);
cw_dbg_ktv_dump(params->local_cfg,DBG_INFO,"start"," ", "end" ); cw_dbg_ktv_dump(params->cfg,DBG_INFO,"start"," ", "end" );
i=-1; i=-1;
while(1){ while(1){
char basekey[CW_KTV_MAX_KEY_LEN]; char basekey[CW_CFG_MAX_KEY_LEN];
cw_Val_t * result; cw_Val_t * result;
i = cw_ktv_idx_get_next(params->local_cfg,key,i+1); i = cw_ktv_idx_get_next(params->cfg,key,i+1);
if (i==-1) if (i==-1)
break; break;
sprintf(basekey,"%s.%d",key,i); sprintf(basekey,"%s.%d",key,i);
printf("Our basekey is %s\n",basekey); printf("Our basekey is %s\n",basekey);
result = cw_ktv_base_exists(params->local_cfg,basekey); result = cw_ktv_base_exists(params->cfg,basekey);
if (result == NULL){ if (result == NULL){
continue; continue;
} }
@ -121,6 +124,8 @@ printf("current is %s\n", current);
return len; return len;
*/
return 0;
} }
int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
@ -128,14 +133,15 @@ int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
{ {
char current[CW_KTV_MAX_KEY_LEN]; char current[CW_CFG_MAX_KEY_LEN];
int stack[10]; int stack[10];
stack[0]=0; stack[0]=0;
current[0]=0; current[0]=0;
stop();
return 0;
// return cw_out_traverse0(handler,params,dst,-1,current,handler->key, stack);
return cw_out_traverse0(handler,params,dst,-1,current,handler->key, stack);
} }

View File

@ -20,7 +20,7 @@ int cw_process_element(struct cw_ElemHandlerParams *params, int proto, int vendo
struct cw_ElemData * elem_data, elem_data_search; struct cw_ElemData * elem_data, elem_data_search;
int rc; int rc;
params->elem=NULL; // params->elem=NULL;
/* try to retrieve a handler for this message element */ /* try to retrieve a handler for this message element */
handler = cw_msgset_get_elemhandler(params->msgset,proto, vendor, elem_id); handler = cw_msgset_get_elemhandler(params->msgset,proto, vendor, elem_id);

View File

@ -21,149 +21,6 @@
* @brief implementation of cw_put_msg. * @brief implementation of cw_put_msg.
*/ */
#include "cw.h"
#include "conn.h"
#include "log.h"
#include "dbg.h"
#include "msgset.h"
#include "mavltypes.h"
/**
* Put a message to a buffer
* This functions assumes, that a message header is
* alread initilaized in buffer
* Message alements are taken fom actiondef in #conn->action
*/
int cw_put_msg(struct conn *conn, uint8_t * rawout)
{
char details[1024];
uint8_t *msgptr,*dst;
int type;
struct cw_MsgData * msg;
struct mlistelem * elem;
int len,l;
cw_dbg(DBG_INFO, "Number of elements in ktv: %d",conn->local_cfg->count);
/* cw_dbg_ktv_dump(conn->local_cfg,DBG_CFG_DMP,"Local CFG","LOCAL:","End Local CFG");*/
/* rawout is already initialized, so we can get
* msg type from buffer */
msgptr = rawout + cw_get_hdr_msg_offset(rawout);
type = cw_get_msg_type(msgptr);
/* look for message data */
msg = cw_msgset_get_msgdata(conn->msgset,type);
if (msg == NULL){
cw_log(LOG_ERR,"Error: Can't create message of type %d (%s) - no definition found.",
type, cw_strmsg(type));
return CAPWAP_RESULT_MSG_UNRECOGNIZED;
}
if (msg->preprocess){
msg->preprocess(conn);
}
cw_dbg(DBG_MSG_ASSEMBLY,"*** Assembling message of type %d (%s) ***",
msg->type, msg->name);
dst = msgptr+8;
len =0;
mlist_foreach(elem,msg->elements_list){
struct cw_ElemData * data;
struct cw_ElemHandler * handler;
struct cw_ElemHandlerParams params;
data = mlistelem_dataptr(elem);
handler = cw_msgset_get_elemhandler(conn->msgset,data->proto,data->vendor,data->id);
printf("Elem: %d %d %d %s\n", data->proto, data->vendor, data->id, handler->name);
if (handler==NULL){
cw_log(LOG_ERR,"Can't put message element %d %d %d, no handler defined.",
data->proto,data->vendor,data->id);
continue;
}
if (handler->put == NULL){
if (data->mand){
cw_log(LOG_ERR,"Error: Can't add mandatory message element %d - %s, no put method defined",
handler->id, handler->name);
}
continue;
}
/* params.conn=conn;*/
params.local_cfg=conn->local_cfg;
params.remote_cfg=conn->remote_cfg;
params.default_cfg=conn->default_cfg;
params.global_cfg=conn->global_cfg;
params.msgset=conn->msgset;
params.elemdata = data;
params.elem=NULL;
params.msgdata=msg;
params.debug_details=details;
*details=0;
if (strcmp(handler->key,"cisco/ap-led-flash-config")==0){
printf("flash config\n");
/* cisco/ap-led-flash-config/flash-enable */
}
l = handler->put(handler,&params,dst+len);
/* if(l>0)
cw_dbg_elem(DBG_ELEM_OUT,conn,type,handler,dst+len,l);
* if (strlen(details)){
cw_dbg(DBG_ELEM_DETAIL," %s",params.debug_details);
}
*/ len += l;
}
cw_set_msg_elems_len(msgptr, len);
cw_dbg(DBG_MSG_ASSEMBLY,"*** Done assenmbling message of type %d (%s) ***",
msg->type, msg->name);
if (type & 1) {
/* It's a request, so we have to set seqnum */
int s = conn_get_next_seqnum(conn);
cw_set_msg_seqnum(msgptr,s);
}
{
printf ("----------------------------------- redecode -----------------------------\n");
uint8_t *elems_ptr;
int offset = cw_get_hdr_msg_offset(rawout);
uint8_t *msg_ptr = rawout + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
mavl_t * cfg = cw_ktv_create();
struct cw_ElemHandlerParams params;
params.remote_cfg=cfg;
params.msgset=conn->msgset;
params.msgdata=msg;
cw_decode_elements( &params, elems_ptr,elems_len);
printf ("----------------------------------- end redecode -----------------------------\n");
}
return CAPWAP_RESULT_SUCCESS;
}
/** /**
* Put a message to a buffer * Put a message to a buffer
@ -173,7 +30,7 @@ printf("Elem: %d %d %d %s\n", data->proto, data->vendor, data->id, handler->name
*/ */
int cw_put_custom_msg(struct conn *conn, uint8_t * rawout, /*mavl_conststr_t elems*/ int t) int cw_put_custom_msg(struct cw_Conn *conn, uint8_t * rawout, /*mavl_conststr_t elems*/ int t)
{ {
/* /*

View File

@ -32,7 +32,8 @@ int cw_read_ac_descriptor(mavl_t store,
struct cw_DescriptorSubelemDef *allowed) struct cw_DescriptorSubelemDef *allowed)
{ {
cw_ktv_read_struct(params->remote_cfg,acstatus,eh->key,data,len); CW_TYPE_STRUCT->read(params->cfg,eh->key,data,len,acstatus);
// cw_ktv_read_struct(params->remote_cfg,acstatus,eh->key,data,len);
if (!allowed) if (!allowed)
allowed=allowed_default; allowed=allowed_default;

View File

@ -41,18 +41,17 @@ int cw_read_descriptor_subelems(mavl_t cfg, const char * parent_key,
sublen = cw_get_word(data + sub + 6); sublen = cw_get_word(data + sub + 6);
subtype = cw_get_word(data + sub + 4); subtype = cw_get_word(data + sub + 4);
/* search sub-element */ /* search sub-element */
for (i = 0; elems[i].maxlen; i++) { for (i = 0; elems[i].maxlen; i++) {
if (elems[i].type == subtype)
if (elems[i].type == subtype /* && elems[i].vendor_id==vendor_id*/)
break; break;
} }
if (!elems[i].maxlen) { if (!elems[i].maxlen) {
cw_dbg_version_subelem(DBG_ELEM_ERR, "Can't handle sub-elem, vendor or type unknown", /* cw_dbg_version_subelem(DBG_ELEM_ERR,
subtype, vendor_id, data+sub+8, sublen); "Can't handle sub-elem, vendor or type unknown",
subtype, vendor_id,
data + sub + 8, sublen);*/
errors++; errors++;
} else { } else {
int l = sublen; int l = sublen;
@ -69,15 +68,24 @@ int cw_read_descriptor_subelems(mavl_t cfg, const char * parent_key,
/* vendor */ /* vendor */
sprintf(key,"%s/%s/%s",parent_key,elems[i].key,CW_SKEY_VENDOR); sprintf(key, "%s/%s/%s", parent_key, elems[i].key,
cw_ktv_add(cfg,key,CW_TYPE_DWORD,NULL,data + sub,4); CW_SKEY_VENDOR);
cw_cfg_set_int(cfg, key, vendor_id);
/* version */ /* version */
sprintf(key,"%s/%s/%s",parent_key,elems[i].key,CW_SKEY_VERSION); sprintf(key, "%s/%s/%s", parent_key, elems[i].key,
cw_ktv_add(cfg,key,CW_TYPE_BSTR16,NULL,data+sub+8,l); CW_SKEY_VERSION);
CW_TYPE_BSTR16->read(cfg,key,data+sub+8,l,NULL);
sprintf(dbgstr, "%s", key); sprintf(dbgstr, "%s", key);
cw_dbg_version_subelem(DBG_SUBELEM, dbgstr, subtype, vendor_id, data+sub+8,l);
/* cw_dbg_version_subelem(DBG_SUBELEM, dbgstr, subtype,
vendor_id, data + sub + 8, l);*/
success++; success++;
} }

View File

@ -2,7 +2,7 @@
#include "log.h" #include "log.h"
int cw_read_from(struct conn *conn, struct sockaddr_storage *from) int cw_read_from(struct cw_Conn *conn, struct sockaddr_storage *from)
{ {
int n; int n;
uint8_t buf[2024]; uint8_t buf[2024];

View File

@ -1,30 +0,0 @@
#include "capwap.h"
#include "val.h"
#include "msgset.h"
#include "log.h"
#include "cw.h"
int cw_in_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
char key[CW_KTV_MAX_KEY_LEN];
cw_Val_t * result;
int radio;
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT;
}
radio=cw_get_byte(elem_data);
sprintf(key,"radio.%d/%s",radio,handler->key);
result = cw_ktv_add(params->remote_cfg, key,
handler->type, NULL, elem_data+1,elem_len-1);
params->elem=result;
return CAPWAP_RESULT_SUCCESS;
}

View File

@ -16,7 +16,7 @@ static struct cw_DescriptorSubelemDef allowed_default[] = {
}; };
int cw_read_wtp_descriptor(mavl_t cfg, struct conn *conn, int cw_read_wtp_descriptor(mavl_t cfg, struct cw_Conn *conn,
struct cw_ElemHandler *eh, uint8_t * data, int len, struct cw_ElemHandler *eh, uint8_t * data, int len,
struct cw_DescriptorSubelemDef *allowed) struct cw_DescriptorSubelemDef *allowed)
{ {
@ -38,7 +38,7 @@ int cw_read_wtp_descriptor(mavl_t cfg, struct conn *conn,
"Non standard conform WTP Descriptor, number of encryptoin elements is 0."); "Non standard conform WTP Descriptor, number of encryptoin elements is 0.");
} }
sprintf(key,"%s/%s",eh->key, CW_SKEY_MAX_RADIOS); sprintf(key,"%s/%s",eh->key, "max-radios");
cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data,1); cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data,1);
sprintf(key,"%s/%s",eh->key, CW_SKEY_RADIOS_IN_USE); sprintf(key,"%s/%s",eh->key, CW_SKEY_RADIOS_IN_USE);

View File

@ -20,7 +20,7 @@ static struct cw_DescriptorSubelemDef allowed_default[] = {
/** /**
* Read WTP Descriptor in Cisco-Style (Draft 7) * Read WTP Descriptor in Cisco-Style (Draft 7)
*/ */
int cw_read_wtp_descriptor_7(mavl_t cfg, struct conn *conn, int cw_read_wtp_descriptor_7(mavl_t cfg, struct cw_Conn *conn,
struct cw_ElemHandler *eh, uint8_t * data, int len, struct cw_ElemHandler *eh, uint8_t * data, int len,
struct cw_DescriptorSubelemDef *allowed) struct cw_DescriptorSubelemDef *allowed)
{ {
@ -29,12 +29,11 @@ int cw_read_wtp_descriptor_7(mavl_t cfg, struct conn *conn,
int pos; int pos;
char key[64]; char key[64];
sprintf(key,"%s/%s",eh->key, CW_SKEY_MAX_RADIOS); sprintf(key,"%s/%s",eh->key, "max-radios");
cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data,1); cw_cfg_set_int(cfg,key,cw_get_byte(data));
sprintf(key,"%s/%s",eh->key, CW_SKEY_RADIOS_IN_USE); sprintf(key,"%s/%s",eh->key, CW_SKEY_RADIOS_IN_USE);
cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data+1,1); cw_cfg_set_int(cfg,key,cw_get_byte(data+1));
pos = 2; pos = 2;

View File

@ -1,10 +1,13 @@
#include "cw.h" #include "cw.h"
#include "cfg.h"
#include "dbg.h"
static int get_psk(struct conn * conn,const char * username, uint8_t **psk, unsigned int *len) static int get_psk(struct cw_Conn *conn, const char *username, uint8_t ** psk,
unsigned int *len)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
cw_Val_t *result; cw_Val_t *result;
sprintf(key, "%s/%s", "psk", username); sprintf(key, "%s/%s", "psk", username);
result = cw_ktv_get(conn->local_cfg, key, CW_TYPE_BSTR16); result = cw_ktv_get(conn->local_cfg, key, CW_TYPE_BSTR16);
@ -33,23 +36,23 @@ static int get_psk(struct conn * conn,const char * username, uint8_t **psk, unsi
* @param default_cipher * @param default_cipher
* @return * @return
*/ */
int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * default_cipher) int cw_setup_dtls(struct cw_Conn *conn, cw_Cfg_t * cfg, const char *prefix,
char *default_cipher)
{ {
char key[CW_KTV_MAX_KEY_LEN]; char key[CW_CFG_MAX_KEY_LEN];
char *ssl_cert,*ssl_key; const char *ssl_cert, *ssl_key;
uint8_t security; uint8_t security;
security = 0; security = 0;
sprintf(key, "%s/%s", prefix, "ssl-cipher"); sprintf(key, "%s/%s", prefix, "ssl-cipher");
conn->dtls_cipher = cw_ktv_get_str(cfg,key, default_cipher); conn->dtls_cipher = cw_cfg_get(cfg, key, default_cipher);
sprintf(key, "%s/%s", prefix, "ssl-psk"); sprintf(key, "%s/%s", prefix, "ssl-psk");
conn->dtls_psk = cw_ktv_get_bstr16(cfg,key,NULL); conn->dtls_psk = cw_cfg_get(cfg, key, NULL);
sprintf(key, "%s/%s", prefix, "ssl-psk-enable"); sprintf(key, "%s/%s", prefix, "ssl-psk-enable");
conn->dtls_psk_enable = cw_ktv_get_bool(cfg,key,0); conn->dtls_psk_enable = cw_cfg_get_bool(cfg, key, "flase");
if (conn->dtls_psk_enable) { if (conn->dtls_psk_enable) {
security |= CAPWAP_FLAG_AC_SECURITY_S; security |= CAPWAP_FLAG_AC_SECURITY_S;
@ -58,22 +61,21 @@ int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * de
sprintf(key, "%s/%s", prefix, "ssl-certfile"); sprintf(key, "%s/%s", prefix, "ssl-certfile");
ssl_cert = cw_ktv_get_str(conn->local_cfg,key,NULL); ssl_cert = cw_cfg_get(cfg, key, NULL);
sprintf(key, "%s/%s", prefix, "ssl-keyfile"); sprintf(key, "%s/%s", prefix, "ssl-keyfile");
ssl_key = cw_ktv_get_str(conn->local_cfg,key,NULL); ssl_key = cw_cfg_get(cfg, key, NULL);
if (ssl_cert != NULL && ssl_key != NULL) { if (ssl_cert != NULL && ssl_key != NULL) {
conn->dtls_cert_file = ssl_cert; conn->dtls_cert_file = ssl_cert;
conn->dtls_key_file = ssl_key; conn->dtls_key_file = ssl_key;
sprintf(key, "%s/%s", prefix, "ssl-keypass"); sprintf(key, "%s/%s", prefix, "ssl-keypass");
conn->dtls_key_pass = cw_ktv_get_str(cfg,key,NULL); conn->dtls_key_pass = cw_cfg_get(cfg, key, NULL);
security |= CAPWAP_FLAG_AC_SECURITY_X; security |= CAPWAP_FLAG_AC_SECURITY_X;
} }
sprintf(key, "%s/%s", prefix, "ssl-dhbits"); sprintf(key, "%s/%s", prefix, "ssl-dhbits");
conn->dtls_dhbits = cw_ktv_get_word(cfg,key,1024); conn->dtls_dhbits = cw_cfg_get_word(cfg, key, 1024);
conn->dtls_get_psk = get_psk; conn->dtls_get_psk = get_psk;
return security; return security;
} }

View File

@ -84,6 +84,30 @@ static const char * get_type_name(cw_Val_t *data)
return CW_TYPE_BOOL->name; return CW_TYPE_BOOL->name;
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
cw_Val_t val;
int l;
char str[2048];
memset(&val,0,sizeof(cw_Val_t));
val.valguard = param;
get(&val,src,len);
to_str(&val,str,2048);
cw_cfg_set(cfg,key,str);
l = val.type->len(&val);
if (val.type->del)
val.type->del(&val);
return l;
}
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_BOOL,key,dst,param);
}
const struct cw_Type cw_type_bool = { const struct cw_Type cw_type_bool = {
"Bool", /* name */ "Bool", /* name */
NULL, /* del */ NULL, /* del */
@ -93,5 +117,8 @@ const struct cw_Type cw_type_bool = {
from_str, /* from_str */ from_str, /* from_str */
len, /* len */ len, /* len */
data, /* data */ data, /* data */
get_type_name /* get_type_name */ get_type_name, /* get_type_name */
NULL,
bread,
bwrite
}; };

View File

@ -104,6 +104,75 @@ static int cast(cw_Val_t * data)
return 0; return 0;
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
char *d, *dst;
dst = malloc(len*2+3);
if (dst==NULL)
return 0;
d=dst;
if ( format_is_utf8 ( src, len) ) {
d += sprintf ( d, "%.*s", len, src );
} else {
d += sprintf ( d, ".x" );
d += format_hex ( d, src,len);
}
cw_cfg_set(cfg,key,dst);
free(dst);
return d - dst;
}
static int xput(uint8_t * dst,const char *s)
{
int msize;
int l;
l = strlen(s);
if (s[0]!='.'){
memcpy(dst,(uint8_t*)s,l);
return l;
}
if (l<=2){
memcpy(dst,(uint8_t*)s,l);
return l;
}
if (s[1]=='.'){
memcpy(dst,(uint8_t*)s+1,l-1);
return l-1;
}
if (s[1]!='x'){
memcpy(dst,(uint8_t*)s,l);
return l;
}
/* the string starts with ".x" - read hexbytes */
l-=2;
msize=l/2;
if(l&1)
msize++;
cw_format_scan_hex_bytes(dst,s+2,l);
return msize;
}
static int bwrite(cw_Cfg_t **cfg, const char *key, uint8_t *dst, const void * param)
{
const char *s;
s = cw_cfg_get_l(cfg,key,NULL);
if (s==NULL)
return -1;
return xput(dst,s);
}
const struct cw_Type cw_type_bstr16 = { const struct cw_Type cw_type_bstr16 = {
"Bstr16", /* name */ "Bstr16", /* name */
@ -115,7 +184,10 @@ const struct cw_Type cw_type_bstr16 = {
len, /* len */ len, /* len */
data, /* data */ data, /* data */
get_type_name, /* get_type_name */ get_type_name, /* get_type_name */
cast /* cast */ cast, /* cast */
bread,
bwrite
}; };

View File

@ -35,6 +35,9 @@ static int put(const cw_Val_t *data, uint8_t * dst)
static const char * get_guardstr(int val, const cw_ValValRange_t * valrange) static const char * get_guardstr(int val, const cw_ValValRange_t * valrange)
{ {
if (valrange==NULL)
return NULL;
while(valrange->name!=NULL){ while(valrange->name!=NULL){
if(val>=valrange->min && val<=valrange->max) if(val>=valrange->min && val<=valrange->max)
return valrange->name; return valrange->name;
@ -121,6 +124,26 @@ static int cast(cw_Val_t * data)
return 0; return 0;
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
uint8_t val;
cw_ValValRange_t * valrange = (cw_ValValRange_t *) param;
const char *str;
val = cw_get_byte(src);
str = get_guardstr(val, valrange);
if (str != NULL)
cw_cfg_set(cfg,key,str);
else
cw_cfg_set_int(cfg,key,val);
return 1;
}
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_BYTE,key,dst,param);
}
const struct cw_Type cw_type_byte = { const struct cw_Type cw_type_byte = {
"Byte", /* name */ "Byte", /* name */
@ -132,5 +155,8 @@ const struct cw_Type cw_type_byte = {
len, /* len */ len, /* len */
data, /* data */ data, /* data */
get_type_name, /* get_type_name */ get_type_name, /* get_type_name */
cast cast,
bread,
bwrite
}; };

View File

@ -66,6 +66,45 @@ static int cast(cw_Val_t * data)
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
uint32_t val;
//cw_ValValRange_t * valrange = (cw_ValValRange_t *) param;
//const char *str;
val = cw_get_dword(src);
/* str = get_guardstr(val, valrange);
if (str != NULL)
cw_cfg_set(cfg,key,str);
else*/
cw_cfg_set_int(cfg,key,val);
return 4;
}
static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_DWORD,key,dst,param);
/* cw_Val_t val;
int l;
const char *s;
memset(&val,0,sizeof(cw_Val_t));
val.valguard=param;
s = cw_cfg_get(cfg,key,NULL);
if (s==NULL)
return -1;
from_str(&val,s);
l = put(&val,dst);
if(val.type->del)
val.type->del(&val);
return l;*/
}
const struct cw_Type cw_type_dword = { const struct cw_Type cw_type_dword = {
"Dword", /* name */ "Dword", /* name */
NULL, /* del */ NULL, /* del */
@ -76,6 +115,8 @@ const struct cw_Type cw_type_dword = {
NULL, /* len */ NULL, /* len */
NULL, /* data */ NULL, /* data */
get_type_name, /* get_type_name */ get_type_name, /* get_type_name */
cast cast,
bread,
bwrite
}; };

View File

@ -111,6 +111,29 @@ static const char * get_type_name(cw_Val_t *data)
return CW_TYPE_IPADDRESS->name; return CW_TYPE_IPADDRESS->name;
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
char str[128];
int rc;
cw_Val_t val;
memset(&val,0,sizeof(cw_Val_t));
get(&val,src,len);
to_str(&val,str,128);
cw_cfg_set(cfg,key,str);
rc = val.type->len(&val);
del(&val);
return rc;
}
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_IPADDRESS,key,dst,param);
}
const struct cw_Type cw_type_ipaddress = { const struct cw_Type cw_type_ipaddress = {
"IPAddress", /* name */ "IPAddress", /* name */
del, /* del */ del, /* del */
@ -120,7 +143,11 @@ const struct cw_Type cw_type_ipaddress = {
from_str, /* from_str */ from_str, /* from_str */
len, /* len */ len, /* len */
data, /* data */ data, /* data */
get_type_name get_type_name,
NULL,
bread,
bwrite,
}; };

View File

@ -90,6 +90,21 @@ static const char * get_type_name(cw_Val_t *data)
return CW_TYPE_STR->name; return CW_TYPE_STR->name;
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
cw_Val_t val;
int l;
char str[2048];
memset(&val,0,sizeof(cw_Val_t));
val.valguard = param;
get(&val,src,len);
to_str(&val,str,2048);
cw_cfg_set(cfg,key,str);
l = val.type->len(&val);
del(&val);
return l;
}
const struct cw_Type cw_type_str = { const struct cw_Type cw_type_str = {
@ -101,5 +116,9 @@ const struct cw_Type cw_type_str = {
from_str, /* from_str */ from_str, /* from_str */
len, /* len */ len, /* len */
NULL, /* data */ NULL, /* data */
get_type_name /* get_type_name */ get_type_name, /* get_type_name */
NULL,
bread,
}; };

201
src/cw/cw_type_struct.c Normal file
View File

@ -0,0 +1,201 @@
#include "cw.h"
#include "val.h"
#include "dbg.h"
#include "log.h"
static int read_struct(cw_Cfg_t * cfg,const cw_ValStruct_t * stru, const char *pkey,
const uint8_t * data, int len)
{
char key[CW_CFG_MAX_KEY_LEN];
int pos, i,l;
pos=0; i=0;
while (stru[i].type != NULL){
if(stru[i].position!=-1)
pos=stru[i].position;
if (stru[i].key!=NULL)
sprintf(key,"%s/%s",pkey,stru[i].key);
else
sprintf(key,"%s",pkey);
switch (stru[i].len){
case CW_STRUCT_LEN_BYTE:
/* read len from next byte */
l = cw_get_byte(data+pos);
pos ++;
break;
case CW_STRUCT_LEN_WORD:
/* read len from next word */
l = cw_get_word(data+pos);
pos ++;
break;
case -1:
l = len-pos;
break;
default:
l = stru[i].len;
if (pos+l > len){
l = len-pos;
}
}
l=stru[i].type->read(cfg,key,data+pos,l,stru[i].valguard);
// printf("READ STRUCT (%d): %s: %s\n",pos,key,dbstr);
if (stru[i].len==-1){
///l = result->type->len(result);
}
else {
l = stru[i].len;
}
if(stru[i].position == -1)
pos+=l;
i++;
}
return pos;
}
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
cw_ValStruct_t * stru = (cw_ValStruct_t *) param;
read_struct(cfg,stru,key,src,len);
return 1;
}
static int write_struct(cw_Cfg_t ** cfgs, const cw_ValStruct_t * stru, const char *pkey,
uint8_t * dst)
{
char key[CW_CFG_MAX_KEY_LEN];
int pos, i;
const char * result;
int wrlen;
cw_Val_t val;
memset(&val,0,sizeof(cw_Val_t));
pos=0; i=0;
for(i=0; stru[i].type != NULL;i++){
if (stru[i].position!=-1){
pos=stru[i].position;
}
if (stru[i].len!=-1)
memset(dst+pos,0,stru[i].len);
if (stru[i].key!=NULL)
sprintf(key,"%s/%s",pkey,stru[i].key);
else
sprintf(key,"%s",pkey);
result = cw_cfg_get_l(cfgs,key,NULL);
if(result) {
// char s[2048];
// result->type->to_str(result,s,2048);
// printf("Content: '%s'\n",s);
}
if (result == NULL){
cw_log(LOG_ERR,"Can't put %s, no value found, filling wth zeros.",key);
memset(dst+pos,0,stru[i].len);
}
else{
struct cw_Type * type;
type = (struct cw_Type *)stru[i].type;
wrlen = type->write(cfgs,stru[i].key,dst+pos,stru[i].valguard);
/* result->valguard=stru[i].valguard;
if (cw_ktv_cast(result,stru[i].type)==NULL){
cw_log(LOG_ERR,"Can't cast key '%s' from %s to %s",key,result->type->name,stru[i].type->name);
}
result->type->put(result,dst+pos);*/
}
if (stru[i].len!=-1)
pos+=stru[i].len;
else
pos+=wrlen; //result->type->len(result);
}
return pos;
}
static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void * param)
{
return write_struct(cfgs,param,key,dst);
cw_dbg(DBG_X,"Key: %s",key);
stop();
/*
int start;
int len;
cw_Val_t search;
const char *result;
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return 0;
}
search.key = (char*)handler->key;
result = mavl_get_first(params->cfg,&search);
if (result == NULL ){
if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
return 0;
}
if (strncmp(result->key,handler->key, strlen(handler->key))!=0){
if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
return 0;
}
start = params->msgset->header_len(handler);
len = cw_ktv_write_struct(params->cfg,
params->cfg,
handler->type,handler->key,dst+start);
return params->msgset->write_header(handler,dst,len);
*/
}
const struct cw_Type cw_type_struct = {
"Struct", /* name */
NULL, /* del */
NULL, /* put */
NULL, /* get */
NULL, /* to_str */
NULL, /* from_str */
NULL, /* len */
NULL, /* data */
NULL, /* get_type_name */
NULL,
bread,
bwrite
};

View File

@ -63,6 +63,41 @@ static int cast(cw_Val_t * data)
return 0; return 0;
} }
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
uint16_t val;
//cw_ValValRange_t * valrange = (cw_ValValRange_t *) param;
//const char *str;
val = cw_get_word(src);
/* str = get_guardstr(val, valrange);
if (str != NULL)
cw_cfg_set(cfg,key,str);
else*/
cw_cfg_set_int(cfg,key,val);
return 2;
}
static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_WORD,key,dst,param);
/* cw_Val_t val;
int l;
const char *s;
memset(&val,0,sizeof(cw_Val_t));
val.valguard=param;
s = cw_cfg_get_l(cfg,key,NULL);
if (s==NULL)
return -1;
from_str(&val,s);
l = put(&val,dst);
if(val.type->del)
val.type->del(&val);
return l;*/
}
const struct cw_Type cw_type_word = { const struct cw_Type cw_type_word = {
"Word", /* name */ "Word", /* name */
@ -74,7 +109,9 @@ const struct cw_Type cw_type_word = {
NULL, NULL,
NULL, NULL,
get_type_name, get_type_name,
cast cast,
bread,
bwrite,
}; };

View File

@ -3,30 +3,34 @@
#include "log.h" #include "log.h"
#include "cw.h" #include "cw.h"
#include "dbg.h" #include "dbg.h"
#include "cfg.h"
int cw_write_descriptor_subelem (uint8_t *dst, mavl_t ktvstore, int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t * cfg,
int subelem_id, const char * parent_key ) int subelem_id, const char * parent_key )
{ {
char key[256]; char key[256];
cw_Val_t * vendor, *version ; uint32_t vendor;
uint8_t *d; bstr16_t version;
const char *vendor_s;
uint8_t *d;
/* d += cw_put_dword(d, bstrv_get_vendor_id(v)); /* d += cw_put_dword(d, bstrv_get_vendor_id(v));
d += cw_put_dword(d, (subelem_id << 16) | bstrv_len(v)); d += cw_put_dword(d, (subelem_id << 16) | bstrv_len(v));
d += cw_put_data(d, bstrv_data(v), bstrv_len(v)); d += cw_put_data(d, bstrv_data(v), bstrv_len(v));
*/ */
sprintf (key, "%s/%s", parent_key, CW_SKEY_VENDOR); sprintf (key, "%s/%s", parent_key, CW_SKEY_VENDOR);
vendor = cw_ktv_get (ktvstore, key, CW_TYPE_DWORD); vendor_s = cw_cfg_get (cfg, key, NULL);
if (vendor == NULL) { if (vendor_s == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value of type Dword found.", key); cw_log (LOG_ERR, "Can't put subelem %s, no value of type Dword found.", key);
return 0; return 0;
} }
vendor = atoi(vendor_s);
sprintf (key, "%s/%s", parent_key, CW_SKEY_VERSION); sprintf (key, "%s/%s", parent_key, CW_SKEY_VERSION);
version = cw_ktv_get (ktvstore, key, CW_TYPE_BSTR16); version = cw_cfg_get_bstr16 (cfg, key, NULL);
if (version == NULL) { if (version == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value of type Bstr16 found.", key); cw_log (LOG_ERR, "Can't put subelem %s, no value of type Bstr16 found.", key);
@ -36,12 +40,14 @@ int cw_write_descriptor_subelem (uint8_t *dst, mavl_t ktvstore,
d = dst; d = dst;
/* put vendor */ /* put vendor */
d += vendor->type->put (vendor, d); d += cw_put_dword(d, vendor); //->type->put (vendor, d);
/* put version */ /* put version */
d += cw_put_dword (d, (subelem_id << 16) | version->type->len(version)); d += cw_put_dword (d, (subelem_id << 16) | bstr16_len(version));
d += version->type->put(version,d); d += cw_put_bstr16(d, version);
free(version);
return d-dst; return d-dst;
} }

View File

@ -1,10 +1,14 @@
#include "cw.h" #include "cw.h"
#include "dbg.h"
int cw_write_radio_element(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int idx int cw_write_radio_element(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int idx
, uint8_t * dst) , uint8_t * dst)
{ {
char key[CW_KTV_MAX_KEY_LEN]; stop();
return 0;
char key[CW_CFG_MAX_KEY_LEN];
cw_Val_t *elem, search; cw_Val_t *elem, search;
int len; int len;
uint8_t * d; uint8_t * d;
@ -15,7 +19,7 @@ int cw_write_radio_element(struct cw_ElemHandler * handler, struct cw_ElemHandle
printf("Looking for readio key: %s\n",key); printf("Looking for readio key: %s\n",key);
search.key=key; search.key=key;
elem = mavl_get(params->local_cfg, &search); elem = mavl_get(params->cfg, &search);
if (elem==NULL){ if (elem==NULL){
printf("Nothing found\n"); printf("Nothing found\n");

View File

@ -1,44 +0,0 @@
#ifndef __CWMSG_H
#define __CWMSG_H
#include <stdint.h>
#include "radioinfo.h"
struct cwmsg{
uint8_t * buffer;
uint8_t * trnsprthdr;
uint8_t * ctrlhdr;
uint8_t * msgelems;
int pos;
int flags;
int hlen;
int rid;
int seqnum;
int type;
int capwap_mode;
};
struct conn;
/*
extern void cwmsg_init(struct cwmsg * cwmsg, uint8_t *buffer, int type, int seqnum, struct radioinfo * radioinfo);
//int cwmsg_send(struct cwmsg * cwmsg, int seqnum, int rid, struct conn * conn);
//
extern void cwmsg_addelem(struct cwmsg *msg,int type, const uint8_t *elem, int len);
extern void cwmsg_vaddelem(struct cwmsg *msg,int type, ...);
//extern void cwmsg_addelem_ac_descriptor(struct cwmsg *msg,struct ac_info * acinfo,struct wtpinfo * wtpinfo);
extern void cwmsg_addelem_ac_timestamp(struct cwmsg *msg);
extern void cwmsg_init_echo_request(struct cwmsg * cwmsg,uint8_t *buffer,struct conn * conn, struct radioinfo * radioinfo);
extern void cwmsg_addelem_mtu_discovery_padding(struct cwmsg * msg, struct conn* conn);
extern void cwmsg_addelem_image_identifier(struct cwmsg *msg,uint32_t vendor_id,uint8_t *img, int len);
//extern void cwmsg_addelem_radio_operational_state(struct cwmsg * cwmsg, struct radioinfo * ri);
extern void cwmsg_addelem_vendor_cisco_mwar_addr(struct cwmsg *msg, struct conn *conn);
*/
#endif

View File

@ -55,7 +55,7 @@ uint32_t cw_dbg_opt_level = 0;
static struct cw_StrListElem color_on[] = { static struct cw_StrListElem theme0[] = {
{DBG_PKT_IN, ANSI_YELLOW}, {DBG_PKT_IN, ANSI_YELLOW},
{DBG_PKT_OUT, ANSI_YELLOW ANSI_ITALIC}, {DBG_PKT_OUT, ANSI_YELLOW ANSI_ITALIC},
@ -86,7 +86,7 @@ static struct cw_StrListElem color_on[] = {
{DBG_INFO, ANSI_DEFAULT}, {DBG_INFO, ANSI_DEFAULT},
{DBG_STATE, ANSI_BBLACK ANSI_BOLD }, {DBG_STATE, ANSI_GREEN ANSI_BOLD},
{DBG_RFC, ANSI_BRED}, {DBG_RFC, ANSI_BRED},
{DBG_X, "\x1b[31m"}, {DBG_X, "\x1b[31m"},
@ -98,6 +98,9 @@ static struct cw_StrListElem color_on[] = {
{CW_STR_STOP, ""} {CW_STR_STOP, ""}
}; };
static struct cw_StrListElem * color_on = theme0;
struct cw_StrListElem color_ontext[] = { struct cw_StrListElem color_ontext[] = {
/* {DBG_ELEM_DMP, "\x1b[37m"},*/ /* {DBG_ELEM_DMP, "\x1b[37m"},*/
@ -132,7 +135,10 @@ static struct cw_StrListElem prefix[] = {
{DBG_DTLS_DETAIL, " DTLS - "}, {DBG_DTLS_DETAIL, " DTLS - "},
{DBG_WARN, " Warning - "}, {DBG_WARN, " Warning - "},
{DBG_MOD, " Mod - "}, {DBG_MOD, " Mod - "},
{DBG_STATE, " State - "}, {DBG_STATE, " STATEMACHINE - "},
{DBG_CFG_SET, " Cfg Set - "},
{DBG_X, "XXXXX - "}, {DBG_X, "XXXXX - "},
@ -208,7 +214,7 @@ static void cw_dbg_vlog_line(struct cw_LogWriter * writer,
/** /**
* Put a list of missing mandatory message elements to debug output * Put a list of missing mandatory message elements to debug output
*/ */
void cw_dbg_missing_mand(int level, struct conn *conn, int ** ml, int n, void cw_dbg_missing_mand(int level, struct cw_Conn *conn, int ** ml, int n,
int * a) int * a)
{ {
/* /*
@ -243,7 +249,7 @@ void cw_dbg_missing_mand(int level, struct conn *conn, int ** ml, int n,
/** /**
* Display a packet on for debugger * Display a packet on for debugger
*/ */
void cw_dbg_pkt(int level, struct conn *conn, uint8_t * packet, int len, void cw_dbg_pkt(int level, struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from) struct sockaddr *from)
{ {
@ -305,7 +311,7 @@ void cw_dbg_dmp(int level, const uint8_t * data, int len, const char *format, ..
} }
void cw_dbg_msg(int level, struct conn *conn, uint8_t * packet, int len, void cw_dbg_msg(int level, struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from) struct sockaddr *from)
{ {
@ -360,96 +366,6 @@ void cw_dbg_msg(int level, struct conn *conn, uint8_t * packet, int len,
} }
/*
static int cw_format_vendor(char *dst, uint32_t vendor_id, int elem_id,
const uint8_t * elem_data)
{
uint32_t lw_elem_id;
switch (vendor_id) {
case CW_VENDOR_ID_CISCO:
{
if (elem_id != CW_CISCO_SPAM_VENDOR_SPECIFIC) {
return sprintf(dst, "%d - %s", elem_id,
cw_cisco_id_to_str(elem_id));
}
// dive into LWAPP vendor specific decoding
lw_elem_id = lw_get_word(elem_data + 4 + 6);
return sprintf(dst, "%d/LWAPP Vendor: %d - %s",
elem_id,
lw_elem_id, lw_cisco_id_to_str(lw_elem_id));
break;
}
default:
{
return sprintf(dst, "%d", elem_id);
}
}
return 0;
}
*/
void cw_dbg_version_subelem(int level, const char *context, int subtype,
uint32_t vendor_id, const uint8_t * vstr, int len)
{
char v[2048];
int n;
if (!cw_dbg_is_level(level))
return;
if (!vstr)
return;
n = cw_format_version(v, vstr, len);
sprintf(v + n, ", Vendor Id: %d, %s", vendor_id, cw_strvendor(vendor_id));
cw_dbg(level, "%s: SubType %d, %s", context, subtype, v);
}
/*
void cw_dbgv(struct cw_LogWriter *writer, int level, const char * format, va_list args)
{
char fbuf[1024];
if (writer->colored ){
sprintf(fbuf, "DBG:%s%s %s%s%s",
get_dbg_color_on(level),
get_dbg_prefix(level),
get_dbg_color_ontext(level), format, get_dbg_color_off(level)
);
}
else{
sprintf(fbuf, "DBG:%s %s",
get_dbg_prefix(level), format);
}
writer->write(LOG_DEBUG,fbuf,args,&cw_log_console_writer);
}
*/
/*
void cw_dbgv1(struct cw_LogWriter *writer, int level, const char * format, ...){
va_list args;
va_start(args, format);
cw_dbgv(writer,level,format,args);
va_end(args);
}
*/
void cw_dbg(int level, const char *format, ...){ void cw_dbg(int level, const char *format, ...){
int i; int i;
@ -470,7 +386,7 @@ void cw_dbg(int level, const char *format, ...){
void cw_dbg_elem(int level, struct conn *conn, int msg, void cw_dbg_elem(int level, struct cw_Conn *conn, int msg,
struct cw_ElemHandler * handler, const uint8_t * msgbuf, int len) struct cw_ElemHandler * handler, const uint8_t * msgbuf, int len)
{ {
char vendorname[256]; char vendorname[256];

View File

@ -115,10 +115,12 @@ enum cw_dbg_levels{
DBG_CFG_DMP, DBG_CFG_DMP,
DBG_CFG_SET,
/** Debug Mods */ /** Debug Mods */
DBG_MOD, DBG_MOD,
DBG_STATE, /**<Debug State machein */ DBG_STATE, /**<Debug State machine */
DBG_ALL, DBG_ALL,
@ -147,14 +149,14 @@ void cw_dbg_set_level (int level, int on);
int cw_dbg_set_level_from_str(const char *level); int cw_dbg_set_level_from_str(const char *level);
/* /*
void cw_dbg_elem_(struct conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len); void cw_dbg_elem_(struct cw_Conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len);
*/ */
/* /*
void cw_dbg_missing_mand(int level,struct conn *conn,cw_action_in_t ** ml,int n,cw_action_in_t *a); void cw_dbg_missing_mand(int level,struct cw_Conn *conn,cw_action_in_t ** ml,int n,cw_action_in_t *a);
*/ */
void cw_dbg_packet(struct conn *conn, uint8_t * packet, int len); void cw_dbg_packet(struct cw_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_pkt(int level,struct cw_Conn *conn, uint8_t * packet, int len,struct sockaddr *from);
void cw_dbg(int level, const char *format, ...); void cw_dbg(int level, const char *format, ...);
void cw_dbg_dmp(int level, const uint8_t * data, int len, const char *format, ...); void cw_dbg_dmp(int level, const uint8_t * data, int len, const char *format, ...);
@ -199,16 +201,16 @@ void cw_dbg_dmp_(int level, const uint8_t * data, int len, const char *format, .
void cw_dbg_elem(int level, struct conn *conn, int msg, void cw_dbg_elem(int level, struct cw_Conn *conn, int msg,
struct cw_ElemHandler * handler, const uint8_t * msgbuf, int len); struct cw_ElemHandler * handler, const uint8_t * msgbuf, int len);
void cw_dbg_pkt_nc(int level,struct netconn *nc, uint8_t * packet, int len,struct sockaddr *from); void cw_dbg_pkt_nc(int level,struct netconn *nc, 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); void cw_dbg_msg(int level,struct cw_Conn *conn, uint8_t * packet, int len,struct sockaddr *from);
char * cw_dbg_mkdmp(const uint8_t * data, int len); char * cw_dbg_mkdmp(const uint8_t * data, int len);
void cw_dbg_version_subelem(int level, const char *context, int subtype, //void cw_dbg_version_subelem(int level, const char *context, int subtype,
uint32_t vendor_id, const uint8_t * vstr, int len); // uint32_t vendor_id, const uint8_t * vstr, int len);
void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel, void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel,
const char *header, const char *prefix, const char *footer ); const char *header, const char *prefix, const char *footer );
@ -232,6 +234,9 @@ void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel,
*/ */
int cw_dbg_is_level(int level); int cw_dbg_is_level(int level);
#define stop() printf("STOP IN %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__); exit(1)
/** /**
*@} LOGDBG *@} LOGDBG
*/ */

View File

@ -63,6 +63,9 @@ struct cw_StrListElem cw_dbg_strings[] = {
{ DBG_DTLS_BIO_DMP, "dtls_bio_dmp"}, { DBG_DTLS_BIO_DMP, "dtls_bio_dmp"},
{ DBG_DTLS_DETAIL, "dtls_detail"}, { DBG_DTLS_DETAIL, "dtls_detail"},
{ DBG_CFG_SET, "cfg_set" },
{DBG_CFG_DMP, "cfg_dmp" }, {DBG_CFG_DMP, "cfg_dmp" },
{ DBG_WARN, "warn" }, { DBG_WARN, "warn" },

120
src/cw/discovery.c Normal file
View File

@ -0,0 +1,120 @@
#include "discovery.h"
#include "dbg.h"
static int cmp(const void *v1, const void *v2)
{
int rc;
struct cw_DiscoveryResults_elem *e1,*e2;
e1=(struct cw_DiscoveryResults_elem *)v1;
e2=(struct cw_DiscoveryResults_elem *)v2;
rc = e1->prio - e2->prio;
if (rc != 0)
return rc;
rc = e1->wtps - e2->wtps;
if (rc != 0)
return rc;
return e1->ctr-e2->ctr;
}
static void del(void *r)
{
struct cw_DiscoveryResults_elem *e = (struct cw_DiscoveryResults_elem *)r;
cw_cfg_destroy(e->cfg);
}
struct cw_DiscoveryResults *cw_discovery_results_create()
{
struct cw_DiscoveryResults *dis;
dis = malloc(sizeof(struct cw_DiscoveryResults));
if (dis == NULL)
return NULL;
dis->nr = 0;
dis->list =
mavl_create(cmp, del, sizeof(struct cw_DiscoveryResults_elem));
if (dis->list == NULL) {
cw_discovery_results_destroy(dis);
return NULL;
}
return dis;
}
void cw_discovery_results_destroy(struct cw_DiscoveryResults *r)
{
if (r->list)
mavl_destroy(r->list);
free(r);
}
void cw_discovery_results_add(struct cw_DiscoveryResults *dis,
cw_Cfg_t * ac_cfg, cw_Cfg_t * wtp_cfg)
{
const char *acname;
char key[CW_CFG_MAX_KEY_LEN];
struct cw_DiscoveryResults_elem e;
int i;
/* get ac name */
acname = cw_cfg_get(ac_cfg, "capwap/ac-name", NULL);
if (acname == NULL) {
/* this should not happen, because AC Name is a
* amndatory message element */
e.prio = 255;
} else {
/* Get priority for AC from
* ac-name-with-priority list */
sprintf(key, "ac-name-with-priority/%s", acname);
e.prio = cw_cfg_get_byte(wtp_cfg, key, 255);
}
/* for each control ip address the AC has sent */
i = 0;
do {
const char *ipval;
sprintf(key, "capwap-control-ip-address.%d/wtps", i);
e.wtps = cw_cfg_get_word(ac_cfg, key, 65535);
// cw_dbg(DBG_X, "WTPS %d, K: %s", e.wtps);
if (e.wtps == 65535)
break;
sprintf(key, "capwap-control-ip-address.%d/address", i);
ipval = cw_cfg_get(ac_cfg, key, "");
sprintf(key, "%04d%05d%04d", e.prio, e.wtps, dis->nr);
e.ctr=dis->list->count;
i++;
e.cfg = cw_cfg_create();
if (e.cfg == NULL)
continue;
cw_cfg_copy(ac_cfg,e.cfg);
strcpy(e.ip,ipval);
mavl_insert(dis->list,&e,NULL);
/* cw_ktv_add(dis->prio_ip, key, CW_TYPE_SYSPTR, NULL, (uint8_t *) (&ipval),
sizeof(ipval));
cw_ktv_add(dis->prio_ac, key, CW_TYPE_SYSPTR, NULL, (uint8_t *)(&remote_cfg),
sizeof(remote_cfg)); */
// cw_dbg(DBG_X, "KEY: %s: %s", key, ipval);
} while (i < 255);
dis->nr++;
}

29
src/cw/discovery.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef DISCOVERY_H
#define DISCOVERY_H
#include <mavl.h>
#include "cfg.h"
struct cw_DiscoveryResults_elem {
uint32_t key;
char ip[64];
cw_Cfg_t * cfg;
int prio;
int wtps;
int ctr;
};
struct cw_DiscoveryResults
{
int nr;
struct mavl * list;
};
void cw_discovery_results_destroy(struct cw_DiscoveryResults *dis);
struct cw_DiscoveryResults * cw_discovery_results_create();
void cw_discovery_results_add(struct cw_DiscoveryResults *dis, cw_Cfg_t *ac_cfg, cw_Cfg_t * wtp_cfg);
void cw_discovery_results_destroy(struct cw_DiscoveryResults * r);
#endif

View File

@ -31,6 +31,7 @@
#define dtls_connect dtls_openssl_connect #define dtls_connect dtls_openssl_connect
#define dtls_shutdown dtls_openssl_shutdown #define dtls_shutdown dtls_openssl_shutdown
#define dtls_get_cipher dtls_openssl_get_cipher #define dtls_get_cipher dtls_openssl_get_cipher
#define dtls_data_destroy dtls_openssl_data_destroy
#else #else
#include "dtls_gnutls.h" #include "dtls_gnutls.h"
#define dtls_init dtls_gnutls_init #define dtls_init dtls_gnutls_init

Some files were not shown because too many files have changed in this diff Show More