Main Page | Data Structures | Directories | File List | Data Fields

src/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 935 2006-01-31 22:22:04 -0500 (Tue, 31 Jan 2006) 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          int gw_port = 0;
00191      t_trusted_mac *p;
00192    
00193     fw_quiet = 0;
00194 
00195          LOCK_CONFIG();
00196     config = config_get_config();
00197          gw_interface = safe_strdup(config->gw_interface);
00198          gw_address = safe_strdup(config->gw_address);
00199          gw_port = config->gw_port;
00200          UNLOCK_CONFIG();
00201     
00202          /*
00203           *
00204           * Everything in the MANGLE table
00205           *
00206           */
00207 
00208                         /* Create new chains */
00209                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED);
00210                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING);
00211                         iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING);
00212 
00213                         /* Assign links and rules to these new chains */
00214                         iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface);
00215                         iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, gw_interface);
00216                         iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, gw_interface);
00217 
00218             for (p = config->trustedmaclist; p != NULL; p = p->next)
00219                 iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN);
00220 
00221          /*
00222           *
00223           * Everything in the NAT table
00224           *
00225           */
00226 
00227                         /* Create new chains */
00228                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING);
00229                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00230                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00231                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL);
00232                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN);
00233                         iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS);
00234 
00235                         /* Assign links and rules to these new chains */
00236                         iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface);
00237 
00238                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, gw_address);
00239                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT");
00240 
00241                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00242                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);
00243                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);
00244                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
00245 
00246                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS);
00247                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL);
00248                         iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);
00249 
00250 
00251          /*
00252           *
00253           * Everything in the FILTER table
00254           *
00255           */
00256 
00257                         /* Create new chains */
00258                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00259                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS);
00260                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED);
00261                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL);
00262                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE);
00263                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN);
00264                         iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN);
00265 
00266                         /* Assign links and rules to these new chains */
00267                         iptables_do_command("-t filter -A FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, gw_interface);
00268                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS);
00269                         iptables_fw_set_authservers();
00270 
00271                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED);
00272                         iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED);
00273 
00274                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL);
00275                         iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL);
00276                         iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL);
00277 
00278                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION);
00279                         iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE);
00280 
00281                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN);
00282                         iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN);
00283     
00284                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
00285                         iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN);
00286                         iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");
00287 
00288         free(gw_interface);
00289         free(gw_address);
00290 
00291     return 1;
00292 }
00293 
00298 int
00299 iptables_fw_destroy(void)
00300 {
00301     fw_quiet = 1;
00302 
00303          debug(LOG_DEBUG, "Destroying our iptables entries");
00304 
00305          /*
00306           *
00307           * Everything in the MANGLE table
00308           *
00309           */
00310          debug(LOG_DEBUG, "Destroying chains in the MANGLE table");
00311          iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED);
00312          iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING);
00313          iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING);
00314     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED);
00315     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING);
00316     iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING);
00317     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED);
00318     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING);
00319     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING);
00320 
00321         /*
00322          *
00323          * Everything in the NAT table
00324          *
00325          */
00326         debug(LOG_DEBUG, "Destroying chains in the NAT table");
00327         iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING);
00328         iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS);
00329     iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING);
00330     iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00331     iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00332     iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN);
00333         iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS);
00334     iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING);
00335     iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER);
00336     iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00337     iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN);
00338 
00339          /*
00340           *
00341           * Everything in the FILTER table
00342           *
00343           */
00344          debug(LOG_DEBUG, "Destroying chains in the FILTER table");
00345          iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET);
00346          iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00347          iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS);
00348          iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED);
00349          iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL);
00350          iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE);
00351          iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN);
00352          iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN);
00353          iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET);
00354          iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS);
00355          iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED);
00356          iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL);
00357          iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE);
00358          iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN);
00359          iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN);
00360 
00361     return 1;
00362 }
00363 
00364 /*
00365  * Helper for iptables_fw_destroy
00366  * @param table The table to search
00367  * @param chain The chain in that table to search
00368  * @param mention A word to find and delete in rules in the given table+chain
00369  */
00370 int
00371 iptables_fw_destroy_mention(
00372                 char * table,
00373                 char * chain,
00374                 char * mention
00375 ) {
00376         FILE *p = NULL;
00377         char *command = NULL;
00378         char *command2 = NULL;
00379         char line[MAX_BUF];
00380         char rulenum[10];
00381         int deleted = 0;
00382 
00383         debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", mention, table, chain);
00384 
00385         safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain);
00386 
00387         if ((p = popen(command, "r"))) {
00388                 /* Skip first 2 lines */
00389                 while (!feof(p) && fgetc(p) != '\n');
00390                 while (!feof(p) && fgetc(p) != '\n');
00391                 /* Loop over entries */
00392                 while (fgets(line, sizeof(line), p)) {
00393                         /* Look for mention */
00394                         if (strstr(line, mention)) {
00395                                 /* Found mention - Get the rule number into rulenum*/
00396                                 if (sscanf(line, "%9[0-9]", rulenum) == 1) {
00397                                         /* Delete the rule: */
00398                                         debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, mention);
00399                                         safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum);
00400                                         iptables_do_command(command2);
00401                                         free(command2);
00402                                         deleted = 1;
00403                                         /* Do not keep looping - the captured rulenums will no longer be accurate */
00404                                         break;
00405                                 }
00406                         }
00407                 }
00408                 pclose(p);
00409         }
00410 
00411         free(command);
00412 
00413         if (deleted) {
00414                 /* Recurse just in case there are more in the same table+chain */
00415                 iptables_fw_destroy_mention(table, chain, mention);
00416         }
00417 
00418         return (deleted);
00419 }
00420 
00422 int
00423 iptables_fw_access(fw_access_t type, char *ip, char *mac, int tag)
00424 {
00425     int rc;
00426 
00427     fw_quiet = 0;
00428 
00429     switch(type) {
00430         case FW_ACCESS_ALLOW:
00431             iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag);
00432             rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip);
00433             break;
00434         case FW_ACCESS_DENY:
00435             iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag);
00436             rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip);
00437             break;
00438         default:
00439             rc = -1;
00440             break;
00441     }
00442 
00443     return rc;
00444 }
00445 
00447 int
00448 iptables_fw_counters_update(void)
00449 {
00450     FILE *output;
00451     char *script,
00452         ip[16],
00453         rc;
00454     unsigned long long int counter;
00455     t_client *p1;
00456          struct in_addr tempaddr;
00457 
00458     /* Look for outgoing traffic */
00459     safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING);
00460     output = popen(script, "r");
00461     free(script);
00462     if (!output) {
00463         debug(LOG_ERR, "popen(): %s", strerror(errno));
00464         return -1;
00465     }
00466 
00467     /* skip the first two lines */
00468     while (('\n' != fgetc(output)) && !feof(output))
00469         ;
00470     while (('\n' != fgetc(output)) && !feof(output))
00471         ;
00472     while (output && !(feof(output))) {
00473         rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip);
00474         if (2 == rc && EOF != rc) {
00475                           /* Sanity*/
00476                           if (!inet_aton(ip, &tempaddr)) {
00477                                   debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
00478                                   continue;
00479                           }
00480             debug(LOG_DEBUG, "Outgoing %s Bytes=%llu", ip, counter);
00481             LOCK_CLIENT_LIST();
00482             if ((p1 = client_list_find_by_ip(ip))) {
00483                 if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
00484                     p1->counters.outgoing = p1->counters.outgoing_history + counter;
00485                     p1->counters.last_updated = time(NULL);
00486                     debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes", ip, counter);
00487                 }
00488             } else {
00489                 debug(LOG_ERR, "Could not find %s in client list", ip);
00490             }
00491             UNLOCK_CLIENT_LIST();
00492         }
00493     }
00494     pclose(output);
00495 
00496     /* Look for incoming traffic */
00497     safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING);
00498     output = popen(script, "r");
00499     free(script);
00500     if (!output) {
00501         debug(LOG_ERR, "popen(): %s", strerror(errno));
00502         return -1;
00503     }
00504 
00505     /* skip the first two lines */
00506     while (('\n' != fgetc(output)) && !feof(output))
00507         ;
00508     while (('\n' != fgetc(output)) && !feof(output))
00509         ;
00510     while (output && !(feof(output))) {
00511         rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip);
00512         if (2 == rc && EOF != rc) {
00513                           /* Sanity*/
00514                           if (!inet_aton(ip, &tempaddr)) {
00515                                   debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
00516                                   continue;
00517                           }
00518             debug(LOG_DEBUG, "Incoming %s Bytes=%llu", ip, counter);
00519             LOCK_CLIENT_LIST();
00520             if ((p1 = client_list_find_by_ip(ip))) {
00521                 if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
00522                     p1->counters.incoming = p1->counters.incoming_history + counter;
00523                     debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter);
00524                 }
00525             } else {
00526                 debug(LOG_ERR, "Could not find %s in client list", ip);
00527             }
00528             UNLOCK_CLIENT_LIST();
00529         }
00530     }
00531     pclose(output);
00532 
00533     return 1;
00534 }

Generated on Tue Jan 31 23:13:16 2006 for WifiDog by  doxygen 1.4.4