Make static the options not in opt.h
[darkstat] / acct.c
diff --git a/acct.c b/acct.c
index 27f48ac..540bf35 100644 (file)
--- a/acct.c
+++ b/acct.c
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2011 Emil Mikulic.
+ * copyright (c) 2001-2012 Emil Mikulic.
  *
  * acct.c: traffic accounting
  *
@@ -26,7 +26,6 @@
 #include "now.h"
 #include "opt.h"
 
-#include <arpa/inet.h> /* for inet_aton() */
 #define __FAVOR_BSD
 #include <netinet/tcp.h>
 #include <sys/socket.h>
@@ -134,36 +133,25 @@ acct_init_localnet(const char *spec)
    verbosef("   local network mask: %s", addr_to_str(&localmask));
 }
 
-static int
-addr_is_local(const struct addr * const a)
-{
-   if (a->family == IPv4) {
-      if (using_localnet4) {
-         if (addr_inside(a, &localnet4, &localmask4))
-            return 1;
-      } else {
-         if (addr_equal(a, &localip4))
-            return 1;
-      }
-   } else {
-      assert(a->family == IPv6);
-      if (using_localnet6) {
-         if (addr_inside(a, &localnet6, &localmask6))
-            return 1;
-      } else {
-         if (addr_equal(a, &localip6))
-            return 1;
-      }
+static int addr_is_local(const struct addr * const a,
+                         const struct local_ips *local_ips) {
+   if (is_localip(a, local_ips))
+      return 1;
+   if (a->family == IPv4 && using_localnet4) {
+      if (addr_inside(a, &localnet4, &localmask4))
+         return 1;
+   } else if (a->family == IPv6 && using_localnet6) {
+      if (addr_inside(a, &localnet6, &localmask6))
+         return 1;
    }
    return 0;
 }
 
 /* Account for the given packet summary. */
-void
-acct_for(const struct pktsummary * const sm)
-{
-   struct bucket *hs = NULL, *hd = NULL;
-   struct bucket *ps, *pd;
+void acct_for(const struct pktsummary * const sm,
+              const struct local_ips * const local_ips) {
+   struct bucket *hs = NULL;  // Source host.
+   struct bucket *hd = NULL;  // Dest host.
    int dir_in, dir_out;
 
 #if 0 /* WANT_CHATTY? */
@@ -190,18 +178,15 @@ acct_for(const struct pktsummary * const sm)
    acct_total_bytes += sm->len;
 
    /* Graphs. */
-   dir_out = addr_is_local(&(sm->src));
-   dir_in  = addr_is_local(&(sm->dst));
+   dir_out = addr_is_local(&sm->src, local_ips);
+   dir_in  = addr_is_local(&sm->dst, local_ips);
 
    /* Traffic staying within the network isn't counted. */
-   if (dir_in == 1 && dir_out == 1)
-      dir_in = dir_out = 0;
-
-   if (dir_out) {
+   if (dir_out && !dir_in) {
       daylog_acct((uint64_t)sm->len, GRAPH_OUT);
       graph_acct((uint64_t)sm->len, GRAPH_OUT);
    }
-   if (dir_in) {
+   if (dir_in && !dir_out) {
       daylog_acct((uint64_t)sm->len, GRAPH_IN);
       graph_acct((uint64_t)sm->len, GRAPH_IN);
    }
@@ -210,30 +195,37 @@ acct_for(const struct pktsummary * const sm)
 
    /* 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.lastseen = 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));
-   /*
-    * Don't update recipient's last seen time, we don't know that
-    * they received successfully.
-    */
+   if (!opt_want_local_only || dir_out) {
+      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_mono = now_mono();
+   }
+
+   if (!opt_want_local_only || dir_in) {
+      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) {
-      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) {
+         struct bucket *ps = host_get_ip_proto(hs, sm->proto);
+         ps->out   += sm->len;
+         ps->total += sm->len;
+      }
+      if (hd) {
+         struct bucket *pd = host_get_ip_proto(hd, sm->proto);
+         pd->in    += sm->len;
+         pd->total += sm->len;
+      }
    }
 
    if (opt_ports_max == 0) return; /* skip ports accounting */
@@ -241,45 +233,64 @@ acct_for(const struct pktsummary * const sm)
    /* Ports. */
    switch (sm->proto) {
    case IPPROTO_TCP:
-      if (sm->src_port <= opt_highest_port) {
-         ps = host_get_port_tcp(hs, sm->src_port);
+      // Local ports on host.
+      if ((sm->src_port <= opt_highest_port) && hs) {
+         struct bucket *ps = host_get_port_tcp(hs, sm->src_port);
          ps->out   += sm->len;
          ps->total += sm->len;
       }
-
-      if (sm->dst_port <= opt_highest_port) {
-         pd = host_get_port_tcp(hd, sm->dst_port);
+      if ((sm->dst_port <= opt_highest_port) && hd) {
+         struct bucket *pd = host_get_port_tcp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
          if (sm->tcp_flags == TH_SYN)
             pd->u.port_tcp.syn++;
       }
+
+      // Remote ports.
+      if ((sm->src_port <= opt_highest_port) && hd) {
+         struct bucket *pdr = host_get_port_tcp_remote(hd, sm->src_port);
+         pdr->out   += sm->len;
+         pdr->total += sm->len;
+      }
+      if ((sm->dst_port <= opt_highest_port) && hs) {
+         struct bucket *psr = host_get_port_tcp_remote(hs, sm->dst_port);
+         psr->in    += sm->len;
+         psr->total += sm->len;
+         if (sm->tcp_flags == TH_SYN)
+            psr->u.port_tcp.syn++;
+      }
       break;
 
    case IPPROTO_UDP:
-      if (sm->src_port <= opt_highest_port) {
-         ps = host_get_port_udp(hs, sm->src_port);
+      // Local ports on host.
+      if ((sm->src_port <= opt_highest_port) && hs) {
+         struct bucket *ps = host_get_port_udp(hs, sm->src_port);
          ps->out   += sm->len;
          ps->total += sm->len;
       }
-
-      if (sm->dst_port <= opt_highest_port) {
-         pd = host_get_port_udp(hd, sm->dst_port);
+      if ((sm->dst_port <= opt_highest_port) && hd) {
+         struct bucket *pd = host_get_port_udp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
       }
-      break;
 
-   case IPPROTO_ICMP:
-   case IPPROTO_ICMPV6:
-   case IPPROTO_AH:
-   case IPPROTO_ESP:
-   case IPPROTO_OSPF:
-      /* known protocol, don't complain about it */
+      // Remote ports.
+      if ((sm->src_port <= opt_highest_port) && hd) {
+         struct bucket *pdr = host_get_port_udp_remote(hd, sm->src_port);
+         pdr->out   += sm->len;
+         pdr->total += sm->len;
+      }
+      if ((sm->dst_port <= opt_highest_port) && hs) {
+         struct bucket *psr = host_get_port_udp_remote(hs, sm->dst_port);
+         psr->in    += sm->len;
+         psr->total += sm->len;
+      }
       break;
 
-   default:
-      verbosef("unknown IP proto (%04x)", sm->proto);
+   case IPPROTO_INVALID:
+      /* proto decoding failed, don't complain in accounting */
+      break;
    }
 }