fw_iptables.c

00001 /********************************************************************\
00002  * This program is free software; you can redistribute it and/or    *
00003  * modify it under the terms of the GNU General Public License as   *
00004  * published by the Free Software Foundation; either version 2 of   *
00005  * the License, or (at your option) any later version.              *
00006  *                                                                  *
00007  * This program is distributed in the hope that it will be useful,  *
00008  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00010  * GNU General Public License for more details.                     *
00011  *                                                                  *
00012  * You should have received a copy of the GNU General Public License*
00013  * along with this program; if not, contact:                        *
00014  *                                                                  *
00015  * Free Software Foundation           Voice:  +1-617-542-5942       *
00016  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00017  * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
00018  *                                                                  *
00019  \********************************************************************/
00020 
00021 /* $Id: fw_iptables.c 1162 2007-01-06 23:51:02Z benoitg $ */
00028 #define _GNU_SOURCE
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <stdarg.h>
00033 #include <syslog.h>
00034 #include <errno.h>
00035 #include <string.h>
00036 #include <pthread.h>
00037 #include <sys/socket.h>
00038 #include <netinet/in.h>
00039 #include <arpa/inet.h>
00040 
00041 #include "common.h"
00042 
00043 #include "safe.h"
00044 #include "conf.h"
00045 #include "fw_iptables.h"
00046 #include "firewall.h"
00047 #include "debug.h"
00048 #include "util.h"
00049 #include "client_list.h"
00050 
00051 static int iptables_do_command(char *format, ...);
00052 static char *iptables_compile(char *, char *, t_firewall_rule *);
00053 static void iptables_load_ruleset(char *, char *, char *);
00054 
00055 extern pthread_mutex_t  client_list_mutex;
00056 extern pthread_mutex_t  config_mutex;
00057 
00060 static int fw_quiet = 0;
00061 
00063 static int
00064 iptables_do_command(char *format, ...)
00065 {
00066     va_list vlist;
00067     char *fmt_cmd,
00068         *cmd;
00069     int rc;
00070 
00071     va_start(vlist, format);
00072     safe_vasprintf(&fmt_cmd, format, vlist);
00073          va_end(vlist);
00074 
00075     safe_asprintf(&cmd, "iptables %s", fmt_cmd);
00076 
00077     free(fmt_cmd);
00078 
00079     debug(LOG_DEBUG, "Executing command: %s", cmd);
00080         
00081     rc = execute(cmd, fw_quiet);
00082 
00083     free(cmd);
00084 
00085     return rc;
00086 }
00087 
00096 static char *
00097 iptables_compile(char * table, char *chain, t_firewall_rule *rule)
00098 {
00099     char        command[MAX_BUF],
00100                 *mode;
00101     
00102     memset(command, 0, MAX_BUF);
00103     
00104     if (rule->block_allow == 1) {
00105         mode = safe_strdup("ACCEPT");
00106     } else {
00107         mode = safe_strdup("REJECT");
00108     }
00109     
00110     snprintf(command, sizeof(command),  "-t %s -A %s ",table, chain);
00111     if (rule->mask != NULL) {
00112         snprintf((command + strlen(command)), (sizeof(command) - 
00113                 strlen(command)), "-d %s ", rule->mask);
00114     }
00115     if (rule->protocol != NULL) {
00116         snprintf((command + strlen(command)), (sizeof(command) -
00117                 strlen(command)), "-p %s ", rule->protocol);
00118     }
00119     if (rule->port != NULL) {
00120         snprintf((command + strlen(command)), (sizeof(command) -
00121                 strlen(command)), "--dport %s ", rule->port);
00122     }
00123     snprintf((command + strlen(command)), (sizeof(command) - 
00124             strlen(command)), "-j %s", mode);
00125     
00126     free(mode);
00127 
00128     /* XXX The buffer command, an automatic variable, will get cleaned
00129      * off of the stack when we return, so we strdup() it. */
00130     return(safe_strdup(command));
00131 }
00132 
00140 static void
00141 iptables_load_ruleset(char * table, char *ruleset, char *chain)
00142 {
00143         t_firewall_rule         *rule;
00144         char                    *cmd;
00145 
00146         debug(LOG_DEBUG, "Load ruleset %s into table %s, chain %s", ruleset, table, chain);
00147         
00148         for (rule = get_ruleset(ruleset); rule != NULL; rule = rule->next) {
00149                 cmd = iptables_compile(table, chain, rule);
00150                 debug(LOG_DEBUG, "Loading rule \"%s\" into table %s, chain %s", cmd, table, chain);
00151                 iptables_do_command(cmd);
00152                 free(cmd);
00153         }
00154 
00155         debug(LOG_DEBUG, "Ruleset %s loaded into table %s, chain %s", ruleset, table, chain);
00156 }
00157 
00158 void
00159 iptables_fw_clear_authservers(void)
00160 {
00161     iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS);
00162     iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS);
00163 }
00164 
00165 void
00166 iptables_fw_set_authservers(void)
00167 {
00168     s_config *config;
00169     t_auth_serv *auth_server;
00170    
00171     config = config_get_config();
00172     
00173     for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {
00174             if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) {
00175                 iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);
00176                 iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);
00177             }
00178     }
00179 
00180 }
00181 
00184 int
00185 iptables_fw_init(void)
00186 {
00187     s_config *config;
00188          char * gw_interface = NULL;
00189          char * gw_address = NULL;
00190          char * ext_interface = NULL;
00191          int gw_port = 0;
00192      t_trusted_mac *p;
00193    
00194     fw_quiet = 0;
00195 
00196          LOCK_CONFIG();
00197     config = config_get_config();
00198          gw_interface = safe_strdup(config->gw_interface);
00199          gw_address = safe_strdup(config->gw_address);
00200          gw_port = config->gw_port;
00201      if (config->external_interface) {
00202             ext_interface = safe_strdup(config->external_interface);
00203      } else {
00204             ext_interface = get_ext_iface();
00205      }
00206          UNLOCK_CONFIG();
00207     
00208          /*
00209           *
00210           * Everything in the MANGLE table
00211           *
00212           */
00213 
00214                         /* Create new chains */
00215                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED);
00216                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING);
00217                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING);
00218 
00219                         /* Assign links and rules to these new chains */
00220                         iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface);
00221                         iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, gw_interface);
00222                         iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, gw_interface);
00223 
00224             for (p = config->trustedmaclist; p != NULL; p = p->next)
00225                 iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN);
00226 
00227          /*
00228           *
00229           * Everything in the NAT table
00230           *
00231           */
00232 
00233                         /* Create new chains */
00234                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING);
00235                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00236                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00237                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL);
00238                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN);
00239                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS);
00240 
00241                         /* Assign links and rules to these new chains */
00242                         iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface);
00243 
00244                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, gw_address);
00245                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT");
00246 
00247                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00248                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);
00249                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);
00250                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
00251 
00252                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS);
00253                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL);
00254                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);
00255 
00256 
00257          /*
00258           *
00259           * Everything in the FILTER table
00260           *
00261           */
00262 
00263                         /* Create new chains */
00264                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00265                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS);
00266                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED);
00267                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL);
00268                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE);
00269                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN);
00270                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN);
00271 
00272                         /* Assign links and rules to these new chains */
00273 
00274             /* Insert at the beginning */
00275                         iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, gw_interface);
00276 
00277             /* TCPMSS rule for PPPoE */
00278                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP");
00279                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");
00280             if (ext_interface != NULL) {
00281                             iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW,INVALID -j DROP", ext_interface);
00282                             iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface);
00283             } else {
00284                 /* Will this work even if we don't specify an external interface? */
00285                             iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state NEW,INVALID -j DROP");
00286                             iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu");
00287             }
00288 
00289                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS);
00290                         iptables_fw_set_authservers();
00291 
00292                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED);
00293                         iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED);
00294 
00295                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL);
00296                         iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL);
00297                         iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL);
00298 
00299                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION);
00300                         iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE);
00301 
00302                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN);
00303                         iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN);
00304     
00305                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
00306                         iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN);
00307                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");
00308 
00309         free(gw_interface);
00310         free(gw_address);
00311 
00312     return 1;
00313 }
00314 
00319 int
00320 iptables_fw_destroy(void)
00321 {
00322     fw_quiet = 1;
00323 
00324          debug(LOG_DEBUG, "Destroying our iptables entries");
00325 
00326          /*
00327           *
00328           * Everything in the MANGLE table
00329           *
00330           */
00331          debug(LOG_DEBUG, "Destroying chains in the MANGLE table");
00332          iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED);
00333          iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING);
00334          iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING);
00335     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED);
00336     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING);
00337     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING);
00338     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED);
00339     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING);
00340     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING);
00341 
00342         /*
00343          *
00344          * Everything in the NAT table
00345          *
00346          */
00347         debug(LOG_DEBUG, "Destroying chains in the NAT table");
00348         iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING);
00349         iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS);
00350     iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING);
00351     iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00352     iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00353     iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL);
00354     iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN);
00355         iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS);
00356     iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING);
00357     iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00358     iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00359     iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL);
00360     iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN);
00361 
00362          /*
00363           *
00364           * Everything in the FILTER table
00365           *
00366           */
00367          debug(LOG_DEBUG, "Destroying chains in the FILTER table");
00368          iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET);
00369          iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00370          iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS);
00371          iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED);
00372          iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL);
00373          iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE);
00374          iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN);
00375          iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN);
00376          iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00377          iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS);
00378          iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED);
00379          iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL);
00380          iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE);
00381          iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN);
00382          iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN);
00383 
00384     return 1;
00385 }
00386 
00387 /*
00388  * Helper for iptables_fw_destroy
00389  * @param table The table to search
00390  * @param chain The chain in that table to search
00391  * @param mention A word to find and delete in rules in the given table+chain
00392  */
00393 int
00394 iptables_fw_destroy_mention(
00395                 char * table,
00396                 char * chain,
00397                 char * mention
00398 ) {
00399         FILE *p = NULL;
00400         char *command = NULL;
00401         char *command2 = NULL;
00402         char line[MAX_BUF];
00403         char rulenum[10];
00404         int deleted = 0;
00405 
00406         debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", mention, table, chain);
00407 
00408         safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain);
00409 
00410         if ((p = popen(command, "r"))) {
00411                 /* Skip first 2 lines */
00412                 while (!feof(p) && fgetc(p) != '\n');
00413                 while (!feof(p) && fgetc(p) != '\n');
00414                 /* Loop over entries */
00415                 while (fgets(line, sizeof(line), p)) {
00416                         /* Look for mention */
00417                         if (strstr(line, mention)) {
00418                                 /* Found mention - Get the rule number into rulenum*/
00419                                 if (sscanf(line, "%9[0-9]", rulenum) == 1) {
00420                                         /* Delete the rule: */
00421                                         debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, mention);
00422                                         safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum);
00423                                         iptables_do_command(command2);
00424                                         free(command2);
00425                                         deleted = 1;
00426                                         /* Do not keep looping - the captured rulenums will no longer be accurate */
00427                                         break;
00428                                 }
00429                         }
00430                 }
00431                 pclose(p);
00432         }
00433 
00434         free(command);
00435 
00436         if (deleted) {
00437                 /* Recurse just in case there are more in the same table+chain */
00438                 iptables_fw_destroy_mention(table, chain, mention);
00439         }
00440 
00441         return (deleted);
00442 }
00443 
00445 int
00446 iptables_fw_access(fw_access_t type, char *ip, char *mac, int tag)
00447 {
00448     int rc;
00449 
00450     fw_quiet = 0;
00451 
00452     switch(type) {
00453         case FW_ACCESS_ALLOW:
00454             iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag);
00455             rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip);
00456             break;
00457         case FW_ACCESS_DENY:
00458             iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag);
00459             rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip);
00460             break;
00461         default:
00462             rc = -1;
00463             break;
00464     }
00465 
00466     return rc;
00467 }
00468 
00470 int
00471 iptables_fw_counters_update(void)
00472 {
00473     FILE *output;
00474     char *script,
00475         ip[16],
00476         rc;
00477     unsigned long long int counter;
00478     t_client *p1;
00479          struct in_addr tempaddr;
00480 
00481     /* Look for outgoing traffic */
00482     safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING);
00483     output = popen(script, "r");
00484     free(script);
00485     if (!output) {
00486         debug(LOG_ERR, "popen(): %s", strerror(errno));
00487         return -1;
00488     }
00489 
00490     /* skip the first two lines */
00491     while (('\n' != fgetc(output)) && !feof(output))
00492         ;
00493     while (('\n' != fgetc(output)) && !feof(output))
00494         ;
00495     while (output && !(feof(output))) {
00496         rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip);
00497         if (2 == rc && EOF != rc) {
00498                           /* Sanity*/
00499                           if (!inet_aton(ip, &tempaddr)) {
00500                                   debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
00501                                   continue;
00502                           }
00503             debug(LOG_DEBUG, "Outgoing %s Bytes=%llu", ip, counter);
00504             LOCK_CLIENT_LIST();
00505             if ((p1 = client_list_find_by_ip(ip))) {
00506                 if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
00507                     p1->counters.outgoing = p1->counters.outgoing_history + counter;
00508                     p1->counters.last_updated = time(NULL);
00509                     debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes", ip, counter);
00510                 }
00511             } else {
00512                 debug(LOG_ERR, "Could not find %s in client list", ip);
00513             }
00514             UNLOCK_CLIENT_LIST();
00515         }
00516     }
00517     pclose(output);
00518 
00519     /* Look for incoming traffic */
00520     safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING);
00521     output = popen(script, "r");
00522     free(script);
00523     if (!output) {
00524         debug(LOG_ERR, "popen(): %s", strerror(errno));
00525         return -1;
00526     }
00527 
00528     /* skip the first two lines */
00529     while (('\n' != fgetc(output)) && !feof(output))
00530         ;
00531     while (('\n' != fgetc(output)) && !feof(output))
00532         ;
00533     while (output && !(feof(output))) {
00534         rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip);
00535         if (2 == rc && EOF != rc) {
00536                           /* Sanity*/
00537                           if (!inet_aton(ip, &tempaddr)) {
00538                                   debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
00539                                   continue;
00540                           }
00541             debug(LOG_DEBUG, "Incoming %s Bytes=%llu", ip, counter);
00542             LOCK_CLIENT_LIST();
00543             if ((p1 = client_list_find_by_ip(ip))) {
00544                 if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
00545                     p1->counters.incoming = p1->counters.incoming_history + counter;
00546                     debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter);
00547                 }
00548             } else {
00549                 debug(LOG_ERR, "Could not find %s in client list", ip);
00550             }
00551             UNLOCK_CLIENT_LIST();
00552         }
00553     }
00554     pclose(output);
00555 
00556     return 1;
00557 }

Generated on Sat Jan 6 18:51:44 2007 for WifiDog by  doxygen 1.5.1