/* * Helper for iptables_fw_destroy * @param table The table to search * @param chain The chain in that table to search * @param mention A word to find and delete in rules in the given table+chain */ int iptables_fw_destroy_mention( const char * table, const char * chain, const char * mention ) { FILE *p = NULL; char *command = NULL; char *command2 = NULL; char line[MAX_BUF]; char rulenum[10]; char *victim = safe_strdup(mention); int deleted = 0; iptables_insert_gateway_id(&victim); debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", victim, table, chain); safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain); iptables_insert_gateway_id(&command); if ((p = popen(command, "r"))) { /* Skip first 2 lines */ while (!feof(p) && fgetc(p) != '\n'); while (!feof(p) && fgetc(p) != '\n'); /* Loop over entries */ while (fgets(line, sizeof(line), p)) { /* Look for victim */ if (strstr(line, victim)) { /* Found victim - Get the rule number into rulenum*/ if (sscanf(line, "%9[0-9]", rulenum) == 1) { /* Delete the rule: */ debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, victim); safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); iptables_do_command(command2); free(command2); deleted = 1; /* Do not keep looping - the captured rulenums will no longer be accurate */ break; } } } pclose(p); } free(command); free(victim); if (deleted) { /* Recurse just in case there are more in the same table+chain */ iptables_fw_destroy_mention(table, chain, mention); } return (deleted); }
/* * Helper for iptables_fw_destroy * @param table The table to search * @param chain The chain in that table to search * @param mention A word to find and delete in rules in the given table+chain */ int iptables_fw_destroy_mention( const char *table, const char *chain, const char *mention ) { s_config *config; char *iptables; FILE *p = NULL; char *command = NULL; char *command2 = NULL; char line[MAX_BUF]; char rulenum[10]; int retval = -1; debug(LOG_DEBUG, "Checking all mention of %s from %s.%s", mention, table, chain); config = config_get_config(); iptables = config->ip6 ? "ip6tables" : "iptables"; safe_asprintf(&command, "%s -t %s -L %s -n --line-numbers -v", iptables, table, chain); if ((p = popen(command, "r"))) { /* Skip first 2 lines */ while (!feof(p) && fgetc(p) != '\n'); while (!feof(p) && fgetc(p) != '\n'); /* Loop over entries */ while (fgets(line, sizeof(line), p)) { /* Look for mention */ if (strstr(line, mention)) { /* Found mention - Get the rule number into rulenum*/ if (sscanf(line, "%9[0-9]", rulenum) == 1) { /* Delete the rule: */ debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, mention); safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); iptables_do_command(command2); free(command2); retval = 0; /* Do not keep looping - the captured rulenums will no longer be accurate */ break; } } } pclose(p); } free(command); if (retval == 0) { /* Recurse just in case there are more in the same table+chain */ iptables_fw_destroy_mention(table, chain, mention); } return (retval); }
/** Set if a specific client has access through the firewall */ int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag) { int rc; fw_quiet = 0; // add by lijg, 2013-06-04, char tmpip[16]; snprintf(tmpip, sizeof(tmpip), "%s ", ip); switch(type) { case FW_ACCESS_ALLOW: // add by lijg, 2013-05-18, 尝试删除重复添加的规则 debug(LOG_DEBUG, "Attempt deleting firewall rules for (%s) in table %s", tmpip, TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, tmpip); debug(LOG_DEBUG, "Attempt deleting firewall rules for (%s) in table %s", tmpip, TABLE_WIFIDOG_INCOMING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, tmpip); // modified by lijg, 2013-05-17, 取消打标记 iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --or-mark %d", ip, mac, tag); rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); break; case FW_ACCESS_DENY: // modified by lijg, 2013-05-17, 取消打标记 debug(LOG_DEBUG, "Attempt S deleting firewall rules for (%s) in table %s", tmpip, TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, tmpip); debug(LOG_DEBUG, "Attempt S deleting firewall rules for (%s) in table %s", tmpip, TABLE_WIFIDOG_INCOMING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, tmpip); rc = 0; break; default: rc = -1; break; } return rc; }
/** Remove the firewall rules * This is used when we do a clean shutdown of WiFiDog and when it starts to make * sure there are no rules left over */ int iptables_fw_destroy(void) { int got_authdown_ruleset = 0;//NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1; fw_quiet = 1; debug(LOG_DEBUG, "Destroying our iptables entries"); /* * * Everything in the MANGLE table * */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING); iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING); iptables_do_command("-t mangle -F " CHAIN_TRUSTED); iptables_do_command("-t mangle -F " CHAIN_OUTGOING); iptables_do_command("-t mangle -F " CHAIN_INCOMING); iptables_do_command("-t mangle -X " CHAIN_TRUSTED); iptables_do_command("-t mangle -X " CHAIN_OUTGOING); iptables_do_command("-t mangle -X " CHAIN_INCOMING); /* * * Everything in the NAT table * */ debug(LOG_DEBUG, "Destroying chains in the NAT table"); iptables_fw_destroy_mention("nat", "PREROUTING", CHAIN_OUTGOING); iptables_do_command("-t nat -F " CHAIN_AUTHSERVERS); iptables_do_command("-t nat -F " CHAIN_OUTGOING); iptables_do_command("-t nat -F " CHAIN_TO_ROUTER); iptables_do_command("-t nat -F " CHAIN_TO_INTERNET); iptables_do_command("-t nat -F " CHAIN_GLOBAL); iptables_do_command("-t nat -F " CHAIN_UNKNOWN); iptables_do_command("-t nat -X " CHAIN_AUTHSERVERS); iptables_do_command("-t nat -X " CHAIN_OUTGOING); iptables_do_command("-t nat -X " CHAIN_TO_ROUTER); iptables_do_command("-t nat -X " CHAIN_TO_INTERNET); iptables_do_command("-t nat -X " CHAIN_GLOBAL); iptables_do_command("-t nat -X " CHAIN_UNKNOWN); /* * * Everything in the FILTER table * */ debug(LOG_DEBUG, "Destroying chains in the FILTER table"); iptables_fw_destroy_mention("filter", "FORWARD", CHAIN_TO_INTERNET); iptables_do_command("-t filter -F " CHAIN_TO_INTERNET); iptables_do_command("-t filter -F " CHAIN_AUTHSERVERS); iptables_do_command("-t filter -F " CHAIN_LOCKED); iptables_do_command("-t filter -F " CHAIN_GLOBAL); iptables_do_command("-t filter -F " CHAIN_VALIDATE); iptables_do_command("-t filter -F " CHAIN_KNOWN); iptables_do_command("-t filter -F " CHAIN_UNKNOWN); iptables_do_command("-t filter -X " CHAIN_TO_INTERNET); iptables_do_command("-t filter -X " CHAIN_AUTHSERVERS); iptables_do_command("-t filter -X " CHAIN_LOCKED); iptables_do_command("-t filter -X " CHAIN_GLOBAL); iptables_do_command("-t filter -X " CHAIN_VALIDATE); iptables_do_command("-t filter -X " CHAIN_KNOWN); iptables_do_command("-t filter -X " CHAIN_UNKNOWN); return 1; }
/** Update the counters of all the clients in the client list */ int iptables_fw_counters_update(void) { FILE *output; char *script, ip[16], rc; unsigned long long int counter; t_client *p1; struct in_addr tempaddr; debug(LOG_DEBUG, "begin iptables_fw_counters_update"); /* Look for outgoing traffic */ // modified by lijg , 2013-05-18, 修改获取上行流量 safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING); iptables_insert_gateway_id(&script); output = popen(script, "r"); free(script); if (!output) { debug(LOG_ERR, "popen(): %s", strerror(errno)); return -1; } /* skip the first two lines */ while (('\n' != fgetc(output)) && !feof(output)) ; while (('\n' != fgetc(output)) && !feof(output)) ; while (output && !(feof(output))) { rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); //debug(LOG_DEBUG, "outgoing >> %s -- %llu (%u)", ip, counter, rc); if (2 == rc && EOF != rc) { /* Sanity*/ if (!inet_aton(ip, &tempaddr)) { debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); continue; } debug(LOG_DEBUG, "Read outgoing traffic for %s: Bytes=%llu", ip, counter); LOCK_CLIENT_LIST(); if ((p1 = client_list_find_by_ip(ip))) { if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { p1->counters.outgoing = p1->counters.outgoing_history + counter; p1->counters.last_updated = time(NULL); debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes. Updated last_updated to %d", ip, counter, p1->counters.last_updated); } } else { debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); } UNLOCK_CLIENT_LIST(); } } pclose(output); /* Look for incoming traffic */ safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING); iptables_insert_gateway_id(&script); output = popen(script, "r"); free(script); if (!output) { debug(LOG_ERR, "popen(): %s", strerror(errno)); return -1; } /* skip the first two lines */ while (('\n' != fgetc(output)) && !feof(output)) ; while (('\n' != fgetc(output)) && !feof(output)) ; while (output && !(feof(output))) { rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); if (2 == rc && EOF != rc) { /* Sanity*/ if (!inet_aton(ip, &tempaddr)) { debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); continue; } debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter); LOCK_CLIENT_LIST(); if ((p1 = client_list_find_by_ip(ip))) { if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { p1->counters.incoming = p1->counters.incoming_history + counter; debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); } } else { debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); } UNLOCK_CLIENT_LIST(); } } pclose(output); debug(LOG_DEBUG, "end iptables_fw_counters_update\n\n"); return 1; }
int iptables_fw_destroy(void) { fw_quiet = 1; debug(LOG_DEBUG, "Destroying our iptables entries"); /* * * Everything in the MANGLE table * */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); // 清除自定义链中的规则 // modified by lijg, 2013-05-17 //iptables_fw_destroy_mention("mangle", "FORWARD", TABLE_WIFIDOG_TRUSTED); //iptables_fw_destroy_mention("mangle", "FORWARD", TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING); // 清除自定义的链 // modified by lijg, 2013-05-17 //iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); //iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); /* * * Everything in the NAT table * */ debug(LOG_DEBUG, "Destroying chains in the NAT table"); iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); // add by lijg, 2013-08-14, clear white list chain iptables_do_command("-t nat -F " TABLE_WIFIDOG_WLIST); iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); // add by lijg, 2013-08-14, clear white list chain iptables_do_command("-t nat -X " TABLE_WIFIDOG_WLIST); /* * * Everything in the FILTER table * */ debug(LOG_DEBUG, "Destroying chains in the FILTER table"); iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); // add by lijg, 2013-08-14, clear white list chain iptables_do_command("-t filter -F " TABLE_WIFIDOG_WLIST); iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); // add by lijg, 2013-08-14, clear white list chain iptables_do_command("-t filter -X " TABLE_WIFIDOG_WLIST); return 1; }
/** Remove the firewall rules * This is used when we do a clean shutdown of nodogsplash, * and when it starts, to make sure there are no rules left over from a crash */ int iptables_fw_destroy(void) { fw_quiet = 1; debug(LOG_DEBUG, "Destroying our tc hooks"); tc_destroy_tc(); debug(LOG_DEBUG, "Destroying our iptables entries"); /* * * Everything in the mangle table * */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_BLOCKED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_ALLOWED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING); iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING); iptables_do_command("-t mangle -F " CHAIN_TRUSTED); iptables_do_command("-t mangle -F " CHAIN_BLOCKED); iptables_do_command("-t mangle -F " CHAIN_ALLOWED); iptables_do_command("-t mangle -F " CHAIN_OUTGOING); iptables_do_command("-t mangle -F " CHAIN_INCOMING); iptables_do_command("-t mangle -X " CHAIN_TRUSTED); iptables_do_command("-t mangle -X " CHAIN_BLOCKED); iptables_do_command("-t mangle -X " CHAIN_ALLOWED); iptables_do_command("-t mangle -X " CHAIN_OUTGOING); iptables_do_command("-t mangle -X " CHAIN_INCOMING); /* * * Everything in the nat table * */ debug(LOG_DEBUG, "Destroying chains in the NAT table"); iptables_fw_destroy_mention("nat", "PREROUTING", CHAIN_OUTGOING); iptables_do_command("-t nat -F " CHAIN_OUTGOING); iptables_do_command("-t nat -X " CHAIN_OUTGOING); /* * * Everything in the filter table * */ debug(LOG_DEBUG, "Destroying chains in the FILTER table"); iptables_fw_destroy_mention("filter", "INPUT", CHAIN_TO_ROUTER); iptables_fw_destroy_mention("filter", "FORWARD", CHAIN_TO_INTERNET); iptables_do_command("-t filter -F " CHAIN_TO_ROUTER); iptables_do_command("-t filter -F " CHAIN_TO_INTERNET); iptables_do_command("-t filter -F " CHAIN_AUTHENTICATED); iptables_do_command("-t filter -F " CHAIN_TRUSTED); iptables_do_command("-t filter -F " CHAIN_TRUSTED_TO_ROUTER); iptables_do_command("-t filter -X " CHAIN_TO_ROUTER); iptables_do_command("-t filter -X " CHAIN_TO_INTERNET); iptables_do_command("-t filter -X " CHAIN_AUTHENTICATED); iptables_do_command("-t filter -X " CHAIN_TRUSTED); iptables_do_command("-t filter -X " CHAIN_TRUSTED_TO_ROUTER); return 0; }
/** Remove the firewall rules * This is used when we do a clean shutdown of nodogsplash, * and when it starts, to make sure there are no rules left over from a crash */ int iptables_fw_destroy(void) { fw_quiet = 1; s_config *config; int traffic_control; LOCK_CONFIG(); config = config_get_config(); traffic_control = config->traffic_control; UNLOCK_CONFIG(); if (traffic_control) { debug(LOG_DEBUG, "Destroying our tc hooks"); tc_destroy_tc(); } debug(LOG_DEBUG, "Destroying our iptables entries"); /* Everything in the mangle table */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_BLOCKED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_ALLOWED); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING); iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING); iptables_do_command("-t mangle -F " CHAIN_TRUSTED); iptables_do_command("-t mangle -F " CHAIN_BLOCKED); iptables_do_command("-t mangle -F " CHAIN_ALLOWED); iptables_do_command("-t mangle -F " CHAIN_OUTGOING); iptables_do_command("-t mangle -F " CHAIN_INCOMING); iptables_do_command("-t mangle -X " CHAIN_TRUSTED); iptables_do_command("-t mangle -X " CHAIN_BLOCKED); iptables_do_command("-t mangle -X " CHAIN_ALLOWED); iptables_do_command("-t mangle -X " CHAIN_OUTGOING); iptables_do_command("-t mangle -X " CHAIN_INCOMING); /* Everything in the nat table (ip4 only) */ if (!config->ip6) { debug(LOG_DEBUG, "Destroying chains in the NAT table"); iptables_fw_destroy_mention("nat", "PREROUTING", CHAIN_OUTGOING); iptables_do_command("-t nat -F " CHAIN_OUTGOING); iptables_do_command("-t nat -X " CHAIN_OUTGOING); } /* Everything in the filter table */ debug(LOG_DEBUG, "Destroying chains in the FILTER table"); iptables_fw_destroy_mention("filter", "INPUT", CHAIN_TO_ROUTER); iptables_fw_destroy_mention("filter", "FORWARD", CHAIN_TO_INTERNET); iptables_do_command("-t filter -F " CHAIN_TO_ROUTER); iptables_do_command("-t filter -F " CHAIN_TO_INTERNET); iptables_do_command("-t filter -F " CHAIN_AUTHENTICATED); iptables_do_command("-t filter -F " CHAIN_TRUSTED); iptables_do_command("-t filter -F " CHAIN_TRUSTED_TO_ROUTER); iptables_do_command("-t filter -X " CHAIN_TO_ROUTER); iptables_do_command("-t filter -X " CHAIN_TO_INTERNET); iptables_do_command("-t filter -X " CHAIN_AUTHENTICATED); iptables_do_command("-t filter -X " CHAIN_TRUSTED); iptables_do_command("-t filter -X " CHAIN_TRUSTED_TO_ROUTER); fw_quiet = 0; return 0; }
/** Update the counters of all the clients in the client list */ int iptables_fw_counters_update(void) { FILE *output; char *script, ip[16], rc, mac[18]; unsigned long long int counter; t_client *p1; struct in_addr tempaddr; const s_config *config = config_get_config(); /* Look for outgoing traffic */ safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " CHAIN_OUTGOING); iptables_insert_gateway_id(&script); output = popen(script, "r"); free(script); if (!output) { debug(LOG_ERR, "popen(): %s", strerror(errno)); return -1; } /* skip the first two lines */ while (('\n' != fgetc(output)) && !feof(output)) ; while (('\n' != fgetc(output)) && !feof(output)) ; while (output && !(feof(output))) { //3554 390634 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MAC C0:38:96:96:74:7D MARK set 0x3 /*rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip);*/ //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %17[0-9a-fA-F:] %*s %*s 0x%*u", &counter, ip, mac); if (3 == rc && EOF != rc) { /* Sanity */ if (!inet_aton(ip, &tempaddr)) { debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); continue; } debug(LOG_DEBUG, "Read outgoing traffic for %s(%s): Bytes=%llu", ip, mac, counter); LOCK_CLIENT_LIST(); if ((p1 = client_list_find_by_ip(ip))) { p1->counters.active_duration--; if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { p1->counters.outgoing_delta = p1->counters.outgoing_history + counter - p1->counters.outgoing; p1->counters.outgoing = p1->counters.outgoing_history + counter; p1->counters.last_updated = time(NULL); debug(LOG_DEBUG, "%s(%s) - Outgoing traffic %llu bytes, updated counter.outgoing to %llu bytes. Updated last_updated to %d", ip, mac, counter, p1->counters.outgoing, p1->counters.last_updated); } } else { debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s(%s) in client list, this should not happen unless if the gateway crashed", ip, mac); debug(LOG_ERR, "Preventively deleting firewall rules for %s(%s) in table %s", ip, mac, CHAIN_OUTGOING); iptables_fw_destroy_mention("mangle", CHAIN_OUTGOING, ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s(%s) in table %s", ip, mac, CHAIN_INCOMING); iptables_fw_destroy_mention("mangle", CHAIN_INCOMING, ip); } UNLOCK_CLIENT_LIST(); } } pclose(output); /* Look for incoming traffic */ safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " CHAIN_INCOMING); iptables_insert_gateway_id(&script); output = popen(script, "r"); free(script); if (!output) { debug(LOG_ERR, "popen(): %s", strerror(errno)); return -1; } /* skip the first two lines */ while (('\n' != fgetc(output)) && !feof(output)) ; while (('\n' != fgetc(output)) && !feof(output)) ; while (output && !(feof(output))) { rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); if (2 == rc && EOF != rc) { /* Sanity */ if (!inet_aton(ip, &tempaddr)) { debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); continue; } debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter); LOCK_CLIENT_LIST(); if ((p1 = client_list_find_by_ip(ip))) { if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { p1->counters.incoming_delta = p1->counters.incoming_history + counter - p1->counters.incoming; p1->counters.incoming = p1->counters.incoming_history + counter; debug(LOG_DEBUG, "%s - Incoming traffic %llu bytes, Updated counter.incoming to %llu bytes", ip, counter, p1->counters.incoming); } } else { debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, CHAIN_OUTGOING); iptables_fw_destroy_mention("mangle", CHAIN_OUTGOING, ip); debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, CHAIN_INCOMING); iptables_fw_destroy_mention("mangle", CHAIN_INCOMING, ip); } UNLOCK_CLIENT_LIST(); } } pclose(output); return 1; }
/** Remove the firewall rules * This is used when we do a clean shutdown of WiFiDog and when it starts to make * sure there are no rules left over */ int iptables_fw_destroy(void) { fw_quiet = 1; debug(LOG_DEBUG, "Destroying our iptables entries"); /* * * Everything in the MANGLE table * */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED); iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); /* * * Everything in the NAT table * */ debug(LOG_DEBUG, "Destroying chains in the NAT table"); iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_PORTALSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_PLATSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_SUBSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -X " TABLE_WIFIDOG_PORTALSERVERS); iptables_do_command("-t nat -X " TABLE_WIFIDOG_PLATSERVERS); iptables_do_command("-t nat -X " TABLE_WIFIDOG_SUBSERVERS); iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); /* * * Everything in the FILTER table * */ debug(LOG_DEBUG, "Destroying chains in the FILTER table"); iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -F " TABLE_WIFIDOG_PORTALSERVERS); iptables_do_command("-t filter -F " TABLE_WIFIDOG_PLATSERVERS); iptables_do_command("-t filter -F " TABLE_WIFIDOG_SUBSERVERS); iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -X " TABLE_WIFIDOG_PORTALSERVERS); iptables_do_command("-t filter -X " TABLE_WIFIDOG_PLATSERVERS); iptables_do_command("-t filter -X " TABLE_WIFIDOG_SUBSERVERS); iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); return 1; }