/* 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 "cw/cw_util.h" #include "cw/dbg.h" #include "cw/cw.h" #include "cw/cfg.h" #include "conf.h" #include "ac.h" uint8_t conf_macaddress[12]; uint8_t conf_macaddress_len = 0; long conf_strict_capwap = 1; long conf_strict_headers = 0; char *conf_acid = NULL; char *conf_primary_if = NULL; char **conf_mcast_groups = 0; int conf_mcast_groups_len = 0; //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; int conf_security = 0; long conf_vendor_id = CONF_DEFAULT_VENDOR_ID; bstr_t conf_hardware_version = NULL; bstr_t conf_software_version = NULL; bstr_t conf_cisco_hardware_version = NULL; bstr_t conf_cisco_software_version = NULL; 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_image_dir = 0; char *conf_control_port = 0; int conf_dtls_verify_peer = 1; static int init_ac_name(cw_Cfg_t * cfg) { char *s; char *primary_if=NULL; char ac_name[CAPWAP_MAX_AC_NAME_LEN+1]; uint8_t macaddress[128]; uint8_t macaddress_len; char acid[128]; int i; s= (char*)cw_cfg_get(cfg,"capwap/ac-name",NULL); if (s!=NULL) return 1; 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]); } } free(primary_if); } sprintf(ac_name,"actube%s",acid); cw_cfg_set(cfg,"capwap/ac-name",ac_name); return 1; } #include "../mod/modload.h" #include static int init_listen_addrs(cw_Cfg_t * cfg) { char key[CW_CFG_MAX_KEY_LEN]; struct ifaddrs *ifap, *ifa; int rc; int ctr; struct cw_Cfg_iter cfi; cw_cfg_iter_init(cfg, &cfi, "actube/listen"); if (cw_cfg_iter_next(&cfi,NULL) != NULL) return 0; rc = getifaddrs(&ifap); if (rc == -1) return 0; ctr = 0; /* get the addresses */ for (ifa = ifap; ifa != 0; ifa = ifa->ifa_next) { char str[100]; /** ignore loopback interfaces if configured*/ if (!conf_use_loopback) { if ((ifa->ifa_flags & IFF_LOOPBACK)) { continue; } } if (!ifa->ifa_addr) continue; if (ifa->ifa_addr->sa_family == AF_INET && conf_ipv4) { sock_addrtostr(ifa->ifa_addr, str, 100,0); sprintf(key,"actube/listen.%d",ctr++); cw_cfg_set(cfg,key,str); } if (ifa->ifa_addr->sa_family == AF_INET6 && conf_ipv6) { sock_addrtostr(ifa->ifa_addr, str, 100,0); if (strncmp(str, "fe80:", 5) == 0) { strcat(str, "%"); strcat(str, ifa->ifa_name); } sprintf(key,"actube/listen.%d",ctr++); cw_cfg_set(cfg,key,str); } } 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", /* "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 /* static int add_bcast_addr(void *priv, void *addr) { printf("Callback Called\n"); union mavldata *ud; ud = addr; printf("Callback Called %s\n", ud->str); 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(cw_Cfg_t *cfg) { int rc; char str[100]; char key[100]; struct ifaddrs *ifa0, *ifa; mavl_t t; mavliter_t it; struct cw_Cfg_iter cfi; int i; cw_cfg_iter_init(cfg, &cfi, "actube/bcast"); if (cw_cfg_iter_next(&cfi,NULL) != NULL) return 0; if (!cw_cfg_get_bool(cfg,"actube/ipv4", 1)) return 1; /*t = mavl_create_ptr(); */ t = mavl_create_ptr(mavl_cmpstr,mavl_freeptr); if (t==NULL) return 0; /* add the default broadast address */ mavl_add_str(t, cw_strdup("255.255.255.255")); /* add all other local broadcast addresses */ 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) continue; if (sa->sa_family != AF_INET) continue; if (ifa->ifa_broadaddr) { char *s,*sr; sock_addrtostr(ifa->ifa_broadaddr, str, 100,1); *strchr(str, ':') = 0; 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 *)); i=0; mavliter_init(&it,t); mavliter_foreach(&it){ char * d; d = mavliter_get_str(&it); // conf_bcast_addrs[conf_bcast_addrs_len] = cw_strdup(d); // if (conf_bcast_addrs[conf_bcast_addrs_len] != 0) // conf_bcast_addrs_len++; sprintf(key,"actube/bcast.%d",i++); cw_cfg_set(cfg,key,d); } mavl_destroy(t); freeifaddrs(ifa0); return 1; } int init_mcast_groups(cw_Cfg_t * cfg) { int ctr; int i; int n = 0; int n4 = 0, n6 = 0; if (conf_mcast_groups) return 1; if (conf_ipv4) { n4 = sizeof(conf_default_mcast_groups_ipv4) / sizeof(char *); } if (conf_ipv6) { n6 = sizeof(conf_default_mcast_groups_ipv6) / sizeof(char *); } 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 *)); ctr = 0; for (i = 0; i < n4; i++) { uint8_t *g = (uint8_t *) conf_default_mcast_groups_ipv4[i]; conf_mcast_groups[ctr] = (char *) cw_setstr((uint8_t **) & conf_mcast_groups[ctr], g, strlen((char *) g)); if (conf_mcast_groups[ctr]) ctr++; } for (i = 0; i < n6; i++) { uint8_t *g = (uint8_t *) conf_default_mcast_groups_ipv6[i]; conf_mcast_groups[ctr] = (char *) cw_setstr((uint8_t **) & conf_mcast_groups[ctr], g, strlen((char *) g)); if (conf_mcast_groups[ctr]) ctr++; } conf_mcast_groups_len = n; return 1; } /* static int conf_read_strings(cfg_t * cfg, char *name, char ***dst, int *len) { int n, i; n = cfg_size(cfg, name); *len = n; if (n == 0) return 1; *dst = malloc(sizeof(char *) * n); if (!*dst) return 0; for (i = 0; i < n; i++) { char *str = cfg_getnstr(cfg, name, i); if (!((*dst)[i] = malloc(strlen(str) + 1))) { *len = 0; return 0; } strcpy((*dst)[i], str); } return 1; } */ /* static int conf_read_dbg_level(cfg_t * cfg) { const char *name = "dbg"; int n, i; n = cfg_size(cfg, name); for (i = 0; i < n; i++) { char *str = cfg_getnstr(cfg, name, i); int b = cw_strlist_get_id(cw_dbg_strings, str); cw_dbg_set_level(b, 1); } return 1; } */ struct cw_Mod ** conf_mods; char *conf_mods_dir = NULL; /* * Read the module names from config file */ static int init_mods(cw_Cfg_t *cfg){ int i; struct cw_Cfg_entry *e; const char * modname; 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_mod_set_path(conf_mods_dir); cw_cfg_iter_init(cfg, &cfi, "actube/mod"); for (i=0; (e = cw_cfg_iter_next(&cfi, NULL)) != NULL; i++) { modname = e->val; struct cw_Mod * mod = cw_mod_load(modname, cfg, CW_ROLE_AC); if (!mod) return 0; cw_mod_add_to_list(mod); } return 1; } int conf_parse_listen_addr(const char *addrstr, char *saddr, char *port, int *proto) { char *b; int c; int i, l; char *ctrlport; char *p = strchr(addrstr, '/'); if (!p) *proto = AC_PROTO_CAPWAP; else { if (strcmp("capwap", p + 1) == 0) *proto = AC_PROTO_CAPWAP; else if (strcmp("lwapp", p + 1) == 0) *proto = AC_PROTO_LWAPP; else *proto = AC_PROTO_UNKNOWN; } switch (*proto) { case AC_PROTO_CAPWAP: ctrlport = CAPWAP_CONTROL_PORT_STR; break; case AC_PROTO_LWAPP: ctrlport = LWAPP_CONTROL_PORT_STR; break; default: ctrlport = "0"; } c = 0; if (p) l = p - addrstr; else l = strlen(addrstr); for (i = 0; i < l; i++) { if (addrstr[i] == ':') c++; } /* no colon found, asume its ipv4 w/o port */ if (c == 0) { strncpy(saddr, addrstr, l); saddr[l] = 0; strcpy(port, ctrlport); return 0; } /* one colon found, so we assume, its an ipv4 * address with port */ if (c == 1) { char *c = strchr(addrstr, ':'); strncpy(saddr, addrstr, c - addrstr); saddr[c - addrstr] = 0; strncpy(port, c + 1, l - (c - addrstr)); port[l - (c - addrstr) - 1] = 0; return 0; } /* we assume now, its ipv6 */ b = strstr(addrstr, "]:"); if (!b) { /* ippv6 w/o port */ strncpy(saddr, addrstr, l); saddr[l] = 0; strcpy(port, ctrlport); return 0; } strncpy(saddr, addrstr + 1, b - addrstr); saddr[b - addrstr - 1] = 0; strncpy(port, b + 2, l - (b - addrstr) - 2); port[l - (b - addrstr) - 2] = 0; return 0; } void ac_conf_init(cw_Cfg_t *cfg) { init_listen_addrs(cfg); init_bcast_addrs(cfg); init_ac_name(cfg); init_mods(cfg); }