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 1305 2007-11-01 20:04:20Z 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 
00064 static int
00065 iptables_do_command(char *format, ...)
00066 {
00067     va_list vlist;
00068     char *fmt_cmd,
00069         *cmd;
00070     int rc;
00071 
00072     va_start(vlist, format);
00073     safe_vasprintf(&fmt_cmd, format, vlist);
00074          va_end(vlist);
00075 
00076     safe_asprintf(&cmd, "iptables %s", fmt_cmd);
00077 
00078     free(fmt_cmd);
00079 
00080     debug(LOG_DEBUG, "Executing command: %s", cmd);
00081         
00082     rc = execute(cmd, fw_quiet);
00083 
00084     free(cmd);
00085 
00086     return rc;
00087 }
00088 
00097 static char *
00098 iptables_compile(char * table, char *chain, t_firewall_rule *rule)
00099 {
00100     char        command[MAX_BUF],
00101                 *mode;
00102     
00103     memset(command, 0, MAX_BUF);
00104     
00105     if (rule->block_allow == 1) {
00106         mode = safe_strdup("ACCEPT");
00107     } else {
00108         mode = safe_strdup("REJECT");
00109     }
00110     
00111     snprintf(command, sizeof(command),  "-t %s -A %s ",table, chain);
00112     if (rule->mask != NULL) {
00113         snprintf((command + strlen(command)), (sizeof(command) - 
00114                 strlen(command)), "-d %s ", rule->mask);
00115     }
00116     if (rule->protocol != NULL) {
00117         snprintf((command + strlen(command)), (sizeof(command) -
00118                 strlen(command)), "-p %s ", rule->protocol);
00119     }
00120     if (rule->port != NULL) {
00121         snprintf((command + strlen(command)), (sizeof(command) -
00122                 strlen(command)), "--dport %s ", rule->port);
00123     }
00124     snprintf((command + strlen(command)), (sizeof(command) - 
00125             strlen(command)), "-j %s", mode);
00126     
00127     free(mode);
00128 
00129     /* XXX The buffer command, an automatic variable, will get cleaned
00130      * off of the stack when we return, so we strdup() it. */
00131     return(safe_strdup(command));
00132 }
00133 
00141 static void
00142 iptables_load_ruleset(char * table, char *ruleset, char *chain)
00143 {
00144         t_firewall_rule         *rule;
00145         char                    *cmd;
00146 
00147         debug(LOG_DEBUG, "Load ruleset %s into table %s, chain %s", ruleset, table, chain);
00148         
00149         for (rule = get_ruleset(ruleset); rule != NULL; rule = rule->next) {
00150                 cmd = iptables_compile(table, chain, rule);
00151                 debug(LOG_DEBUG, "Loading rule \"%s\" into table %s, chain %s", cmd, table, chain);
00152                 iptables_do_command(cmd);
00153                 free(cmd);
00154         }
00155 
00156         debug(LOG_DEBUG, "Ruleset %s loaded into table %s, chain %s", ruleset, table, chain);
00157 }
00158 
00159 void
00160 iptables_fw_clear_authservers(void)
00161 {
00162     iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS);
00163     iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS);
00164 }
00165 
00166 void
00167 iptables_fw_set_authservers(void)
00168 {
00169     s_config *config;
00170     t_auth_serv *auth_server;
00171    
00172     config = config_get_config();
00173     
00174     for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {
00175             if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) {
00176                 iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);
00177                 iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);
00178             }
00179     }
00180 
00181 }
00182 
00185 int
00186 iptables_fw_init(void)
00187 {
00188     s_config *config;
00189          char * gw_interface = NULL;
00190          char * gw_address = NULL;
00191          char * ext_interface = NULL;
00192          int gw_port = 0;
00193      t_trusted_mac *p;
00194    
00195     fw_quiet = 0;
00196 
00197          LOCK_CONFIG();
00198     config = config_get_config();
00199          gw_interface = safe_strdup(config->gw_interface);
00200          gw_address = safe_strdup(config->gw_address);
00201          gw_port = config->gw_port;
00202      if (config->external_interface) {
00203             ext_interface = safe_strdup(config->external_interface);
00204      } else {
00205             ext_interface = get_ext_iface();
00206      }
00207          UNLOCK_CONFIG();
00208     
00209         if (ext_interface == NULL) {
00210                 debug(LOG_ERR, "FATAL: no external interface");
00211                 /* XXX leaks safe_strdup()'d strings */
00212                 return 0;
00213         }
00214          /*
00215           *
00216           * Everything in the MANGLE table
00217           *
00218           */
00219 
00220                         /* Create new chains */
00221                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED);
00222                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING);
00223                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING);
00224 
00225                         /* Assign links and rules to these new chains */
00226                         iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface);
00227                         iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, gw_interface);//this rule will be inserted before the prior one
00228                         iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, gw_interface);
00229 
00230             for (p = config->trustedmaclist; p != NULL; p = p->next)
00231                 iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN);
00232 
00233          /*
00234           *
00235           * Everything in the NAT table
00236           *
00237           */
00238 
00239                         /* Create new chains */
00240                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING);
00241                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00242                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00243                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL);
00244                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN);
00245                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS);
00246 
00247                         /* Assign links and rules to these new chains */
00248                         iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface);
00249 
00250                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, gw_address);
00251                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT");
00252 
00253                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00254                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);
00255                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);
00256                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
00257 
00258                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS);
00259                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL);
00260                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);
00261 
00262 
00263          /*
00264           *
00265           * Everything in the FILTER table
00266           *
00267           */
00268 
00269                         /* Create new chains */
00270                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00271                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS);
00272                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED);
00273                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL);
00274                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE);
00275                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN);
00276                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN);
00277 
00278                         /* Assign links and rules to these new chains */
00279 
00280             /* Insert at the beginning */
00281                         iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, gw_interface);
00282 
00283 
00284                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP");
00285 
00286                         /* XXX: Why this? it means that connections setup after authentication
00287                            stay open even after the connection is done... 
00288                            iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/
00289 
00290                         //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23
00291                         //iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface);
00292             
00293             /* TCPMSS rule for PPPoE */
00294                         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);
00295 
00296                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS);
00297                         iptables_fw_set_authservers();
00298 
00299                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED);
00300                         iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED);
00301 
00302                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL);
00303                         iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL);
00304                         iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL);
00305 
00306                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION);
00307                         iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE);
00308 
00309                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN);
00310                         iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN);
00311     
00312                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
00313                         iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN);
00314                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");
00315 
00316         free(gw_interface);
00317         free(gw_address);
00318 
00319     return 1;
00320 }
00321 
00326 int
00327 iptables_fw_destroy(void)
00328 {
00329     fw_quiet = 1;
00330 
00331          debug(LOG_DEBUG, "Destroying our iptables entries");
00332 
00333          /*
00334           *
00335           * Everything in the MANGLE table
00336           *
00337           */
00338          debug(LOG_DEBUG, "Destroying chains in the MANGLE table");
00339          iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED);
00340          iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING);
00341          iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING);
00342     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED);
00343     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING);
00344     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING);
00345     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED);
00346     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING);
00347     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING);
00348 
00349         /*
00350          *
00351          * Everything in the NAT table
00352          *
00353          */
00354         debug(LOG_DEBUG, "Destroying chains in the NAT table");
00355         iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING);
00356         iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS);
00357     iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING);
00358     iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00359     iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00360     iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL);
00361     iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN);
00362         iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS);
00363     iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING);
00364     iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00365     iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00366     iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL);
00367     iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN);
00368 
00369          /*
00370           *
00371           * Everything in the FILTER table
00372           *
00373           */
00374          debug(LOG_DEBUG, "Destroying chains in the FILTER table");
00375          iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET);
00376          iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00377          iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS);
00378          iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED);
00379          iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL);
00380          iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE);
00381          iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN);
00382          iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN);
00383          iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00384          iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS);
00385          iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED);
00386          iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL);
00387          iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE);
00388          iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN);
00389          iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN);
00390 
00391     return 1;
00392 }
00393 
00394 /*
00395  * Helper for iptables_fw_destroy
00396  * @param table The table to search
00397  * @param chain The chain in that table to search
00398  * @param mention A word to find and delete in rules in the given table+chain
00399  */
00400 int
00401 iptables_fw_destroy_mention(
00402                 char * table,
00403                 char * chain,
00404                 char * mention
00405 ) {
00406         FILE *p = NULL;
00407         char *command = NULL;
00408         char *command2 = NULL;
00409         char line[MAX_BUF];
00410         char rulenum[10];
00411         int deleted = 0;
00412 
00413         debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", mention, table, chain);
00414 
00415         safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain);
00416 
00417         if ((p = popen(command, "r"))) {
00418                 /* Skip first 2 lines */
00419                 while (!feof(p) && fgetc(p) != '\n');
00420                 while (!feof(p) && fgetc(p) != '\n');
00421                 /* Loop over entries */
00422                 while (fgets(line, sizeof(line), p)) {
00423                         /* Look for mention */
00424                         if (strstr(line, mention)) {
00425                                 /* Found mention - Get the rule number into rulenum*/
00426                                 if (sscanf(line, "%9[0-9]", rulenum) == 1) {
00427                                         /* Delete the rule: */
00428                                         debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, mention);
00429                                         safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum);
00430                                         iptables_do_command(command2);
00431                                         free(command2);
00432                                         deleted = 1;
00433                                         /* Do not keep looping - the captured rulenums will no longer be accurate */
00434                                         break;
00435                                 }
00436                         }
00437                 }
00438                 pclose(p);
00439         }
00440 
00441         free(command);
00442 
00443         if (deleted) {
00444                 /* Recurse just in case there are more in the same table+chain */
00445                 iptables_fw_destroy_mention(table, chain, mention);
00446         }
00447 
00448         return (deleted);
00449 }
00450 
00452 int
00453 iptables_fw_access(fw_access_t type, char *ip, char *mac, int tag)
00454 {
00455     int rc;
00456 
00457     fw_quiet = 0;
00458 
00459     switch(type) {
00460         case FW_ACCESS_ALLOW:
00461             iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag);
00462             rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip);
00463             break;
00464         case FW_ACCESS_DENY:
00465             iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag);
00466             rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip);
00467             break;
00468         default:
00469             rc = -1;
00470             break;
00471     }
00472 
00473     return rc;
00474 }
00475 
00477 int
00478 iptables_fw_counters_update(void)
00479 {
00480     FILE *output;
00481     char *script,
00482         ip[16],
00483         rc;
00484     unsigned long long int counter;
00485     t_client *p1;
00486          struct in_addr tempaddr;
00487 
00488     /* Look for outgoing traffic */
00489     safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING);
00490     output = popen(script, "r");
00491     free(script);
00492     if (!output) {
00493         debug(LOG_ERR, "popen(): %s", strerror(errno));
00494         return -1;
00495     }
00496 
00497     /* skip the first two lines */
00498     while (('\n' != fgetc(output)) && !feof(output))
00499         ;
00500     while (('\n' != fgetc(output)) && !feof(output))
00501         ;
00502     while (output && !(feof(output))) {
00503         rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip);
00504         if (2 == rc && EOF != rc) {
00505                           /* Sanity*/
00506                           if (!inet_aton(ip, &tempaddr)) {
00507                                   debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
00508                                   continue;
00509                           }
00510             debug(LOG_DEBUG, "Read outgoing traffic for %s: Bytes=%llu", ip, counter);
00511             LOCK_CLIENT_LIST();
00512             if ((p1 = client_list_find_by_ip(ip))) {
00513                 if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
00514                     p1->counters.outgoing = p1->counters.outgoing_history + counter;
00515                     p1->counters.last_updated = time(NULL);
00516                     debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes.  Updated last_updated to %d", ip, counter, p1->counters.last_updated);
00517                 }
00518             } else {
00519                 debug(LOG_ERR, "Could not find %s in client list", ip);
00520             }
00521             UNLOCK_CLIENT_LIST();
00522         }
00523     }
00524     pclose(output);
00525 
00526     /* Look for incoming traffic */
00527     safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING);
00528     output = popen(script, "r");
00529     free(script);
00530     if (!output) {
00531         debug(LOG_ERR, "popen(): %s", strerror(errno));
00532         return -1;
00533     }
00534 
00535     /* skip the first two lines */
00536     while (('\n' != fgetc(output)) && !feof(output))
00537         ;
00538     while (('\n' != fgetc(output)) && !feof(output))
00539         ;
00540     while (output && !(feof(output))) {
00541         rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip);
00542         if (2 == rc && EOF != rc) {
00543                           /* Sanity*/
00544                           if (!inet_aton(ip, &tempaddr)) {
00545                                   debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
00546                                   continue;
00547                           }
00548             debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter);
00549             LOCK_CLIENT_LIST();
00550             if ((p1 = client_list_find_by_ip(ip))) {
00551                 if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
00552                     p1->counters.incoming = p1->counters.incoming_history + counter;
00553                     debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter);
00554                 }
00555             } else {
00556                 debug(LOG_ERR, "Could not find %s in client list", ip);
00557             }
00558             UNLOCK_CLIENT_LIST();
00559         }
00560     }
00561     pclose(output);
00562 
00563     return 1;
00564 }

Generated on Sun Apr 13 21:55:00 2008 for WifiDog by  doxygen 1.5.3