static void add_A_to_garden(uint8_t *p) { struct in_addr reqaddr; pass_through pt; memcpy(&reqaddr.s_addr, p, 4); memset(&pt, 0, sizeof(pass_through)); pt.mask.s_addr = 0xffffffff; pt.host = reqaddr; if (pass_through_add(dhcp->pass_throughs, MAX_PASS_THROUGHS, &dhcp->num_pass_throughs, &pt, 1 #ifdef HAVE_PATRICIA , dhcp->ptree_dyn #endif )) ; }
int main(int argc, char **argv) { struct gengetopt_args_info args_info; struct hostent *host; char hostname[USERURLSIZE]; int numargs; int ret = -1; int i; options_init(); memset(&args_info, 0, sizeof(args_info)); if (cmdline_parser2(argc, argv, &args_info, 1, 1, 1) != 0) { log_err(0, "Failed to parse command line options"); goto end_processing; } if (args_info.version_given) { options_print_version(); exit(2); } if (args_info.help_given) { options_print_help(); exit(2); } if (cmdline_parser_configfile(args_info.conf_arg ? args_info.conf_arg : DEFCHILLICONF, &args_info, 0, 0, 0)) { log_err(0, "Failed to parse configuration file: %s!", args_info.conf_arg); if (!args_info.forgiving_flag) goto end_processing; } /* Get the system default DNS entries */ if (res_init()) { log_err(0, "Failed to update system DNS settings (res_init()!"); goto end_processing; } /* Handle each option */ _options.initialized = 1; if (args_info.debug_flag) _options.debug = args_info.debugfacility_arg; else _options.debug = 0; /* pass-throughs */ memset(_options.pass_throughs, 0, sizeof(_options.pass_throughs)); _options.num_pass_throughs = 0; /** simple configuration parameters **/ _options.layer3 = args_info.layer3_flag; #if(_debug_ && !defined(ENABLE_LAYER3)) if (_options.layer3) log_warn(0, "layer3 not implemented. build with --enable-layer3"); #endif _options.uid = args_info.uid_arg; _options.gid = args_info.gid_arg; _options.mtu = args_info.mtu_arg; _options.usetap = args_info.usetap_flag; _options.noarpentries = args_info.noarpentries_flag; #if(_debug_ && !defined(ENABLE_TAP)) if (_options.noarpentries) log_warn(0, "tap not implemented. build with --enable-tap"); #endif #if(_debug_ && !defined(ENABLE_TAP)) if (_options.usetap) log_warn(0, "tap not implemented. build with --enable-tap"); #endif _options.foreground = args_info.fg_flag; _options.interval = args_info.interval_arg; _options.lease = args_info.lease_arg; _options.leaseplus = args_info.leaseplus_arg; _options.dhcpstart = args_info.dhcpstart_arg; _options.dhcpend = args_info.dhcpend_arg; _options.eapolenable = args_info.eapolenable_flag; #if(_debug_ && !defined(ENABLE_EAPOL)) if (_options.eapolenable) log_warn(0, "EAPOL not implemented. build with --enable-eapol"); #endif _options.swapoctets = args_info.swapoctets_flag; _options.logfacility = args_info.logfacility_arg; _options.chillixml = args_info.chillixml_flag; _options.macauth = args_info.macauth_flag; _options.macreauth = args_info.macreauth_flag; _options.macauthdeny = args_info.macauthdeny_flag; _options.uamport = args_info.uamport_arg; #ifdef ENABLE_UAMUIPORT _options.uamuiport = args_info.uamuiport_arg; #endif _options.macallowlocal = args_info.macallowlocal_flag; _options.strictmacauth = args_info.strictmacauth_flag; _options.strictdhcp = args_info.strictdhcp_flag; _options.no_wispr1 = args_info.nowispr1_flag; _options.no_wispr2 = args_info.nowispr2_flag; _options.wpaguests = args_info.wpaguests_flag; _options.openidauth = args_info.openidauth_flag; _options.challengetimeout = args_info.challengetimeout_arg; _options.challengetimeout2 = args_info.challengetimeout2_arg; _options.defsessiontimeout = args_info.defsessiontimeout_arg; _options.definteriminterval = args_info.definteriminterval_arg; _options.defbandwidthmaxdown = args_info.defbandwidthmaxdown_arg; _options.defbandwidthmaxup = args_info.defbandwidthmaxup_arg; _options.defidletimeout = args_info.defidletimeout_arg; _options.radiusnasporttype = args_info.radiusnasporttype_arg; _options.radiusauthport = args_info.radiusauthport_arg; _options.radiusacctport = args_info.radiusacctport_arg; _options.coaport = args_info.coaport_arg; _options.coanoipcheck = args_info.coanoipcheck_flag; _options.radiustimeout = args_info.radiustimeout_arg; _options.radiusretry = args_info.radiusretry_arg; _options.radiusretrysec = args_info.radiusretrysec_arg; #ifdef ENABLE_RADPROXY _options.proxyport = args_info.proxyport_arg; _options.proxymacaccept = args_info.proxymacaccept_flag; _options.proxyonacct = args_info.proxyonacct_flag; #endif #if(_debug_ && !defined(ENABLE_RADPROXY)) if (args_info.proxyport_arg) log_err(0,"radproxy not implemented. build with --enable-radproxy"); #endif _options.txqlen = args_info.txqlen_arg; _options.ringsize = args_info.ringsize_arg; _options.sndbuf = args_info.sndbuf_arg; _options.rcvbuf = args_info.rcvbuf_arg; _options.childmax = args_info.childmax_arg; _options.postauth_proxyport = args_info.postauthproxyport_arg; _options.pap_always_ok = args_info.papalwaysok_flag; _options.mschapv2 = args_info.mschapv2_flag; _options.acct_update = args_info.acctupdate_flag; _options.dhcpradius = args_info.dhcpradius_flag; _options.dhcp_broadcast = args_info.dhcpbroadcast_flag; _options.dhcpgwport = args_info.dhcpgatewayport_arg; _options.noc2c = args_info.noc2c_flag; _options.tcpwin = args_info.tcpwin_arg; _options.tcpmss = args_info.tcpmss_arg; _options.max_clients = args_info.maxclients_arg; _options.radiusqsize = args_info.radiusqsize_arg; _options.dhcphashsize = args_info.dhcphashsize_arg; _options.uamdomain_ttl = args_info.uamdomainttl_arg; _options.seskeepalive = args_info.seskeepalive_flag; _options.uamallowpost = args_info.uamallowpost_flag; _options.redir = args_info.redir_flag; _options.redirurl = args_info.redirurl_flag; _options.statusfilesave = args_info.statusfilesave_flag; _options.dhcpnotidle = args_info.dhcpnotidle_flag; #if(_debug_ && !defined(ENABLE_CHILLIREDIR)) if (_options.redir) log_err(0, "chilli_redir not implemented. build with --enable-chilliredir"); #endif _options.redirssl = args_info.redirssl_flag; _options.uamuissl = args_info.uamuissl_flag; _options.domaindnslocal = args_info.domaindnslocal_flag; _options.framedservice = args_info.framedservice_flag; _options.radsec = args_info.radsec_flag; #if(_debug_ && !defined(ENABLE_CHILLIRADSEC)) if (_options.radsec) log_err(0, "chilli_radsec not implemented. build with --enable-chilliradsec"); #endif _options.noradallow = args_info.noradallow_flag; _options.peerid = args_info.peerid_arg; #if(_debug_ && !defined(ENABLE_CLUSTER)) if (_options.peerid) log_err(0, "clustering not implemented. build with --enable-cluster"); #endif _options.redirdnsreq = args_info.redirdnsreq_flag; #if(_debug_ && !defined(ENABLE_REDIRDNSREQ)) if (_options.redirdnsreq) log_err(0, "redirdnsreq not implemented. build with --enable-redirdnsreq"); #endif #ifdef ENABLE_IPV6 _options.ipv6 = args_info.ipv6_flag; _options.ipv6only = args_info.ipv6only_flag; #endif #ifdef ENABLE_LEAKYBUCKET _options.scalewin = args_info.scalewin_flag; _options.bwbucketupsize = args_info.bwbucketupsize_arg; _options.bwbucketdnsize = args_info.bwbucketdnsize_arg; _options.bwbucketminsize = args_info.bwbucketminsize_arg; #endif #ifdef ENABLE_PROXYVSA _options.vlanlocation = args_info.vlanlocation_flag; _options.location_stop_start = args_info.locationstopstart_flag; _options.location_copy_called = args_info.locationcopycalled_flag; _options.location_immediate_update = args_info.locationimmediateupdate_flag; _options.location_option_82 = args_info.locationopt82_flag; if (args_info.proxylocattr_given) { for (numargs = 0; numargs < args_info.proxylocattr_given && numargs < PROXYVSA_ATTR_CNT; ++numargs) { unsigned int i[2]; switch (sscanf(args_info.proxylocattr_arg[numargs], "%u,%u", &i[0], &i[1])) { case 0: log_err(0, "invalid input %s", args_info.proxylocattr_arg[numargs]); break; case 1: _options.proxy_loc[numargs].attr = i[0]; break; case 2: _options.proxy_loc[numargs].attr_vsa = i[0]; _options.proxy_loc[numargs].attr = i[1]; break; } log_dbg("Proxy location attr %d %d", (int)_options.proxy_loc[numargs].attr_vsa, (int)_options.proxy_loc[numargs].attr); } } #endif if (args_info.dhcpgateway_arg && !inet_aton(args_info.dhcpgateway_arg, &_options.dhcpgwip)) { log_err(0, "Invalid DHCP gateway IP address: %s!", args_info.dhcpgateway_arg); if (!args_info.forgiving_flag) goto end_processing; } if (args_info.dhcprelayagent_arg && !inet_aton(args_info.dhcprelayagent_arg, &_options.dhcprelayip)) { log_err(0, "Invalid DHCP gateway relay IP address: %s!", args_info.dhcprelayagent_arg); if (!args_info.forgiving_flag) goto end_processing; } _options.dhcpif = STRDUP(args_info.dhcpif_arg); #ifdef ENABLE_MULTILAN for (numargs = 0; numargs < args_info.moreif_given && numargs < MAX_MOREIF; ++numargs) { char *nif = STRDUP(args_info.moreif_arg[numargs]); char *vln = strchr(nif, '/'); _options.moreif[numargs].dhcpif = nif; if (vln) { if (strlen(vln) > 1) _options.moreif[numargs].vlan = vln + 1; *vln = 0; } else { vln = strchr(nif, '.'); if (vln && strlen(vln) > 1) _options.moreif[numargs].vlan = vln + 1; } } #endif if (!args_info.radiussecret_arg) { log_err(0, "radiussecret must be specified!"); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.nexthop_arg) { memset(_options.nexthop, 0, PKT_ETH_ALEN); _options.has_nexthop = 0; } else { unsigned int temp[PKT_ETH_ALEN]; char macstr[RADIUS_ATTR_VLEN]; int macstrlen; int i; if ((macstrlen = strlen(args_info.nexthop_arg)) >= (RADIUS_ATTR_VLEN-1)) { log_err(0, "MAC address too long"); if (!args_info.forgiving_flag) goto end_processing; } memcpy(macstr, args_info.nexthop_arg, macstrlen); macstr[macstrlen] = 0; /* Replace anything but hex with space */ for (i=0; i<macstrlen; i++) if (!isxdigit((int) macstr[i])) macstr[i] = 0x20; if (sscanf (macstr, "%2x %2x %2x %2x %2x %2x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6) { log_err(0, "MAC conversion failed!"); return -1; } for (i = 0; i < PKT_ETH_ALEN; i++) _options.nexthop[i] = temp[i]; _options.has_nexthop = 1; } if (!args_info.dhcpmac_arg) { memset(_options.dhcpmac, 0, PKT_ETH_ALEN); _options.dhcpusemac = 0; _options.dhcpmacset = 0; } else { unsigned int temp[PKT_ETH_ALEN]; char macstr[RADIUS_ATTR_VLEN]; int macstrlen; int i; if ((macstrlen = strlen(args_info.dhcpmac_arg)) >= (RADIUS_ATTR_VLEN-1)) { log_err(0, "MAC address too long"); if (!args_info.forgiving_flag) goto end_processing; } memcpy(macstr, args_info.dhcpmac_arg, macstrlen); macstr[macstrlen] = 0; /* Replace anything but hex with space */ for (i=0; i<macstrlen; i++) if (!isxdigit((int) macstr[i])) macstr[i] = 0x20; if (sscanf (macstr, "%2x %2x %2x %2x %2x %2x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6) { log_err(0, "MAC conversion failed!"); return -1; } for (i = 0; i < PKT_ETH_ALEN; i++) _options.dhcpmac[i] = temp[i]; _options.dhcpusemac = 1; _options.dhcpmacset = args_info.dhcpmacset_flag; } if (args_info.net_arg) { if (option_aton(&_options.net, &_options.mask, args_info.net_arg, 0)) { log_err(0, "Invalid network address: %s!", args_info.net_arg); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.uamlisten_arg) { _options.uamlisten.s_addr = htonl(ntohl(_options.net.s_addr)+1); } else if (!inet_aton(args_info.uamlisten_arg, &_options.uamlisten)) { log_err(0, "Invalid UAM IP address: %s!", args_info.uamlisten_arg); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.dhcplisten_arg) { _options.dhcplisten.s_addr = _options.uamlisten.s_addr; } else if (!inet_aton(args_info.dhcplisten_arg, &_options.dhcplisten)) { log_err(0, "Invalid DHCP IP address: %s!", args_info.dhcplisten_arg); if (!args_info.forgiving_flag) goto end_processing; } } else { log_err(0, "Network address must be specified ('net' parameter)!"); if (!args_info.forgiving_flag) goto end_processing; } log_dbg("DHCP Listen: %s", inet_ntoa(_options.dhcplisten)); log_dbg("UAM Listen: %s", inet_ntoa(_options.uamlisten)); if (!args_info.uamserver_arg) { log_err(0, "WARNING: No uamserver defiend!"); } if (args_info.uamserver_arg) { int uamserverport=80; if (_options.debug & DEBUG_CONF) { log_dbg("Uamserver: %s\n", args_info.uamserver_arg); } if (get_urlparts(args_info.uamserver_arg, hostname, USERURLSIZE, &uamserverport, 0)) { log_err(0, "Failed to parse uamserver: %s!", args_info.uamserver_arg); if (!args_info.forgiving_flag) goto end_processing; } if (!args_info.uamaliasname_arg || strncmp(args_info.uamaliasname_arg, hostname, strlen(args_info.uamaliasname_arg))) { if (!(host = gethostbyname(hostname))) { log_err(0, "Could not resolve IP address of uamserver: %s!", args_info.uamserver_arg); } else { int j = 0; pass_through pt; memset(&pt, 0, sizeof(pt)); pt.port = uamserverport; pt.mask.s_addr = ~0; while (host->h_addr_list[j] != NULL) { if (_options.debug & DEBUG_CONF) { log_dbg("Uamserver IP address #%d: %s\n", j, inet_ntoa(*(struct in_addr*) host->h_addr_list[j])); } pt.host.s_addr = ((struct in_addr*) host->h_addr_list[j++])->s_addr; if (pass_through_add(_options.pass_throughs, MAX_PASS_THROUGHS, &_options.num_pass_throughs, &pt, 0 #ifdef HAVE_PATRICIA , 0 #endif )) log_err(0, "Too many pass-throughs! skipped %s:%d", inet_ntoa(pt.host), pt.port); } } } } _options.uamanydns = args_info.uamanydns_flag; #ifdef ENABLE_UAMANYIP _options.uamanyip = args_info.uamanyip_flag; _options.uamnatanyip = args_info.uamnatanyip_flag; #endif _options.dnsparanoia = args_info.dnsparanoia_flag; _options.radiusoriginalurl = args_info.radiusoriginalurl_flag; _options.routeonetone = args_info.routeonetone_flag; #ifdef HAVE_PATRICIA _options.patricia = args_info.patricia_flag; #endif #ifdef ENABLE_GARDENACCOUNTING _options.nousergardendata = args_info.nousergardendata_flag; _options.uamgardendata = args_info.uamgardendata_flag; _options.uamotherdata = args_info.uamotherdata_flag; #endif for (numargs = 0; numargs < args_info.uamallowed_given; ++numargs) { pass_throughs_from_string(_options.pass_throughs, MAX_PASS_THROUGHS, &_options.num_pass_throughs, args_info.uamallowed_arg[numargs], 0, 0 #ifdef HAVE_PATRICIA , 0 #endif ); } #ifdef ENABLE_DHCPOPT _options.dhcp_options_len = 0; for (numargs = 0; numargs < args_info.dhcpopt_given; ++numargs) { unsigned char binopt[128]; int hex_length = strlen(args_info.dhcpopt_arg[numargs]); int bin_length = hex_length / 2; if (hex_length > 0 && (bin_length * 2) == hex_length && bin_length < sizeof(binopt)) { log_dbg("DHCP Options %s", args_info.dhcpopt_arg[numargs]); if (redir_hextochar((unsigned char *)args_info.dhcpopt_arg[numargs], hex_length, binopt, bin_length) == 0) { if (_options.dhcp_options_len + bin_length < sizeof(_options.dhcp_options)) { memcpy(_options.dhcp_options + _options.dhcp_options_len, binopt, bin_length); _options.dhcp_options_len += bin_length; } else { log_dbg("No room for DHCP option %d", (int)binopt[0]); } } else { log_dbg("Bad DHCP option hex encoding"); } } else { log_dbg("DHCP options are hex encoded binary"); } } #endif #ifdef ENABLE_MODULES memset(_options.modules, 0, sizeof(_options.modules)); for (numargs = 0; numargs < args_info.module_given; ++numargs) { if (numargs < MAX_MODULES) { char *n, *sc; int len, nlen; n = args_info.module_arg[numargs]; len = strlen(n); sc = strchr(n, ';'); if (!sc) sc = strchr(n, ':'); nlen = sc ? (sc - n) : len; safe_snprintf(_options.modules[numargs].name, sizeof(_options.modules[numargs].name), "%.*s", nlen, n); if (sc && len > (nlen + 1)) { safe_snprintf(_options.modules[numargs].conf, sizeof(_options.modules[numargs].conf), "%.*s", len - nlen - 1, sc + 1); } } } #endif #ifdef ENABLE_CHILLIREDIR /* for (numargs = 0; numargs < MAX_REGEX_PASS_THROUGHS; ++numargs) { if (_options.regex_pass_throughs[numargs].re_host.allocated) regfree(&_options.regex_pass_throughs[numargs].re_host); if (_options.regex_pass_throughs[numargs].re_path.allocated) regfree(&_options.regex_pass_throughs[numargs].re_path); if (_options.regex_pass_throughs[numargs].re_qs.allocated) regfree(&_options.regex_pass_throughs[numargs].re_qs); } */ memset(_options.regex_pass_throughs, 0, sizeof(_options.regex_pass_throughs)); _options.regex_num_pass_throughs = 0; for (numargs = 0; numargs < args_info.uamregex_given; ++numargs) { regex_pass_throughs_from_string(_options.regex_pass_throughs, MAX_REGEX_PASS_THROUGHS, &_options.regex_num_pass_throughs, args_info.uamregex_arg[numargs], 0); } #endif for (numargs = 0; numargs < MAX_UAM_DOMAINS; ++numargs) { if (_options.uamdomains[numargs]) free(_options.uamdomains[numargs]); _options.uamdomains[numargs] = 0; } if (args_info.uamdomain_given) { for (numargs = 0, i=0; numargs < args_info.uamdomain_given && i < MAX_UAM_DOMAINS; ++numargs) { char *tb = args_info.uamdomain_arg[numargs]; char *tok, *str, *ptr; for (str = tb ; i < MAX_UAM_DOMAINS; str = NULL) { tok = strtok_r(str, ",", &ptr); if (!tok) break; log_dbg("uamdomain %s", tok); _options.uamdomains[i++] = STRDUP(tok); } } } _options.allowdyn = 1; #ifdef ENABLE_UAMANYIP _options.autostatip = args_info.autostatip_arg; if (_options.autostatip) _options.uamanyip = 1; #endif if (args_info.nodynip_flag) { _options.allowdyn = 0; } else { if (!args_info.dynip_arg) { _options.dynip = STRDUP(args_info.net_arg); } else { struct in_addr addr; struct in_addr mask; _options.dynip = STRDUP(args_info.dynip_arg); if (option_aton(&addr, &mask, _options.dynip, 0)) { log_err(0, "Failed to parse dynamic IP address pool!"); if (!args_info.forgiving_flag) goto end_processing; } } } /* statip */ if (args_info.statip_arg) { struct in_addr addr; struct in_addr mask; _options.statip = STRDUP(args_info.statip_arg); if (option_aton(&addr, &mask, _options.statip, 0)) { log_err(0, "Failed to parse static IP address pool!"); return -1; } _options.allowstat = 1; } else { _options.allowstat = 0; } #ifdef ENABLE_UAMANYIP if (args_info.uamnatanyipex_arg) { if (option_aton(&_options.uamnatanyipex_addr, &_options.uamnatanyipex_mask, args_info.uamnatanyipex_arg, 0)) { log_err(0, "Failed to parse uamnatanyipex network!"); return -1; } } if (args_info.uamanyipex_arg) { if (option_aton(&_options.uamanyipex_addr, &_options.uamanyipex_mask, args_info.uamanyipex_arg, 0)) { log_err(0, "Failed to parse uamanyipex network!"); return -1; } } #endif if (args_info.dns1_arg) { if (!inet_aton(args_info.dns1_arg, &_options.dns1)) { log_err(0,"Invalid primary DNS address: %s!", args_info.dns1_arg); if (!args_info.forgiving_flag) goto end_processing; } } else if (_res.nscount >= 1) { _options.dns1 = _res.nsaddr_list[0].sin_addr; } else { _options.dns1.s_addr = 0; } if (args_info.dns2_arg) { if (!inet_aton(args_info.dns2_arg, &_options.dns2)) { log_err(0,"Invalid secondary DNS address: %s!", args_info.dns1_arg); if (!args_info.forgiving_flag) goto end_processing; } } else if (_res.nscount >= 2) { _options.dns2 = _res.nsaddr_list[1].sin_addr; } else { _options.dns2.s_addr = _options.dns1.s_addr; } /* If no listen option is specified listen to any local port */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.radiuslisten_arg) { if (!(host = gethostbyname(args_info.radiuslisten_arg))) { log_err(0, "Invalid listening address: %s! [%s]", args_info.radiuslisten_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.radiuslisten.s_addr, host->h_addr, host->h_length); } } else { _options.radiuslisten.s_addr = htonl(INADDR_ANY); } #ifdef ENABLE_NETNAT if (args_info.natip_arg) { if (!(host = gethostbyname(args_info.natip_arg))) { log_warn(0, "Invalid natip address: %s! [%s]", args_info.natip_arg, strerror(errno)); } else { memcpy(&_options.natip.s_addr, host->h_addr, host->h_length); } } #endif if (args_info.uamlogoutip_arg) { if (!(host = gethostbyname(args_info.uamlogoutip_arg))) { log_warn(0, "Invalid uamlogoutup address: %s! [%s]", args_info.uamlogoutip_arg, strerror(errno)); } else { memcpy(&_options.uamlogout.s_addr, host->h_addr, host->h_length); } } if (args_info.uamaliasip_arg) { if (!(host = gethostbyname(args_info.uamaliasip_arg))) { log_warn(0, "Invalid uamaliasip address: %s! [%s]", args_info.uamlogoutip_arg, strerror(errno)); } else { memcpy(&_options.uamalias.s_addr, host->h_addr, host->h_length); } } if (args_info.postauthproxy_arg) { if (!(host = gethostbyname(args_info.postauthproxy_arg))) { log_warn(0, "Invalid postauthproxy address: %s! [%s]", args_info.postauthproxy_arg, strerror(errno)); } else { memcpy(&_options.postauth_proxyip.s_addr, host->h_addr, host->h_length); } } /* If no option is specified terminate */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.radiusserver1_arg) { if (!(host = gethostbyname(args_info.radiusserver1_arg))) { log_err(0, "Invalid radiusserver1 address: %s! [%s]", args_info.radiusserver1_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.radiusserver1.s_addr, host->h_addr, host->h_length); } } else { log_err(0,"No radiusserver1 address given!"); if (!args_info.forgiving_flag) goto end_processing; } /* radiusserver2 */ /* If no option is specified terminate */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.radiusserver2_arg) { if (!(host = gethostbyname(args_info.radiusserver2_arg))) { log_err(0, "Invalid radiusserver2 address: %s! [%s]", args_info.radiusserver2_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.radiusserver2.s_addr, host->h_addr, host->h_length); } } else { _options.radiusserver2.s_addr = 0; } /* If no listen option is specified listen to any local port */ /* Do hostname lookup to translate hostname to IP address */ if (args_info.proxylisten_arg) { #ifdef ENABLE_RADPROXY if (!(host = gethostbyname(args_info.proxylisten_arg))) { log_err(0, "Invalid listening address: %s! [%s]", args_info.proxylisten_arg, strerror(errno)); if (!args_info.forgiving_flag) goto end_processing; } else { memcpy(&_options.proxylisten.s_addr, host->h_addr, host->h_length); } } else { _options.proxylisten.s_addr = htonl(INADDR_ANY); #elif (_debug_) log_warn(0,"radproxy not implemented. build with --enable-radproxy"); #endif } /* Store proxyclient as in_addr net and mask */ if (args_info.proxyclient_arg) { #ifdef ENABLE_RADPROXY if(option_aton(&_options.proxyaddr, &_options.proxymask, args_info.proxyclient_arg, 0)) { log_err(0,"Invalid proxy client address: %s!", args_info.proxyclient_arg); if (!args_info.forgiving_flag) goto end_processing; } } else { _options.proxyaddr.s_addr = ~0; /* Let nobody through */ _options.proxymask.s_addr = 0; #elif (_debug_) log_warn(0,"radproxy not implemented. build with --enable-radproxy"); #endif } memset(_options.macok, 0, sizeof(_options.macok)); _options.macoklen = 0; for (numargs = 0; numargs < args_info.macallowed_given; ++numargs) { char *p1 = NULL; char *p2 = NULL; char *p3 = malloc(strlen(args_info.macallowed_arg[numargs])+1); int i; unsigned int mac[6]; log_dbg("Macallowed #%d: %s", numargs, args_info.macallowed_arg[numargs]); strcpy(p3, args_info.macallowed_arg[numargs]); p1 = p3; if ((p2 = strchr(p1, ','))) { *p2 = '\0'; } while (p1) { if (_options.macoklen>=MACOK_MAX) { log_err(0,"Too many addresses in macallowed %s!", args_info.macallowed_arg); } else { /* Replace anything but hex and comma with space */ for (i=0; i<strlen(p1); i++) if (!isxdigit((int) p1[i])) p1[i] = 0x20; if (sscanf (p1, "%2x %2x %2x %2x %2x %2x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 6) { log_err(0, "Failed to convert macallowed option to MAC Address"); } else { log_dbg("Macallowed address #%d: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X", _options.macoklen, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); for (i = 0; i < 6; i++) _options.macok[_options.macoklen][i] = (unsigned char) mac[i]; _options.macoklen++; } } if (p2) { p1 = p2+1; if ((p2 = strchr(p1, ','))) { *p2 = 0; } } else { p1 = NULL; } } free(p3); } /** string parameters **/ #ifdef HAVE_SSL _options.sslkeyfile = STRDUP(args_info.sslkeyfile_arg); _options.sslkeypass = STRDUP(args_info.sslkeypass_arg); _options.sslcertfile = STRDUP(args_info.sslcertfile_arg); _options.sslcafile = STRDUP(args_info.sslcafile_arg); #endif #ifdef USING_IPC_UNIX _options.unixipc = STRDUP(args_info.unixipc_arg); #endif #ifdef HAVE_NETFILTER_COOVA _options.kname = STRDUP(args_info.kname_arg); #endif #ifdef ENABLE_DNSLOG _options.dnslog = STRDUP(args_info.dnslog_arg); #else if (args_info.dnslog_arg) log_err(0, "option dnslog given when no support built-in"); #endif #ifdef ENABLE_IPWHITELIST _options.ipwhitelist = STRDUP(args_info.ipwhitelist_arg); #else if (args_info.ipwhitelist_arg) log_err(0, "option ipwhitelist given when no support built-in"); #endif #ifdef ENABLE_UAMDOMAINFILE _options.uamdomainfile = STRDUP(args_info.uamdomainfile_arg); #else if (args_info.uamdomainfile_arg) log_err(0, "option uamdomainfile given when no support built-in"); #endif #ifdef ENABLE_MODULES _options.moddir = STRDUP(args_info.moddir_arg); #else if (args_info.moddir_arg) log_err(0, "option moddir given when no support built-in"); #endif #ifdef ENABLE_RADPROXY if (!args_info.proxysecret_arg) { _options.proxysecret = STRDUP(args_info.radiussecret_arg); } else { _options.proxysecret = STRDUP(args_info.proxysecret_arg); } #endif #ifdef ENABLE_REDIRINJECT _options.inject = STRDUP(args_info.inject_arg); _options.inject_ext = STRDUP(args_info.injectext_arg); _options.inject_wispr = args_info.injectwispr_flag; #endif #ifdef ENABLE_EXTADMVSA if (args_info.extadmvsa_given) { for (numargs = 0; numargs < args_info.extadmvsa_given && numargs < EXTADMVSA_ATTR_CNT; ++numargs) { int len = strlen(args_info.extadmvsa_arg[numargs]); if (len > 0 && len < 256) { unsigned int i[2]; char s[256]; if (sscanf(args_info.extadmvsa_arg[numargs], "%u,%u:%s", &i[0], &i[1], s) == 3) { char *idx = strchr(s, ':'); _options.extadmvsa[numargs].attr_vsa = i[0]; _options.extadmvsa[numargs].attr = i[1]; if (idx) *idx = 0; safe_strncpy(_options.extadmvsa[numargs].script, s, sizeof(_options.extadmvsa[numargs].script)-1); if (idx) { safe_strncpy(_options.extadmvsa[numargs].data, idx + 1, sizeof(_options.extadmvsa[numargs].data)-1); } } else if (sscanf(args_info.extadmvsa_arg[numargs], "%u:%s", &i[0], s) == 2) { char *idx = strchr(s, ':'); _options.extadmvsa[numargs].attr = i[0]; if (idx) *idx = 0; safe_strncpy(_options.extadmvsa[numargs].script, s, sizeof(_options.extadmvsa[numargs].script)-1); if (idx) { safe_strncpy(_options.extadmvsa[numargs].data, idx + 1, sizeof(_options.extadmvsa[numargs].data)-1); } } else { log_err(0, "invalid input %s", args_info.extadmvsa_arg[numargs]); } } log_dbg("Extended admin-user attr (%d/%d) data=%s script=%s", (int)_options.extadmvsa[numargs].attr_vsa, (int)_options.extadmvsa[numargs].attr, _options.extadmvsa[numargs].data, _options.extadmvsa[numargs].script); } } #endif _options.peerkey = STRDUP(args_info.peerkey_arg); _options.routeif = STRDUP(args_info.routeif_arg); _options.wwwdir = STRDUP(args_info.wwwdir_arg); _options.wwwbin = STRDUP(args_info.wwwbin_arg); _options.uamui = STRDUP(args_info.uamui_arg); _options.localusers = STRDUP(args_info.localusers_arg); _options.uamurl = STRDUP(args_info.uamserver_arg); _options.uamaaaurl = STRDUP(args_info.uamaaaurl_arg); _options.uamhomepage = STRDUP(args_info.uamhomepage_arg); _options.wisprlogin = STRDUP(args_info.wisprlogin_arg); _options.uamsecret = STRDUP(args_info.uamsecret_arg); _options.macsuffix = STRDUP(args_info.macsuffix_arg); _options.macpasswd = STRDUP(args_info.macpasswd_arg); _options.adminuser = STRDUP(args_info.adminuser_arg); _options.adminpasswd = STRDUP(args_info.adminpasswd_arg); _options.adminupdatefile = STRDUP(args_info.adminupdatefile_arg); _options.rtmonfile = STRDUP(args_info.rtmonfile_arg); _options.ssid = STRDUP(args_info.ssid_arg); _options.vlan = STRDUP(args_info.vlan_arg); _options.nasmac = STRDUP(args_info.nasmac_arg); _options.nasip = STRDUP(args_info.nasip_arg); _options.tundev = STRDUP(args_info.tundev_arg); _options.radiusnasid = STRDUP(args_info.radiusnasid_arg); _options.radiuslocationid = STRDUP(args_info.radiuslocationid_arg); _options.radiuslocationname = STRDUP(args_info.radiuslocationname_arg); _options.locationname = STRDUP(args_info.locationname_arg); _options.radiussecret = STRDUP(args_info.radiussecret_arg); #ifdef ENABLE_LARGELIMITS /*_options.radiusacctsecret = STRDUP(args_info.radiusacctsecret_arg); _options.radiusadmsecret = STRDUP(args_info.radiusadmsecret_arg);*/ #endif _options.cmdsocket = STRDUP(args_info.cmdsocket_arg); _options.cmdsocketport = args_info.cmdsocketport_arg; _options.domain = STRDUP(args_info.domain_arg); _options.ipup = STRDUP(args_info.ipup_arg); _options.ipdown = STRDUP(args_info.ipdown_arg); _options.conup = STRDUP(args_info.conup_arg); _options.condown = STRDUP(args_info.condown_arg); _options.macup = STRDUP(args_info.macup_arg); _options.macdown = STRDUP(args_info.macdown_arg); _options.pidfile = STRDUP(args_info.pidfile_arg); _options.statedir = STRDUP(args_info.statedir_arg); _options.usestatusfile = STRDUP(args_info.usestatusfile_arg); _options.uamaliasname = STRDUP(args_info.uamaliasname_arg); _options.uamhostname = STRDUP(args_info.uamhostname_arg); _options.binconfig = STRDUP(args_info.bin_arg); _options.ethers = STRDUP(args_info.ethers_arg); #ifdef ENABLE_IEEE8021Q _options.ieee8021q = args_info.ieee8021q_flag; _options.ieee8021q_only = args_info.only8021q_flag; _options.vlanupdate = STRDUP(args_info.vlanupdate_arg); #endif #ifdef ENABLE_PROXYVSA _options.locationupdate = STRDUP(args_info.locationupdate_arg); #endif #ifdef EX_OPT_MAIN #include EX_OPT_MAIN #endif ret = 0; if (_options.binconfig) { /* save out the configuration */ bstring bt = bfromcstr(""); int ok = options_save(_options.binconfig, bt); if (!ok) log_err(0, "could not save configuration options!"); bdestroy(bt); } if (args_info.reload_flag) { if (execl(SBINDIR "/chilli_query", "chilli_query", args_info.cmdsocket_arg, "reload", (char *) 0) != 0) { log_err(errno, "execl() did not return 0!"); exit(2); } } end_processing: cmdline_parser_free (&args_info); return ret; }
int pass_throughs_from_string(pass_through *ptlist, uint32_t ptlen, uint32_t *ptcnt, char *s, char is_dyn, char is_rem #ifdef HAVE_PATRICIA , patricia_tree_t *ptree #endif ) { struct hostent *host; pass_through pt; char *t, *p1 = NULL, *p2 = NULL; char *p3; if (!s || strlen(s) == 0) return 0; p3 = malloc(strlen(s)+1); strcpy(p3, s); p1 = p3; if (_options.debug) syslog(LOG_DEBUG, "Uamallowed [%s]", s); for ( ; p1; p1 = p2) { /* save the next entry position */ if ((p2 = strchr(p1, ','))) { *p2=0; p2++; } /* clear the pass-through entry in case we partitially filled it already */ memset(&pt, 0, sizeof(pass_through)); /* eat whitespace */ while (isspace((int) *p1)) p1++; /* look for specific protocols */ if ((t = strchr(p1, ':'))) { int pnum = 0; *t = 0; #ifdef HAVE_GETPROTOENT if (1) { struct protoent *proto = getprotobyname(p1); if (!proto && !strchr(p1, '.')) proto = getprotobynumber(atoi(p1)); if (proto) pnum = proto->p_proto; } #else if (!strcmp(p1,"tcp")) { pnum = 6; } else if (!strcmp(p1,"udp")) { pnum = 17; } else if (!strcmp(p1,"icmp")) { pnum = 1; } #endif if (pnum > 0) { /* if a protocol, skip ahead */ pt.proto = pnum; p1 = t + 1; } else { /* if not a protocol, put the ':' back */ *t = ':'; } } #ifdef ENABLE_GARDENEXT { char *e = strchr(p1, '#'); if (e) { int add = atoi(e+1); pt.expiry = mainclock_now() + add; *e = 0; } } #endif /* look for an optional port */ if ((t = strchr(p1, ':'))) { pt.port = atoi(t+1); *t = 0; } if (strchr(p1, '/')) { /* parse a network address */ if (option_aton(&pt.host, &pt.mask, p1, 0)) { syslog(LOG_ERR, "Invalid uamallowed network address or mask %s!", s); continue; } if (is_rem) { if (pass_through_rem(ptlist, ptcnt, &pt #ifdef HAVE_PATRICIA , ptree #endif )) syslog(LOG_ERR, "Too many pass-throughs! skipped %s", s); } else { if (pass_through_add(ptlist, ptlen, ptcnt, &pt, is_dyn #ifdef HAVE_PATRICIA , ptree #endif )) syslog(LOG_ERR, "Too many pass-throughs! skipped %s", s); } } else { /* otherwise, parse a host ip or hostname */ int j = 0; pt.mask.s_addr = 0xffffffff; if (!(host = gethostbyname(p1))) { syslog(LOG_ERR, "%s: Invalid uamallowed domain or address: %s!", strerror(errno), p1); continue; } while (host->h_addr_list[j] != NULL) { pt.host = *((struct in_addr *) host->h_addr_list[j++]); if (is_rem) { if (pass_through_rem(ptlist, ptcnt, &pt #ifdef HAVE_PATRICIA , ptree #endif )) syslog(LOG_ERR, "Too many pass-throughs! skipped %s", s); } else { if (pass_through_add(ptlist, ptlen, ptcnt, &pt, is_dyn #ifdef HAVE_PATRICIA , ptree #endif )) syslog(LOG_ERR, "Too many pass-throughs! skipped %s", s); } } } } free(p3); return 0; }