/*
This file is part of actube.
libcapwap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libcapwap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see .
*/
#include
#include
#include
#include
#include "capwap.h"
#include "sock.h"
#include "conf.h"
#include "cw_log.h"
#include "cw_util.h"
uint8_t conf_macaddress[12];
uint8_t conf_macaddress_len=0;
char * conf_acname = NULL;
int conf_acname_len = 0;
char * conf_acid = NULL;
char * conf_primary_if = NULL;
long conf_max_wtps = CONF_DEFAULT_MAXWTPS;
char * conf_logfilename=CONF_DEFAULT_LOGFILENAME;
struct sockaddr_storage * conf_salist=NULL;
char ** conf_listen_addrs;
int conf_listen_addrs_len=0;
char ** conf_mcast_groups=0;
int conf_mcast_groups_len=0;
char ** conf_bcast_addrs=0;
int conf_bcast_addrs_len;
struct sockaddr_storage * conf_bsalist=NULL;
int conf_salist_len=0;
int conf_bsalist_len=0;
struct sockaddr * conf_ac_ips;
int conf_ac_ips_len;
char * conf_sslcertfilename=NULL;
char * conf_sslkeyfilename=NULL;
char * conf_sslkeypass=NULL;
char * conf_dtls_psk=NULL;
//char * conf_ac_hardware_version=NULL;
//char * conf_ac_software_version=NULL;
int conf_security=0;
long conf_vendor_id=CONF_DEFAULT_VENDOR_ID;
char * conf_hardware_version;
char * conf_software_version;
int conf_use_loopback = 0;
long conf_debug_level=-1;
char * conf_db_file =0;
int conf_ipv4=1;
#ifdef WITH_IPV6
int conf_ipv6=1;
#endif
#ifdef WITH_LWAPP
int conf_lwapp=1;
char * conf_lw_control_port=0;
#endif
char * conf_control_port=0;
static int init_acname()
{
if (conf_acname == NULL){
conf_acname=malloc(strlen(CONF_DEFAULT_ACNAME)+strlen(conf_acid)+1);
sprintf(conf_acname,"%s%s",CONF_DEFAULT_ACNAME,conf_acid);
}
conf_acname_len=strlen(conf_acname);
return 1;
}
static int init_acid()
{
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;
};
int i;
conf_acid = malloc(2*conf_macaddress_len+1);
char *s = conf_acid;
for (i=0; i
static int init_listen_addrs()
{
if (conf_listen_addrs!=0)
return 1;
struct ifaddrs * ifap,*ifa;
int rc = getifaddrs(&ifap);
if (rc==-1)
return 0;
/* count the addresses */
int ctr=0;
for (ifa=ifap; ifa!=0; ifa=ifa->ifa_next){
if (ifa->ifa_addr->sa_family==AF_INET && conf_ipv4)
ctr++;
#ifdef WITH_IPV6
if (ifa->ifa_addr->sa_family==AF_INET6 && conf_ipv6)
ctr++;
#endif
}
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;
/* get the addresses */
for (ifa=ifap; ifa!=0; ifa=ifa->ifa_next){
char str[100];
if(!conf_use_loopback){
if ((ifa->ifa_flags & IFF_LOOPBACK)){
continue;
}
}
if (ifa->ifa_addr->sa_family==AF_INET && conf_ipv4){
sock_addrtostr(ifa->ifa_addr,str,100);
*strchr(str,':')=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++;
}
#ifdef WITH_IPV6
if (ifa->ifa_addr->sa_family==AF_INET6 && conf_ipv6){
sock_addrtostr(ifa->ifa_addr,str,100);
if (strncmp(str,"fe80:",5)==0){
strcat(str,"%");
strcat(str,ifa->ifa_name);
}
conf_listen_addrs[ctr]=(char*)cw_setstr((uint8_t**)&conf_listen_addrs[ctr],(uint8_t*)str,strlen(str));
if (conf_listen_addrs[ctr])
ctr++;
}
#endif
}
conf_listen_addrs_len=ctr;
rc=1;
errX:
freeifaddrs(ifap);
return rc;
}
static char * conf_default_mcast_groups_ipv4[] = {
"224.0.1.140",
};
#ifdef WITH_IPV6
static char * conf_default_mcast_groups_ipv6[] = {
/* "ff01:0:0:0:0:0:0:18c",
"ff02:0:0:0:0:0:0:18c%em0",
"ff03:0:0:0:0:0:0:18c",
"ff04:0:0:0:0:0:0:18c",
"ff05:0:0:0:0:0:0:18c",
"ff06:0:0:0:0:0:0:18c"
*/
};
#endif
//#include "avltree"
#include "stravltree.h"
static int add_bcast_addr(void *priv, void * addr)
{
char *s = (char*)addr;
conf_bcast_addrs[conf_bcast_addrs_len]=strdup(s);
if (conf_bcast_addrs[conf_bcast_addrs_len]!=0)
conf_bcast_addrs_len++;
return 1;
}
/*
* Initialize broadcast addresses (ipv4 only)
*/
int init_bcast_addrs()
{
if (conf_bcast_addrs)
return 1;
if (!conf_ipv4)
return 1;
struct avltree *t = stravltree_create();
if (!t)
return 0;
/* add the default broadast address */
stravltree_add(t,"255.255.255.255");
/* add all other local broadcast addresses */
struct ifaddrs * ifa0,*ifa;
int rc = getifaddrs(&ifa0);
if (rc==-1)
return 0;
for (ifa=ifa0; ifa!=0; ifa=ifa->ifa_next){
struct sockaddr * sa;
if (!(ifa->ifa_flags & IFF_BROADCAST))
continue;
if(!conf_use_loopback){
if ((ifa->ifa_flags & IFF_LOOPBACK))
continue;
}
sa = ifa->ifa_addr;
if(sa->sa_family != AF_INET)
continue;
char str[100];
if (ifa->ifa_broadaddr){
sock_addrtostr(ifa->ifa_broadaddr,str,100);
*strchr(str,':')=0;
stravltree_add(t,str);
}
}
conf_bcast_addrs=malloc(t->count*sizeof(char*));
stravltree_foreach(t,add_bcast_addr,0,1);
stravltree_destroy(t);
freeifaddrs(ifa0);
return 1;
}
int init_mcast_groups()
{
if (conf_mcast_groups)
return 1;
int n = 0;
int n4=0,n6=0;
if (conf_ipv4){
n4=sizeof(conf_default_mcast_groups_ipv4)/sizeof(char*);
}
#ifdef WITH_IPV6
if (conf_ipv6){
n6=sizeof(conf_default_mcast_groups_ipv6)/sizeof(char*);
}
#endif
n=n4+n6;
if (n==0)
return 1;
conf_mcast_groups=malloc(sizeof(char*)*n);
if (!conf_mcast_groups)
return 0;
memset(conf_mcast_groups,0,n*sizeof(char*));
int ctr=0;
int i;
for(i=0; i