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,21 +241,23 @@ 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);
 | 
				
			||||||
 | 
					        sprintf(dst, "%s", e->key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!conf_listen_addrs_len) {
 | 
					
 | 
				
			||||||
		cw_log (LOG_ERR, "Fatal error: No listen addresses found.");
 | 
					int ac_run(cw_Cfg_t * cfg)
 | 
				
			||||||
		return 1;
 | 
					{
 | 
				
			||||||
	}
 | 
					        struct cw_Cfg_iter cfi;
 | 
				
			||||||
 | 
						const char *s;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@ -362,16 +266,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 +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);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else{
 | 
				
			||||||
 | 
								s=acid;
 | 
				
			||||||
 | 
								for (i = 0; i < macaddress_len; i++) {
 | 
				
			||||||
 | 
									s += sprintf(s, "%02X", macaddress[i]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	conf_acname_len = strlen(conf_acname);
 | 
					
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										483
									
								
								src/cw/cfg.c
									
									
									
									
									
								
							
							
						
						
									
										483
									
								
								src/cw/cfg.c
									
									
									
									
									
								
							@ -7,28 +7,82 @@
 | 
				
			|||||||
#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)
 | 
				
			||||||
	struct cw_Cfg_entry * e1,*e2;
 | 
					{
 | 
				
			||||||
	e1=(struct cw_Cfg_entry *)k1;
 | 
						while (isdigit(*s))
 | 
				
			||||||
	e2=(struct cw_Cfg_entry *)k2;
 | 
							s++;
 | 
				
			||||||
	return strcmp(e1->key,e2->key);
 | 
						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;
 | 
				
			||||||
 | 
						e1 = (struct cw_Cfg_entry *) k1;
 | 
				
			||||||
 | 
						e2 = (struct cw_Cfg_entry *) k2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cw_Cfg_t * cw_cfg_create()
 | 
					cw_Cfg_t *cw_cfg_create()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return mavl_create(cmp, del, sizeof(struct cw_Cfg_entry));
 | 
						return mavl_create(cmp, del, sizeof(struct cw_Cfg_entry));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cw_Cfg_entry e;
 | 
						struct cw_Cfg_entry e;
 | 
				
			||||||
	int replaced;
 | 
						int replaced;
 | 
				
			||||||
@ -37,12 +91,12 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val)
 | 
				
			|||||||
	if (!e.key)
 | 
						if (!e.key)
 | 
				
			||||||
		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);
 | 
				
			||||||
	if (!rc){
 | 
						if (!rc) {
 | 
				
			||||||
		del(&e);
 | 
							del(&e);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -52,32 +106,27 @@ 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)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	mavliter_t it;
 | 
						mavliter_t it;
 | 
				
			||||||
	struct cw_Cfg_entry *e;
 | 
						struct cw_Cfg_entry *e;
 | 
				
			||||||
	mavliter_init(&it,cfg);
 | 
						mavliter_init(&it, cfg);
 | 
				
			||||||
	mavliter_foreach(&it){
 | 
						mavliter_foreach(&it) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		e = mavliter_get(&it);
 | 
							e = mavliter_get(&it);
 | 
				
			||||||
		printf("%s: '%s'\n",e->key,e->val);
 | 
							printf("%s: '%s'\n", e->key, e->val);
 | 
				
			||||||
		//cw_dbg(dbglevel,"%s%s :%s: %s",prefix,data->key,type->get_type_name(data), value);
 | 
							//cw_dbg(dbglevel,"%s%s :%s: %s",prefix,data->key,type->get_type_name(data), value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -97,23 +146,23 @@ struct parser {
 | 
				
			|||||||
static int get_char(struct parser *p)
 | 
					static int get_char(struct parser *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
	c = fgetc (p->f);
 | 
						c = fgetc(p->f);
 | 
				
			||||||
	p->pos++;
 | 
						p->pos++;
 | 
				
			||||||
	if (c=='\n'){
 | 
						if (c == '\n') {
 | 
				
			||||||
		p->prevpos=p->pos;
 | 
							p->prevpos = p->pos;
 | 
				
			||||||
		p->line ++;
 | 
							p->line++;
 | 
				
			||||||
		p->pos=0;
 | 
							p->pos = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	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);
 | 
					{
 | 
				
			||||||
	if (c=='\n'){
 | 
						ungetc(c, p->f);
 | 
				
			||||||
 | 
						if (c == '\n') {
 | 
				
			||||||
		p->line--;
 | 
							p->line--;
 | 
				
			||||||
		p->pos=p->prevpos;
 | 
							p->pos = p->prevpos;
 | 
				
			||||||
	}
 | 
						} else
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		p->pos--;
 | 
							p->pos--;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -123,17 +172,17 @@ static int get_char_q(struct parser *p)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while(1) {
 | 
						while (1) {
 | 
				
			||||||
		c = get_char(p);
 | 
							c = get_char(p);
 | 
				
			||||||
		if (c==EOF || c=='\n')
 | 
							if (c == EOF || c == '\n')
 | 
				
			||||||
			return c;
 | 
								return c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(c=='"' && !p->quote){
 | 
							if (c == '"' && !p->quote) {
 | 
				
			||||||
			p->quote=1;
 | 
								p->quote = 1;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if(c=='"' && p->quote){
 | 
							if (c == '"' && p->quote) {
 | 
				
			||||||
			p->quote=0;
 | 
								p->quote = 0;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
@ -143,11 +192,11 @@ static int get_char_q(struct parser *p)
 | 
				
			|||||||
	if (!p->quote)
 | 
						if (!p->quote)
 | 
				
			||||||
		return c;
 | 
							return c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c!='\\')
 | 
						if (c != '\\')
 | 
				
			||||||
		return c;
 | 
							return c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c = get_char(p);
 | 
						c = get_char(p);
 | 
				
			||||||
	switch(c){
 | 
						switch (c) {
 | 
				
			||||||
		case EOF:
 | 
							case EOF:
 | 
				
			||||||
			return c;
 | 
								return c;
 | 
				
			||||||
		case 'n':
 | 
							case 'n':
 | 
				
			||||||
@ -158,32 +207,32 @@ static int get_char_q(struct parser *p)
 | 
				
			|||||||
		case '"':
 | 
							case '"':
 | 
				
			||||||
			return '"';
 | 
								return '"';
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			unget_char(p,c);
 | 
								unget_char(p, c);
 | 
				
			||||||
			return '\\';
 | 
								return '\\';
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We will never reach here */
 | 
						/* We will never reach here */
 | 
				
			||||||
	/* return c;*/
 | 
						/* return c; */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int skip_chars (struct parser *p, const char * chars)
 | 
					static int skip_chars(struct parser *p, const char *chars)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ( (c = get_char (p)) != EOF) {
 | 
						while ((c = get_char(p)) != EOF) {
 | 
				
			||||||
		if (strchr (chars, c))
 | 
							if (strchr(chars, c))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		return c;
 | 
							return c;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return c;
 | 
						return c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int skip_to_chars (struct parser *p, const char *chars)
 | 
					static int skip_to_chars(struct parser *p, const char *chars)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ( (c = get_char (p)) != EOF) {
 | 
						while ((c = get_char(p)) != EOF) {
 | 
				
			||||||
		if (strchr (chars, c))
 | 
							if (strchr(chars, c))
 | 
				
			||||||
			return c;
 | 
								return c;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return c;
 | 
						return c;
 | 
				
			||||||
@ -191,52 +240,56 @@ static int skip_to_chars (struct parser *p, const char *chars)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int read_key (struct parser *p, char *key, int max_len)
 | 
					static int read_key(struct parser *p, char *key, int max_len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int c,n;
 | 
						int c, n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		c = skip_chars (p, " \t\n\a\v");
 | 
							c = skip_chars(p, " \t\n\a\v");
 | 
				
			||||||
		if (c == '#') {
 | 
							if (c == '#') {
 | 
				
			||||||
			c = skip_to_chars (p, "\n\a");
 | 
								c = skip_to_chars(p, "\n\a");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} while (c != EOF);
 | 
						} while (c != EOF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unget_char(p,c);
 | 
						unget_char(p, c);
 | 
				
			||||||
	c=get_char_q(p);
 | 
						c = get_char_q(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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)
 | 
				
			||||||
			unget_char(p,c);
 | 
							    && !strchr("._/-()@#|{}[]\\", c) /*strchr(": \t\n\a",c) */ ) {
 | 
				
			||||||
 | 
								unget_char(p, c);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		key[n]=c;
 | 
							key[n] = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c=get_char_q(p);
 | 
							c = get_char_q(p);
 | 
				
			||||||
		n++;
 | 
							n++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	key[n]=0;
 | 
						key[n] = 0;
 | 
				
			||||||
	return n;
 | 
						return n;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int skip_to_colon(FILE *f,struct parser * p)
 | 
					static int skip_to_colon(FILE * f, struct parser *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
	c = skip_chars (p, " \t");
 | 
						c = skip_chars(p, " \t");
 | 
				
			||||||
	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,58 +297,58 @@ 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;
 | 
					{
 | 
				
			||||||
	if (!skip_to_colon(p->f,p))
 | 
						int c, n, quote;
 | 
				
			||||||
 | 
						if (!skip_to_colon(p->f, p))
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	c = skip_chars (p, " \t");
 | 
						c = skip_chars(p, " \t");
 | 
				
			||||||
	if (c=='"'){
 | 
						if (c == '"') {
 | 
				
			||||||
		quote=1;
 | 
							quote = 1;
 | 
				
			||||||
		c=get_char(p);
 | 
							c = get_char(p);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							quote = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else{
 | 
						n = 0;
 | 
				
			||||||
		quote=0;
 | 
						while (c != EOF && n < max_len) {
 | 
				
			||||||
	}
 | 
							if (quote && c == '"') {
 | 
				
			||||||
	n=0;
 | 
					 | 
				
			||||||
	while(c!=EOF && n<max_len){
 | 
					 | 
				
			||||||
		if (quote && c=='"'){
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (c=='\n'){
 | 
							if (c == '\n') {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (quote){
 | 
							if (quote) {
 | 
				
			||||||
			if (c=='\\'){
 | 
								if (c == '\\') {
 | 
				
			||||||
				c = get_char(p);
 | 
									c = get_char(p);
 | 
				
			||||||
				switch(c){
 | 
									switch (c) {
 | 
				
			||||||
					case 'n':
 | 
										case 'n':
 | 
				
			||||||
						c='\n';
 | 
											c = '\n';
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case '\\':
 | 
										case '\\':
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case '"':
 | 
										case '"':
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					default:
 | 
										default:
 | 
				
			||||||
						unget_char(p,c);
 | 
											unget_char(p, c);
 | 
				
			||||||
						c='\\';
 | 
											c = '\\';
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		val[n++]=c;
 | 
							val[n++] = c;
 | 
				
			||||||
		c=get_char(p);
 | 
							c = get_char(p);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(!quote && n>0){
 | 
						if (!quote && n > 0) {
 | 
				
			||||||
		while(n>0){
 | 
							while (n > 0) {
 | 
				
			||||||
			if (isspace(val[n-1]))
 | 
								if (isspace(val[n - 1]))
 | 
				
			||||||
				n--;
 | 
									n--;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val[n]=0;
 | 
						val[n] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return n;
 | 
						return n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -303,20 +356,20 @@ static int read_val(struct parser *p, char *val, int max_len){
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cw_cfg_read_line (FILE *f, struct parser *p, char * key, char *val)
 | 
					int cw_cfg_read_line(FILE * f, struct parser *p, char *key, char *val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int n;
 | 
						int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n = read_key (p,key,CW_CFG_MAX_KEY_LEN);
 | 
						n = read_key(p, key, CW_CFG_MAX_KEY_LEN);
 | 
				
			||||||
	if (n==0)
 | 
						if (n == 0)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	if (n==-1){
 | 
						if (n == -1) {
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n = read_val (p,val,CW_CFG_MAX_KEY_LEN);
 | 
						n = read_val(p, val, CW_CFG_MAX_KEY_LEN);
 | 
				
			||||||
	if (n==-1){
 | 
						if (n == -1) {
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
@ -328,45 +381,229 @@ int cw_cfg_read_from_file(FILE * f, cw_Cfg_t * cfg)
 | 
				
			|||||||
	char val[2048];
 | 
						char val[2048];
 | 
				
			||||||
	struct parser p;
 | 
						struct parser p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p.line=1;
 | 
						p.line = 1;
 | 
				
			||||||
	p.pos=0;
 | 
						p.pos = 0;
 | 
				
			||||||
	p.prevpos=0;
 | 
						p.prevpos = 0;
 | 
				
			||||||
	p.quote=0;
 | 
						p.quote = 0;
 | 
				
			||||||
	p.f=f;
 | 
						p.f = f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
	int errs=0;
 | 
						int errs = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rc = cw_cfg_read_line(f,&p,key,val);
 | 
							rc = cw_cfg_read_line(f, &p, key, val);
 | 
				
			||||||
		if (rc==-1){
 | 
							if (rc == -1) {
 | 
				
			||||||
			fprintf(stderr,"Error: %s\n",p.error);
 | 
								fprintf(stderr, "Error: %s\n", p.error);
 | 
				
			||||||
			errs++;
 | 
								errs++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (rc != 0){
 | 
							if (rc != 0) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cw_cfg_set(cfg,key,val);
 | 
							cw_cfg_set(cfg, key, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}while(rc==0);
 | 
						} while (rc == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return errs;
 | 
						return errs;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cw_cfg_load(const char *filename,cw_Cfg_t * cfg)
 | 
					int cw_cfg_load(const char *filename, cw_Cfg_t * cfg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int errs;
 | 
						int errs;
 | 
				
			||||||
	FILE *f = fopen(filename,"rb");
 | 
						FILE *f = fopen(filename, "rb");
 | 
				
			||||||
	if (!f)
 | 
						if (!f)
 | 
				
			||||||
		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