Compare commits
18 Commits
v0.0.0
...
8aa11dccba
| Author | SHA1 | Date | |
|---|---|---|---|
| 8aa11dccba | |||
| 7d28858a70 | |||
| 8db182a303 | |||
| 9452589625 | |||
| be3adf279d | |||
| 1544c6aa1b | |||
| a3bc9dd09c | |||
| fb280d1c1c | |||
| 5240553144 | |||
| 1598abee34 | |||
| 156466eab9 | |||
| 04d469b970 | |||
| 0e07e42167 | |||
| 4c37d89f03 | |||
| 6d9da94863 | |||
| 1616d77a0f | |||
| a389003199 | |||
| eac5e73528 |
@ -17,7 +17,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
|
||||||
|
|||||||
172
src/ac/ac_main.c
172
src/ac/ac_main.c
@ -48,7 +48,8 @@
|
|||||||
|
|
||||||
#include "cw/cfg.h"
|
#include "cw/cfg.h"
|
||||||
|
|
||||||
int ac_run();
|
int ac_run(cw_Cfg_t * cfg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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) {
|
||||||
|
|
||||||
@ -141,52 +142,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;
|
||||||
@ -221,7 +176,7 @@ int main (int argc, char *argv[])
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct bootcfg bootcfg;
|
struct bootcfg bootcfg;
|
||||||
FILE * file;
|
FILE * file;
|
||||||
mavl_t types_tree, acglobal_cfg;
|
mavl_t types_tree;
|
||||||
const cw_Type_t **ti;
|
const cw_Type_t **ti;
|
||||||
|
|
||||||
|
|
||||||
@ -239,75 +194,17 @@ 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();
|
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");
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Init DTLS library */
|
/* Init DTLS library */
|
||||||
dtls_init();
|
dtls_init();
|
||||||
|
|
||||||
@ -322,15 +219,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,39 +241,47 @@ 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()
|
static void pcb(char *dst, struct mavlnode *node)
|
||||||
{
|
{
|
||||||
|
struct cw_Cfg_entry *e = mavlnode_dataptr(node);
|
||||||
if (!conf_listen_addrs_len) {
|
sprintf(dst, "%s", e->key);
|
||||||
cw_log (LOG_ERR, "Fatal error: No listen addresses found.");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ac_run(cw_Cfg_t * cfg)
|
||||||
|
{
|
||||||
|
struct cw_Cfg_iter cfi;
|
||||||
|
const char *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* it is important to create the unicast sockets first,
|
/* it is important to create the unicast sockets first,
|
||||||
* because when we create the mcast an bcast sockets next
|
* because when we create the mcast an bcast sockets next
|
||||||
* 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 +289,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 +308,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);
|
||||||
|
|||||||
367
src/ac/conf.c
367
src/ac/conf.c
@ -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,44 @@ 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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(ac_name,"actube%s",acid);
|
||||||
|
cw_cfg_set(cfg,"capwap/ac-name",ac_name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,49 +158,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 +194,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 +230,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 +241,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 +292,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 +347,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 +386,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 +440,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 +466,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 +486,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 +494,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 +616,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);
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
39
src/ac/config.ckv
Normal file
39
src/ac/config.ckv
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#Cfg
|
||||||
|
|
||||||
|
#
|
||||||
|
# AC Name
|
||||||
|
# Deafults to actube + mac address of primary interface
|
||||||
|
#
|
||||||
|
#capwap/ac-name
|
||||||
|
#
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
281
src/cw/cfg.c
281
src/cw/cfg.c
@ -7,19 +7,73 @@
|
|||||||
#include "cfg.h"
|
#include "cfg.h"
|
||||||
#include "val.h"
|
#include "val.h"
|
||||||
|
|
||||||
static int cmp(const void *k1,const void*k2){
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +92,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,22 +106,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cw_cfg_dump(cw_Cfg_t * cfg)
|
void cw_cfg_dump(cw_Cfg_t * cfg)
|
||||||
{
|
{
|
||||||
@ -107,13 +156,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 +259,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 +283,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 +297,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 +306,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 +421,189 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cw_cfg_get_next_idx(cw_Cfg_t * cfg, const char *key, int n)
|
||||||
|
{
|
||||||
|
char ikey[CW_CFG_MAX_KEY_LEN];
|
||||||
|
struct cw_Cfg_entry search, *result;
|
||||||
|
const char *d;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(ikey, "%s.%d", key, n);
|
||||||
|
|
||||||
|
search.key = ikey;
|
||||||
|
result = mavl_get_first(cfg, &search);
|
||||||
|
|
||||||
|
printf("KEY: %s\n", search.key);
|
||||||
|
printf("NNNNN: %s\n", result->key);
|
||||||
|
|
||||||
|
|
||||||
|
if (result == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
d = NULL;
|
||||||
|
for (i = strlen(ikey); i >= 0; i--) {
|
||||||
|
|
||||||
|
if (ikey[i] == '.') {
|
||||||
|
d = result->key + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result->key[i] != '.') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(result->key, ikey, i) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
printf("TRANSFER %s\n", result->key + i + 1);
|
||||||
|
return atoi(result->key + i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void pcb(char *dst, struct mavlnode *node)
|
||||||
|
{
|
||||||
|
struct cw_Cfg_entry *e = mavlnode_dataptr(node);
|
||||||
|
sprintf(dst, "%s", e->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cw_cfg_iterate(cw_Cfg_t * cfg, const char *key)
|
||||||
|
{
|
||||||
|
printf("Iterate\n");
|
||||||
|
struct cw_Cfg_entry *e;
|
||||||
|
struct cw_Cfg_entry search;
|
||||||
|
search.key = key;
|
||||||
|
struct mavliter it;
|
||||||
|
struct mavlnode *first;
|
||||||
|
|
||||||
|
mavl_print(cfg,pcb,180);
|
||||||
|
|
||||||
|
printf("SEEK TO %s\n", search.key);
|
||||||
|
|
||||||
|
struct cw_Cfg_iter cfi;
|
||||||
|
cw_cfg_iter_init(cfg, &cfi, key);
|
||||||
|
const char *kee;
|
||||||
|
|
||||||
|
while ((kee = cw_cfg_iter_next(&cfi, NULL)) != NULL) {
|
||||||
|
printf("KEY===%s\n", kee);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
mavliter_init(&it, cfg);
|
||||||
|
mavliter_seek(&it, &search, 0);
|
||||||
|
struct cw_Cfg_entry *en;
|
||||||
|
return;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
i = cw_cfg_get_next_idx(cfg, "actube/listen", i);
|
||||||
|
|
||||||
|
printf("This i %d\n", i);
|
||||||
|
|
||||||
|
while ((i = cw_cfg_get_next_idx(cfg, "actube/listen", i)) != -1) {
|
||||||
|
|
||||||
|
printf("Here i %d\n", i);
|
||||||
|
printf("we have key: %s.%d\n", "actube/listen", i);
|
||||||
|
printf("Next=%d\n", i);
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
e = mavl_get_first(cfg, &search);
|
||||||
|
if (!e) {
|
||||||
|
printf("NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("%s : %s\n", e->key, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key, const char * def)
|
||||||
|
{
|
||||||
|
struct cw_Val v;
|
||||||
|
const char *s = cw_cfg_get(cfg,key,def);
|
||||||
|
CW_TYPE_WORD->from_str(&v,s);
|
||||||
|
return v.val.word;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
src/cw/cfg.h
18
src/cw/cfg.h
@ -14,11 +14,23 @@ 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, const char * def);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -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 );
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "cw/val.h"
|
#include "cw/val.h"
|
||||||
#include "cw/keys.h"
|
#include "cw/keys.h"
|
||||||
#include "cw/dtls.h"
|
#include "cw/dtls.h"
|
||||||
|
#include "cw/cfg.h"
|
||||||
|
|
||||||
#include "mod_capwap.h"
|
#include "mod_capwap.h"
|
||||||
|
|
||||||
@ -15,16 +16,15 @@ static int init(struct cw_Mod * mod, mavl_t global_cfg, int role)
|
|||||||
switch (role){
|
switch (role){
|
||||||
case CW_ROLE_AC:{
|
case CW_ROLE_AC:{
|
||||||
cw_dbg(DBG_MOD, "CAPWAP: Initialiazing mod_capwap in AC mode");
|
cw_dbg(DBG_MOD, "CAPWAP: Initialiazing mod_capwap in AC mode");
|
||||||
cw_ktv_add_from_str(global_cfg,
|
cw_cfg_set(global_cfg,
|
||||||
"capwap/ac-descriptor/hardware/version",
|
"capwap/ac-descriptor/hardware/version",
|
||||||
CW_TYPE_BSTR16,NULL,"0.0.0.1");
|
"0.0.0.1");
|
||||||
cw_ktv_add_from_str(global_cfg,
|
cw_cfg_set(global_cfg,
|
||||||
"capwap/ac-descriptor/hardware/vendor",CW_TYPE_DWORD,NULL,"0");
|
"capwap/ac-descriptor/hardware/vendor","0");
|
||||||
cw_ktv_add_from_str(global_cfg,
|
cw_cfg_set(global_cfg,
|
||||||
"capwap/ac-descriptor/software/version",
|
"capwap/ac-descriptor/software/version","0.0.0.1");
|
||||||
CW_TYPE_BSTR16, NULL, "0.0.0.1");
|
cw_cfg_set(global_cfg,
|
||||||
cw_ktv_add_from_str(global_cfg,
|
"capwap/ac-descriptor/software/vendor", "0");
|
||||||
"capwap/ac-descriptor/software/vendor",CW_TYPE_DWORD, NULL, "0");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user