Define ETHERTYPE_IPV6 ourselves.
[darkstat] / acct.c
diff --git a/acct.c b/acct.c
index 4b04793..62ad076 100644 (file)
--- a/acct.c
+++ b/acct.c
@@ -1,5 +1,5 @@
 /* darkstat 3
 /* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2011 Emil Mikulic.
  *
  * acct.c: traffic accounting
  *
  *
  * acct.c: traffic accounting
  *
@@ -16,7 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "darkstat.h"
 #include "acct.h"
 #include "decode.h"
 #include "conv.h"
 #include "acct.h"
 #include "decode.h"
 #include "conv.h"
@@ -25,8 +24,8 @@
 #include "hosts_db.h"
 #include "localip.h"
 #include "now.h"
 #include "hosts_db.h"
 #include "localip.h"
 #include "now.h"
+#include "opt.h"
 
 
-#include <arpa/inet.h> /* for inet_aton() */
 #define __FAVOR_BSD
 #include <netinet/tcp.h>
 #include <sys/socket.h>
 #define __FAVOR_BSD
 #include <netinet/tcp.h>
 #include <sys/socket.h>
@@ -36,7 +35,7 @@
 #include <stdlib.h> /* for free */
 #include <string.h> /* for memcpy */
 
 #include <stdlib.h> /* for free */
 #include <string.h> /* for memcpy */
 
-uint64_t total_packets = 0, total_bytes = 0;
+uint64_t acct_total_packets = 0, acct_total_bytes = 0;
 
 static int using_localnet4 = 0, using_localnet6 = 0;
 static struct addr localnet4, localmask4, localnet6, localmask6;
 
 static int using_localnet4 = 0, using_localnet6 = 0;
 static struct addr localnet4, localmask4, localnet6, localmask6;
@@ -46,7 +45,8 @@ void
 acct_init_localnet(const char *spec)
 {
    char **tokens;
 acct_init_localnet(const char *spec)
 {
    char **tokens;
-   int num_tokens, isnum, j, ret;
+   unsigned int num_tokens;
+   int isnum, j, ret;
    int pfxlen, octets, remainder;
    struct addr localnet, localmask;
 
    int pfxlen, octets, remainder;
    struct addr localnet, localmask;
 
@@ -80,13 +80,18 @@ acct_init_localnet(const char *spec)
          errx(1, "family mismatch between net and mask");
    } else {
       uint8_t frac, *p;
          errx(1, "family mismatch between net and mask");
    } else {
       uint8_t frac, *p;
+      char *endptr;
 
       localmask.family = localnet.family;
 
       /* Compute the prefix length.  */
 
       localmask.family = localnet.family;
 
       /* Compute the prefix length.  */
-      pfxlen = strtonum(tokens[1], 1,
-                        (localnet.family == IPv6) ? 128 : 32, NULL);
-      if (pfxlen == 0)
+      pfxlen = (unsigned int)strtol(tokens[1], &endptr, 10);
+
+      if ((pfxlen < 0) ||
+          ((localnet.family == IPv6) && (pfxlen > 128)) ||
+          ((localnet.family == IPv4) && (pfxlen > 32)) ||
+          (tokens[1][0] == '\0') ||
+          (*endptr != '\0'))
          errx(1, "invalid network prefix length \"%s\"", tokens[1]);
 
       /* Construct the network mask.  */
          errx(1, "invalid network prefix length \"%s\"", tokens[1]);
 
       /* Construct the network mask.  */
@@ -103,7 +108,7 @@ acct_init_localnet(const char *spec)
       for (j = 0; j < octets; ++j)
          p[j] = 0xff;
 
       for (j = 0; j < octets; ++j)
          p[j] = 0xff;
 
-      frac = 0xff << (8 - remainder);
+      frac = (uint8_t)(0xff << (8 - remainder));
       if (frac)
          p[j] = frac;   /* Have contribution for next position.  */
    }
       if (frac)
          p[j] = frac;   /* Have contribution for next position.  */
    }
@@ -180,8 +185,8 @@ acct_for(const struct pktsummary * const sm)
 #endif
 
    /* Totals. */
 #endif
 
    /* Totals. */
-   total_packets++;
-   total_bytes += sm->len;
+   acct_total_packets++;
+   acct_total_bytes += sm->len;
 
    /* Graphs. */
    dir_out = addr_is_local(&(sm->src));
 
    /* Graphs. */
    dir_out = addr_is_local(&(sm->src));
@@ -200,45 +205,54 @@ acct_for(const struct pktsummary * const sm)
       graph_acct((uint64_t)sm->len, GRAPH_IN);
    }
 
       graph_acct((uint64_t)sm->len, GRAPH_IN);
    }
 
-   if (hosts_max == 0) return; /* skip per-host accounting */
+   if (opt_hosts_max == 0) return; /* skip per-host accounting */
 
    /* Hosts. */
    hosts_db_reduce();
 
    /* Hosts. */
    hosts_db_reduce();
-   hs = host_get(&(sm->src));
-   hs->out   += sm->len;
-   hs->total += sm->len;
-   memcpy(hs->u.host.mac_addr, sm->src_mac, sizeof(sm->src_mac));
-   hs->u.host.last_seen = now;
-
-   hd = host_get(&(sm->dst));
-   hd->in    += sm->len;
-   hd->total += sm->len;
-   memcpy(hd->u.host.mac_addr, sm->dst_mac, sizeof(sm->dst_mac));
-   hd->u.host.last_seen = now;
+   if (!opt_want_local_only || addr_is_local(&sm->src)) {
+      hs = host_get(&(sm->src));
+      hs->out   += sm->len;
+      hs->total += sm->len;
+      memcpy(hs->u.host.mac_addr, sm->src_mac, sizeof(sm->src_mac));
+      hs->u.host.lastseen = now;
+   }
+
+   if (!opt_want_local_only || addr_is_local(&sm->dst)) {
+      hd = host_get(&(sm->dst));
+      hd->in    += sm->len;
+      hd->total += sm->len;
+      memcpy(hd->u.host.mac_addr, sm->dst_mac, sizeof(sm->dst_mac));
+      /*
+       * Don't update recipient's last seen time, we don't know that
+       * they received successfully.
+       */
+   }
 
    /* Protocols. */
    if (sm->proto != IPPROTO_INVALID) {
 
    /* Protocols. */
    if (sm->proto != IPPROTO_INVALID) {
-      ps = host_get_ip_proto(hs, sm->proto);
-      ps->out   += sm->len;
-      ps->total += sm->len;
-
-      pd = host_get_ip_proto(hd, sm->proto);
-      pd->in    += sm->len;
-      pd->total += sm->len;
+      if (hs) {
+         ps = host_get_ip_proto(hs, sm->proto);
+         ps->out   += sm->len;
+         ps->total += sm->len;
+      }
+      if (hd) {
+         pd = host_get_ip_proto(hd, sm->proto);
+         pd->in    += sm->len;
+         pd->total += sm->len;
+      }
    }
 
    }
 
-   if (ports_max == 0) return; /* skip ports accounting */
+   if (opt_ports_max == 0) return; /* skip ports accounting */
 
    /* Ports. */
    switch (sm->proto) {
    case IPPROTO_TCP:
 
    /* Ports. */
    switch (sm->proto) {
    case IPPROTO_TCP:
-      if (sm->src_port <= highest_port) {
+      if ((sm->src_port <= opt_highest_port) && hs) {
          ps = host_get_port_tcp(hs, sm->src_port);
          ps->out   += sm->len;
          ps->total += sm->len;
       }
          ps = host_get_port_tcp(hs, sm->src_port);
          ps->out   += sm->len;
          ps->total += sm->len;
       }
-
-      if (sm->dst_port <= highest_port) {
+      if ((sm->dst_port <= opt_highest_port) && hd) {
          pd = host_get_port_tcp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
          pd = host_get_port_tcp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
@@ -248,13 +262,12 @@ acct_for(const struct pktsummary * const sm)
       break;
 
    case IPPROTO_UDP:
       break;
 
    case IPPROTO_UDP:
-      if (sm->src_port <= highest_port) {
+      if ((sm->src_port <= opt_highest_port) && hs) {
          ps = host_get_port_udp(hs, sm->src_port);
          ps->out   += sm->len;
          ps->total += sm->len;
       }
          ps = host_get_port_udp(hs, sm->src_port);
          ps->out   += sm->len;
          ps->total += sm->len;
       }
-
-      if (sm->dst_port <= highest_port) {
+      if ((sm->dst_port <= opt_highest_port) && hd) {
          pd = host_get_port_udp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
          pd = host_get_port_udp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;