Use struct addr - big cleanup.
authorEmil Mikulic <emikulic@gmail.com>
Tue, 10 May 2011 12:01:25 +0000 (22:01 +1000)
committerEmil Mikulic <emikulic@gmail.com>
Sat, 28 May 2011 10:10:52 +0000 (20:10 +1000)
12 files changed:
acct.c
acct.h
db.c
db.h
decode.c
decode.h
dns.c
dns.h
hosts_db.c
hosts_db.h
localip.c
localip.h

diff --git a/acct.c b/acct.c
index 65e2bc1..49ec8e2 100644 (file)
--- a/acct.c
+++ b/acct.c
@@ -18,6 +18,7 @@
 
 #include "darkstat.h"
 #include "acct.h"
+#include "decode.h"
 #include "conv.h"
 #include "daylog.h"
 #include "err.h"
 #define __FAVOR_BSD
 #include <netinet/tcp.h>
 #include <sys/socket.h>
+#include <assert.h>
+#include <ctype.h> /* for isdigit */
+#include <netdb.h> /* for gai_strerror */
 #include <stdlib.h> /* for free */
 #include <string.h> /* for memcpy */
-#include <ctype.h>  /* isdigit() */
 
 uint64_t total_packets = 0, total_bytes = 0;
 
-static int using_localnet = 0;
-static int using_localnet6 = 0;
-static in_addr_t localnet, localmask;
-static struct in6_addr localnet6, localmask6;
+static int using_localnet4 = 0, using_localnet6 = 0;
+static struct addr localnet4, localmask4, localnet6, localmask6;
 
 /* Parse the net/mask specification into two IPs or die trying. */
 void
 acct_init_localnet(const char *spec)
 {
-   char **tokens, *p;
-   int num_tokens, isnum, j;
-   int build_ipv6;  /* Zero for IPv4, one for IPv6.  */
+   char **tokens;
+   int num_tokens, isnum, j, ret;
    int pfxlen, octets, remainder;
-   struct in_addr addr;
-   struct in6_addr addr6;
+   struct addr localnet, localmask;
 
    tokens = split('/', spec, &num_tokens);
    if (num_tokens != 2)
       errx(1, "expecting network/netmask, got \"%s\"", spec);
 
-   /* Presence of a colon distinguishes address families.  */
-   if (strchr(tokens[0], ':')) {
-      build_ipv6 = 1;
-      if (inet_pton(AF_INET6, tokens[0], &addr6) != 1)
-         errx(1, "invalid IPv6 network address \"%s\"", tokens[0]);
-      memcpy(&localnet6, &addr6, sizeof(localnet6));
-   } else {
-      build_ipv6 = 0;
-      if (inet_pton(AF_INET, tokens[0], &addr) != 1)
-         errx(1, "invalid network address \"%s\"", tokens[0]);
-      localnet = addr.s_addr;
-   }
+   if ((ret = str_to_addr(tokens[0], &localnet)) != 0)
+      errx(1, "couldn't parse \"%s\": %s", tokens[0], gai_strerror(ret));
 
    /* Detect a purely numeric argument.  */
    isnum = 0;
-   p = tokens[1];
-   while (*p != '\0') {
-      if (isdigit(*p)) {
-         isnum = 1;
-         ++p;
-         continue;
-      } else {
-         isnum = 0;
-         break;
+   {
+      const char *p = tokens[1];
+      while (*p != '\0') {
+         if (isdigit(*p)) {
+            isnum = 1;
+            ++p;
+            continue;
+         } else {
+            isnum = 0;
+            break;
+         }
       }
    }
 
    if (!isnum) {
-      if (build_ipv6) {
-         if (inet_pton(AF_INET6, tokens[1], &addr6) != 1)
-            errx(1, "invalid IPv6 network mask \"%s\"", tokens[1]);
-         memcpy(&localmask6, &addr6, sizeof(localmask6));
-      } else {
-         if (inet_pton(AF_INET, tokens[1], &addr) != 1)
-            errx(1, "invalid network mask \"%s\"", tokens[1]);
-         localmask = addr.s_addr;
-      }
+      if ((ret = str_to_addr(tokens[1], &localmask)) != 0)
+         errx(1, "couldn't parse \"%s\": %s", tokens[1], gai_strerror(ret));
+      if (localmask.family != localnet.family)
+         errx(1, "family mismatch between net and mask");
    } else {
       uint8_t frac, *p;
 
+      localmask.family = localnet.family;
+
       /* Compute the prefix length.  */
-      pfxlen = strtonum(tokens[1], 1, build_ipv6 ? 128 : 32, NULL);
+      pfxlen = strtonum(tokens[1], 1,
+                        (localnet.family == IPv6) ? 128 : 32, NULL);
       if (pfxlen == 0)
          errx(1, "invalid network prefix length \"%s\"", tokens[1]);
 
       /* Construct the network mask.  */
       octets = pfxlen / 8;
       remainder = pfxlen % 8;
-      p = build_ipv6 ? (uint8_t *) localmask6.s6_addr : (uint8_t *) &localmask;
+      p = (localnet.family == IPv6) ? (localmask.ip.v6.s6_addr)
+                                    : ((uint8_t *) &(localmask.ip.v4));
 
-      if (build_ipv6)
-         memset(&localmask6, 0, sizeof(localmask6));
+      if (localnet.family == IPv6)
+         memset(p, 0, 16);
       else
-         memset(&localmask, 0, sizeof(localmask));
+         memset(p, 0, 4);
 
       for (j = 0; j < octets; ++j)
          p[j] = 0xff;
@@ -118,47 +108,65 @@ acct_init_localnet(const char *spec)
          p[j] = frac;   /* Have contribution for next position.  */
    }
 
+   free(tokens[0]);
+   free(tokens[1]);
+   free(tokens);
+
    /* Register the correct netmask and calculate the correct net.  */
-   if (build_ipv6) {
+   addr_mask(&localnet, &localmask);
+   if (localnet.family == IPv6) {
       using_localnet6 = 1;
-      for (j = 0; j < 16; ++j)
-         localnet6.s6_addr[j] &= localmask6.s6_addr[j];
+      localnet6 = localnet;
+      localmask6 = localmask;
    } else {
-      using_localnet = 1;
-      localnet &= localmask;
+      using_localnet4 = 1;
+      localnet4 = localnet;
+      localmask4 = localmask;
    }
 
-   free(tokens[0]);
-   free(tokens[1]);
-   free(tokens);
+   verbosef("local network address: %s", addr_to_str(&localnet));
+   verbosef("   local network mask: %s", addr_to_str(&localmask));
+}
 
-   if (build_ipv6) {
-      verbosef("local network address: %s", ip_to_str_af(&localnet6, AF_INET6));
-      verbosef("   local network mask: %s", ip_to_str_af(&localmask6, AF_INET6));
+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 {
-      verbosef("local network address: %s", ip_to_str_af(&localnet, AF_INET));
-      verbosef("   local network mask: %s", ip_to_str_af(&localmask, AF_INET));
+      assert(a->family == IPv6);
+      if (using_localnet6) {
+         if (addr_inside(a, &localnet6, &localmask6))
+            return 1;
+      } else {
+         if (addr_equal(a, &localip6))
+            return 1;
+      }
    }
-
+   return 0;
 }
 
 /* Account for the given packet summary. */
 void
-acct_for(const pktsummary *sm)
+acct_for(const struct pktsummary * const sm)
 {
    struct bucket *hs = NULL, *hd = NULL;
    struct bucket *ps, *pd;
-   struct addr46 ipaddr;
-   struct in6_addr scribble;
-   int dir_in, dir_out, j;
+   int dir_in, dir_out;
 
 #if 0 /* WANT_CHATTY? */
-   printf("%15s > ", ip_to_str_af(&sm->src_ip, AF_INET));
-   printf("%15s ", ip_to_str_af(&sm->dest_ip, AF_INET));
+   printf("%15s > ", addr_to_str(&sm->src));
+   printf("%15s ", addr_to_str(&sm->dst));
    printf("len %4d proto %2d", sm->len, sm->proto);
 
    if (sm->proto == IPPROTO_TCP || sm->proto == IPPROTO_UDP)
-      printf(" port %5d : %5d", sm->src_port, sm->dest_port);
+      printf(" port %5d : %5d", sm->src_port, sm->dst_port);
    if (sm->proto == IPPROTO_TCP)
       printf(" %s%s%s%s%s%s",
          (sm->tcp_flags & TH_FIN)?"F":"",
@@ -176,42 +184,12 @@ acct_for(const pktsummary *sm)
    total_bytes += sm->len;
 
    /* Graphs. */
-   dir_in = dir_out = 0;
-
-   if (sm->af == AF_INET) {
-      if (using_localnet) {
-         if ((sm->src_ip.s_addr & localmask) == localnet)
-            dir_out = 1;
-         if ((sm->dest_ip.s_addr & localmask) == localnet)
-            dir_in = 1;
-         if (dir_in == 1 && dir_out == 1)
-            /* Traffic staying within the network isn't counted. */
-            dir_in = dir_out = 0;
-      } else {
-         if (memcmp(&sm->src_ip, &localip, sizeof(localip)) == 0)
-            dir_out = 1;
-         if (memcmp(&sm->dest_ip, &localip, sizeof(localip)) == 0)
-            dir_in = 1;
-      }
-   } else if (sm->af == AF_INET6) {
-      if (using_localnet6) {
-         for (j = 0; j < 16; ++j)
-            scribble.s6_addr[j] = sm->src_ip6.s6_addr[j] & localmask6.s6_addr[j];
-         if (memcmp(&scribble, &localnet6, sizeof(scribble)) == 0)
-            dir_out = 1;
-         else {
-            for (j = 0; j < 16; ++j)
-               scribble.s6_addr[j] = sm->dest_ip6.s6_addr[j] & localmask6.s6_addr[j];
-            if (memcmp(&scribble, &localnet6, sizeof(scribble)) == 0)
-               dir_in = 1;
-         }
-      } else {
-         if (memcmp(&sm->src_ip6, &localip6, sizeof(localip6)) == 0)
-            dir_out = 1;
-         if (memcmp(&sm->dest_ip6, &localip6, sizeof(localip6)) == 0)
-            dir_in = 1;
-      }
-   }
+   dir_out = addr_is_local(&(sm->src));
+   dir_in  = addr_is_local(&(sm->dst));
+
+   /* Traffic staying within the network isn't counted. */
+   if (dir_in == 1 && dir_out == 1)
+      dir_in = dir_out = 0;
 
    if (dir_out) {
       daylog_acct((uint64_t)sm->len, GRAPH_OUT);
@@ -225,48 +203,20 @@ acct_for(const pktsummary *sm)
    if (hosts_max == 0) return; /* skip per-host accounting */
 
    /* Hosts. */
-   ipaddr.af = sm->af;
-   switch (ipaddr.af) {
-      case AF_INET6:
-         memcpy(&ipaddr.addr.ip6, &sm->src_ip6, sizeof(ipaddr.addr.ip6));
-         break;
-      case AF_INET:
-      default:
-         memcpy(&ipaddr.addr.ip, &sm->src_ip, sizeof(ipaddr.addr.ip));
-         break;
-   }
-   hs = host_get(&ipaddr);
+   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;
 
-   switch (ipaddr.af) {
-      case AF_INET6:
-         memcpy(&ipaddr.addr.ip6, &sm->dest_ip6, sizeof(ipaddr.addr.ip6));
-         break;
-      case AF_INET:
-      default:
-         memcpy(&ipaddr.addr.ip, &sm->dest_ip, sizeof(ipaddr.addr.ip));
-         break;
-   }
-   hd = host_get(&ipaddr); /* this can invalidate hs! */
+   hd = host_get(&(sm->dst)); /* this can invalidate hs! */
    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;
 
    /* Protocols. */
-   switch (ipaddr.af) {
-      case AF_INET6:
-         memcpy(&ipaddr.addr.ip6, &sm->src_ip6, sizeof(ipaddr.addr.ip6));
-         break;
-      case AF_INET:
-      default:
-         memcpy(&ipaddr.addr.ip, &sm->src_ip, sizeof(ipaddr.addr.ip));
-         break;
-   }
-   hs = host_find(&ipaddr);
+   hs = host_find(&(sm->src));
    if (hs != NULL) {
       ps = host_get_ip_proto(hs, sm->proto);
       ps->out   += sm->len;
@@ -290,9 +240,9 @@ acct_for(const pktsummary *sm)
          ps->total += sm->len;
       }
 
-      if (sm->dest_port <= highest_port)
+      if (sm->dst_port <= highest_port)
       {
-         pd = host_get_port_tcp(hd, sm->dest_port);
+         pd = host_get_port_tcp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
          if (sm->tcp_flags == TH_SYN)
@@ -308,9 +258,9 @@ acct_for(const pktsummary *sm)
          ps->total += sm->len;
       }
 
-      if (sm->dest_port <= highest_port)
+      if (sm->dst_port <= highest_port)
       {
-         pd = host_get_port_udp(hd, sm->dest_port);
+         pd = host_get_port_udp(hd, sm->dst_port);
          pd->in    += sm->len;
          pd->total += sm->len;
       }
diff --git a/acct.h b/acct.h
index 336ac85..c0434ed 100644 (file)
--- a/acct.h
+++ b/acct.h
@@ -4,12 +4,14 @@
  * acct.h: traffic accounting
  */
 
-#include "decode.h"
+#include <stdint.h>
+
+struct pktsummary;
 
 extern uint64_t total_packets, total_bytes;
 
 void acct_init_localnet(const char *spec);
-void acct_for(const pktsummary *sm);
+void acct_for(const struct pktsummary * const sm);
 
 extern unsigned int highest_port;
 
diff --git a/db.c b/db.c
index 6a15ade..7dd7901 100644 (file)
--- a/db.c
+++ b/db.c
@@ -152,20 +152,18 @@ read32(const int fd, uint32_t *dest)
    return 1;
 }
 
-/* Read a struct addr46 from a file.  Addresses are always stored in network
+/* Read a struct addr from a file.  Addresses are always stored in network
  * order, both in the file and in the host's memory (FIXME: is that right?)
- * The component "dest->af" must specify AF_INET or AF_INET6.
  */
 int
-readaddr(const int fd, struct addr46 *dest)
+readaddr(const int fd, struct addr *dest)
 {
-   assert(sizeof(*dest) == sizeof(struct addr46));
-   assert(dest->af == AF_INET || dest->af == AF_INET6);
+   assert(dest->family == IPv4 || dest->family == AF_INET6);
 
-   if (dest->af == AF_INET)
-      return readn(fd, &dest->addr.ip, sizeof(struct in_addr));
+   if (dest->family == IPv4)
+      return readn(fd, &(dest->ip.v4), sizeof(dest->ip.v4));
    else
-      return readn(fd, &dest->addr.ip6, sizeof(struct in6_addr));
+      return readn(fd, dest->ip.v6.s6_addr, sizeof(dest->ip.v6.s6_addr));
 }
 
 /* Read a network order uint64_t from a file
@@ -243,20 +241,19 @@ write64(const int fd, const uint64_t i)
 }
 
 
-/* Write the active address part in a struct addr46 structure to a file.
+/* Write the active address part in a struct addr to a file.
  * Addresses are always stored in network order, both in the file and
  * in the host's memory (FIXME: is that right?)
  */
 int
-writeaddr(const int fd, const struct addr46 *const ip)
+writeaddr(const int fd, const struct addr *const a)
 {
-   assert(sizeof(*ip) == sizeof(struct addr46));
-   assert(ip->af == AF_INET || ip->af == AF_INET6);
-
-   if (ip->af == AF_INET)
-      return writen(fd, &ip->addr.ip, sizeof(ip->addr.ip));
-   else
-      return writen(fd, &ip->addr.ip6, sizeof(ip->addr.ip6));
+   if (a->family == IPv4)
+      return writen(fd, &(a->ip.v4), sizeof(a->ip.v4));
+   else {
+      assert(a->family == IPv6);
+      return writen(fd, a->ip.v6.s6_addr, sizeof(a->ip.v6.s6_addr));
+   }
 }
 
 /* ---------------------------------------------------------------------------
diff --git a/db.h b/db.h
index 8f3e686..866b17c 100644 (file)
--- a/db.h
+++ b/db.h
@@ -4,7 +4,10 @@
  * copyright (c) 2007 Ben Stewart, Emil Mikulic.
  */
 
-#include "hosts_db.h"   /* addr46 */
+#include <sys/types.h> /* for size_t */
+#include <stdint.h> /* for uint64_t */
+
+struct addr;
 
 void db_import(const char *filename);
 void db_export(const char *filename);
@@ -21,8 +24,8 @@ int read8(const int fd, uint8_t *dest);
 int expect8(const int fd, uint8_t expecting);
 int read16(const int fd, uint16_t *dest);
 int read32(const int fd, uint32_t *dest);
-int readaddr(const int fd, struct addr46 *dest);
 int read64(const int fd, uint64_t *dest);
+int readaddr(const int fd, struct addr *dest);
 int read_file_header(const int fd, const uint8_t expected[4]);
 
 /* write helpers */
@@ -30,7 +33,7 @@ int writen(const int fd, const void *dest, const size_t len);
 int write8(const int fd, const uint8_t i);
 int write16(const int fd, const uint16_t i);
 int write32(const int fd, const uint32_t i);
-int writeaddr(const int fd, const struct addr46 *const addr);
 int write64(const int fd, const uint64_t i);
+int writeaddr(const int fd, const struct addr *const a);
 
 /* vim:set ts=3 sw=3 tw=78 et: */
index 0cd6cb3..d2c0b85 100644 (file)
--- a/decode.c
+++ b/decode.c
 #include "darkstat.h"
 #include "acct.h"
 #include "cap.h"
+#include "decode.h"
+#include "err.h"
 
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <assert.h>
-#include "err.h"
 #include <pcap.h>
 #include <string.h>
 #include <unistd.h>
@@ -74,15 +75,15 @@ static void decode_ppp(u_char *, const struct pcap_pkthdr *,
 static void decode_pppoe(u_char *, const struct pcap_pkthdr *,
    const u_char *);
 static void decode_pppoe_real(const u_char *pdata, const uint32_t len,
-   pktsummary *sm);
+   struct pktsummary *sm);
 static void decode_linux_sll(u_char *, const struct pcap_pkthdr *,
    const u_char *);
 static void decode_raw(u_char *, const struct pcap_pkthdr *,
    const u_char *);
 static void decode_ip(const u_char *pdata, const uint32_t len,
-   pktsummary *sm);
+   struct pktsummary *sm);
 static void decode_ipv6(const u_char *pdata, const uint32_t len,
-   pktsummary *sm);
+   struct pktsummary *sm);
 
 /* Link-type header information */
 static const struct linkhdr linkhdrs[] = {
@@ -100,7 +101,7 @@ static const struct linkhdr linkhdrs[] = {
    { DLT_LINUX_SLL, SLL_HDR_LEN,   decode_linux_sll },
 #endif
    { DLT_RAW,       RAW_HDR_LEN,   decode_raw },
-   { -1, -1, NULL }
+   { -1, 0, NULL }
 };
 
 /*
@@ -131,30 +132,6 @@ getsnaplen(const struct linkhdr *lh)
    return (20 + lh->hdrlen + IPV6_HDR_LEN + max(TCP_HDR_LEN, UDP_HDR_LEN));
 }
 
-/*
- * Convert IP address to a presentation notation in a static buffer
- * using inet_ntop(3).
- */
-char ipstr[INET6_ADDRSTRLEN]; /* TODO Reentrant? */
-
-char *
-ip_to_str(const struct addr46 *const ip)
-{
-   ipstr[0] = '\0';
-   inet_ntop(ip->af, &ip->addr.ip6, ipstr, sizeof(ipstr));
-
-   return (ipstr);
-}
-
-char *
-ip_to_str_af(const void *const addr, sa_family_t af)
-{
-   ipstr[0] = '\0';
-   inet_ntop(af, addr, ipstr, sizeof(ipstr));
-
-   return (ipstr);
-}
-
 /* Decoding functions. */
 static void
 decode_ether(u_char *user _unused_,
@@ -163,7 +140,7 @@ decode_ether(u_char *user _unused_,
 {
    u_short type;
    const struct ether_header *hdr = (const struct ether_header *)pdata;
-   pktsummary sm;
+   struct pktsummary sm;
    memset(&sm, 0, sizeof(sm));
    sm.time = pheader->ts.tv_sec;
 
@@ -212,7 +189,7 @@ decode_loop(u_char *user _unused_,
       const u_char *pdata)
 {
    uint32_t family;
-   pktsummary sm;
+   struct pktsummary sm;
    memset(&sm, 0, sizeof(sm));
 
    if (pheader->caplen < NULL_HDR_LEN) {
@@ -244,7 +221,7 @@ decode_ppp(u_char *user _unused_,
       const struct pcap_pkthdr *pheader,
       const u_char *pdata)
 {
-   pktsummary sm;
+   struct pktsummary sm;
    memset(&sm, 0, sizeof(sm));
 
    if (pheader->caplen < PPPOE_HDR_LEN) {
@@ -265,7 +242,7 @@ decode_pppoe(u_char *user _unused_,
       const struct pcap_pkthdr *pheader,
       const u_char *pdata)
 {
-   pktsummary sm;
+   struct pktsummary sm;
    memset(&sm, 0, sizeof(sm));
    sm.time = pheader->ts.tv_sec;
    decode_pppoe_real(pdata, pheader->caplen, &sm);
@@ -273,7 +250,7 @@ decode_pppoe(u_char *user _unused_,
 
 static void
 decode_pppoe_real(const u_char *pdata, const uint32_t len,
-   pktsummary *sm)
+   struct pktsummary *sm)
 {
    if (len < PPPOE_HDR_LEN) {
       verbosef("pppoe: packet too short (%u bytes)", len);
@@ -311,7 +288,7 @@ decode_linux_sll(u_char *user _unused_,
       uint16_t ether_type;
    } *hdr = (const struct sll_header *)pdata;
    u_short type;
-   pktsummary sm;
+   struct pktsummary sm;
    memset(&sm, 0, sizeof(sm));
 
    if (pheader->caplen < SLL_HDR_LEN) {
@@ -340,7 +317,7 @@ decode_raw(u_char *user _unused_,
       const struct pcap_pkthdr *pheader,
       const u_char *pdata)
 {
-   pktsummary sm;
+   struct pktsummary sm;
    memset(&sm, 0, sizeof(sm));
 
    decode_ip(pdata, pheader->caplen, &sm);
@@ -349,7 +326,7 @@ decode_raw(u_char *user _unused_,
 }
 
 static void
-decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
+decode_ip(const u_char *pdata, const uint32_t len, struct pktsummary *sm)
 {
    const struct ip *hdr = (const struct ip *)pdata;
 
@@ -368,10 +345,13 @@ decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
    }
 
    sm->len = ntohs(hdr->ip_len);
-   sm->af = AF_INET;
    sm->proto = hdr->ip_p;
-   memcpy(&sm->src_ip, &hdr->ip_src, sizeof(sm->src_ip));
-   memcpy(&sm->dest_ip, &hdr->ip_dst, sizeof(sm->dest_ip));
+
+   sm->src.family = IPv4;
+   sm->src.ip.v4 = hdr->ip_src.s_addr;
+
+   sm->dst.family = IPv4;
+   sm->dst.ip.v4 = hdr->ip_dst.s_addr;
 
    switch (sm->proto) {
       case IPPROTO_TCP: {
@@ -382,7 +362,7 @@ decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
             return;
          }
          sm->src_port = ntohs(thdr->th_sport);
-         sm->dest_port = ntohs(thdr->th_dport);
+         sm->dst_port = ntohs(thdr->th_dport);
          sm->tcp_flags = thdr->th_flags &
             (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG);
          break;
@@ -396,7 +376,7 @@ decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
             return;
          }
          sm->src_port = ntohs(uhdr->uh_sport);
-         sm->dest_port = ntohs(uhdr->uh_dport);
+         sm->dst_port = ntohs(uhdr->uh_dport);
          break;
       }
 
@@ -413,7 +393,7 @@ decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
 }
 
 static void
-decode_ipv6(const u_char *pdata, const uint32_t len, pktsummary *sm)
+decode_ipv6(const u_char *pdata, const uint32_t len, struct pktsummary *sm)
 {
    const struct ip6_hdr *hdr = (const struct ip6_hdr *)pdata;
 
@@ -423,10 +403,13 @@ decode_ipv6(const u_char *pdata, const uint32_t len, pktsummary *sm)
    }
 
    sm->len = ntohs(hdr->ip6_plen) + IPV6_HDR_LEN;
-   sm->af = AF_INET6;
    sm->proto = hdr->ip6_nxt;
-   memcpy(&sm->src_ip6, &hdr->ip6_src, sizeof(sm->src_ip6));
-   memcpy(&sm->dest_ip6, &hdr->ip6_dst, sizeof(sm->dest_ip6));
+
+   sm->src.family = IPv6;
+   memcpy(&sm->src.ip.v6, &hdr->ip6_src, sizeof(sm->src.ip.v6));
+
+   sm->dst.family = IPv6;
+   memcpy(&sm->dst.ip.v6, &hdr->ip6_dst, sizeof(sm->dst.ip.v6));
 
    switch (sm->proto) {
       case IPPROTO_TCP: {
@@ -437,7 +420,7 @@ decode_ipv6(const u_char *pdata, const uint32_t len, pktsummary *sm)
             return;
          }
          sm->src_port = ntohs(thdr->th_sport);
-         sm->dest_port = ntohs(thdr->th_dport);
+         sm->dst_port = ntohs(thdr->th_dport);
          sm->tcp_flags = thdr->th_flags &
             (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG);
          break;
@@ -451,7 +434,7 @@ decode_ipv6(const u_char *pdata, const uint32_t len, pktsummary *sm)
             return;
          }
          sm->src_port = ntohs(uhdr->uh_sport);
-         sm->dest_port = ntohs(uhdr->uh_dport);
+         sm->dst_port = ntohs(uhdr->uh_dport);
          break;
       }
 
index d4c8bc0..f497ac3 100644 (file)
--- a/decode.h
+++ b/decode.h
@@ -15,7 +15,7 @@
 #include <netinet/in.h> /* for <netinet/ip.h>  */
 #include <netinet/ip.h> /* struct ip */
 
-#include "hosts_db.h"   /* addr46 */
+#include "addr.h"
 
 #define PPP_HDR_LEN     4
 #define FDDI_HDR_LEN    21
@@ -44,28 +44,18 @@ struct linkhdr {
 
 const struct linkhdr *getlinkhdr(const int linktype);
 int getsnaplen(const struct linkhdr *lh);
-char *ip_to_str(const struct addr46 *const ip);
-char *ip_to_str_af(const void *const addr, sa_family_t af);
 
-typedef struct {
+struct pktsummary {
    /* Fields are in host byte order (except IPs) */
-   union {
-      struct in_addr src_ip;
-      struct in6_addr src_ip6;
-   };
-   union {
-      struct in_addr dest_ip;
-      struct in6_addr dest_ip6;
-   };
+   struct addr src, dst;
    time_t time;
    uint16_t len;
-   sa_family_t af;               /* AF_{UNSPEC, INET, INET6} */
-   uint8_t proto;                /* IPPROTO_{TCP, UDP, ICMP} */
-   uint8_t tcp_flags;            /* only for TCP */
-   uint16_t src_port, dest_port; /* only for TCP, UDP */
+   uint8_t proto;               /* IPPROTO_{TCP, UDP, ICMP} */
+   uint8_t tcp_flags;           /* only for TCP */
+   uint16_t src_port, dst_port; /* only for TCP, UDP */
    uint8_t src_mac[ETHER_ADDR_LEN],
            dst_mac[ETHER_ADDR_LEN]; /* only for Ethernet */
-} pktsummary;
+};
 
 #endif /* __DARKSTAT_DECODE_H */
 /* vim:set ts=3 sw=3 tw=78 expandtab: */
diff --git a/dns.c b/dns.c
index 125ab62..1c6dc24 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -14,6 +14,7 @@
 #include "err.h"
 #include "hosts_db.h"
 #include "queue.h"
+#include "str.h"
 #include "tree.h"
 
 #include <sys/param.h>
@@ -35,7 +36,7 @@ static int sock[2];
 static pid_t pid = -1;
 
 struct dns_reply {
-   struct addr46 addr;
+   struct addr addr;
    int error; /* for gai_strerror(), or 0 if no error */
    char name[MAXHOSTNAMELEN];
 };
@@ -86,26 +87,22 @@ dns_stop(void)
 
 struct tree_rec {
    RB_ENTRY(tree_rec) ptree;
-   struct addr46 ip;
+   struct addr ip;
 };
 
 static int
 tree_cmp(struct tree_rec *a, struct tree_rec *b)
 {
-   if (a->ip.af != b->ip.af)
+   if (a->ip.family != b->ip.family)
       /* Sort IPv4 to the left of IPv6.  */
-      return (a->ip.af == AF_INET ? -1 : +1);
+      return ((a->ip.family == IPv4) ? -1 : +1);
 
-   if (a->ip.af == AF_INET) {
-      return (memcmp(&a->ip.addr.ip, &b->ip.addr.ip, sizeof(a->ip.addr.ip)));
+   if (a->ip.family == IPv4)
+      return (memcmp(&a->ip.ip.v4, &b->ip.ip.v4, sizeof(a->ip.ip.v4)));
+   else {
+      assert(a->ip.family == IPv6);
+      return (memcmp(&a->ip.ip.v6, &b->ip.ip.v6, sizeof(a->ip.ip.v6)));
    }
-
-   /* AF_INET6 should remain.  */
-   if (a->ip.af == AF_INET6)
-      return (memcmp(&a->ip.addr.ip6, &b->ip.addr.ip6, sizeof(a->ip.addr.ip6)));
-
-   /* Last resort.  */
-   return -1;
 }
 
 static RB_HEAD(tree_t, tree_rec) ip_tree = RB_INITIALIZER(&tree_rec);
@@ -117,7 +114,7 @@ static struct tree_rec * tree_t_RB_MINMAX(struct tree_t *head, int val)
 RB_GENERATE(tree_t, tree_rec, ptree, tree_cmp)
 
 void
-dns_queue(const struct addr46 *const ipaddr)
+dns_queue(const struct addr *const ipaddr)
 {
    struct tree_rec *rec;
    ssize_t num_w;
@@ -125,8 +122,8 @@ dns_queue(const struct addr46 *const ipaddr)
    if (pid == -1)
       return; /* no child was started - we're not doing any DNS */
 
-   if (ipaddr->af != AF_INET && ipaddr->af != AF_INET6) {
-      verbosef("dns_queue() for unknown family %d.\n", ipaddr->af);
+   if ((ipaddr->family != IPv4) && (ipaddr->family != IPv6)) {
+      verbosef("dns_queue() for unknown family %d", ipaddr->family);
       return;
    }
 
@@ -136,7 +133,7 @@ dns_queue(const struct addr46 *const ipaddr)
    if (RB_INSERT(tree_t, &ip_tree, rec) != NULL) {
       /* Already queued - this happens seldom enough that we don't care about
        * the performance hit of needlessly malloc()ing. */
-      verbosef("already queued %s", ip_to_str(ipaddr));
+      verbosef("already queued %s", addr_to_str(ipaddr));
       free(rec);
       return;
    }
@@ -151,7 +148,7 @@ dns_queue(const struct addr46 *const ipaddr)
 }
 
 static void
-dns_unqueue(const struct addr46 *const ipaddr)
+dns_unqueue(const struct addr *const ipaddr)
 {
    struct tree_rec tmp, *rec;
 
@@ -161,7 +158,7 @@ dns_unqueue(const struct addr46 *const ipaddr)
       free(rec);
    }
    else
-      verbosef("couldn't unqueue %s - not in queue!", ip_to_str(ipaddr));
+      verbosef("couldn't unqueue %s - not in queue!", addr_to_str(ipaddr));
 }
 
 /*
@@ -169,7 +166,7 @@ dns_unqueue(const struct addr46 *const ipaddr)
  * (name buffer is allocated by dns_poll)
  */
 static int
-dns_get_result(struct addr46 *ipaddr, char **name)
+dns_get_result(struct addr *ipaddr, char **name)
 {
    struct dns_reply reply;
    ssize_t numread;
@@ -196,17 +193,17 @@ dns_get_result(struct addr46 *ipaddr, char **name)
 #else /* !DARKSTAT_USES_HOSTENT */
    if (reply.error != 0) {
       /* Identify common special cases.  */
-      char *type = "none";
+      const char *type = "none";
 
-      if (reply.addr.af == AF_INET6) {
-         if (IN6_IS_ADDR_LINKLOCAL(&reply.addr.addr.ip6))
+      if (reply.addr.family == IPv6) {
+         if (IN6_IS_ADDR_LINKLOCAL(&reply.addr.ip.v6))
             type = "link-local";
-         else if (IN6_IS_ADDR_SITELOCAL(&reply.addr.addr.ip6))
+         else if (IN6_IS_ADDR_SITELOCAL(&reply.addr.ip.v6))
             type = "site-local";
-         else if (IN6_IS_ADDR_MULTICAST(&reply.addr.addr.ip6))
+         else if (IN6_IS_ADDR_MULTICAST(&reply.addr.ip.v6))
             type = "multicast";
       } else { /* AF_INET */
-         if (IN_MULTICAST(reply.addr.addr.ip.s_addr))
+         if (IN_MULTICAST(reply.addr.ip.v4))
             type = "multicast";
       }
       xasprintf(name, "(%s)", type);
@@ -227,7 +224,7 @@ error:
 void
 dns_poll(void)
 {
-   struct addr46 ip;
+   struct addr ip;
    char *name;
 
    if (pid == -1)
@@ -239,12 +236,12 @@ dns_poll(void)
 
       if (b == NULL) {
          verbosef("resolved %s to %s but it's not in the DB!",
-            ip_to_str(&ip), name);
+            addr_to_str(&ip), name);
          return;
       }
       if (b->u.host.dns != NULL) {
          verbosef("resolved %s to %s but it's already in the DB!",
-            ip_to_str(&ip), name);
+            addr_to_str(&ip), name);
          return;
       }
       b->u.host.dns = name;
@@ -255,25 +252,25 @@ dns_poll(void)
 
 struct qitem {
    STAILQ_ENTRY(qitem) entries;
-   struct addr46 ip;
+   struct addr ip;
 };
 
 STAILQ_HEAD(qhead, qitem) queue = STAILQ_HEAD_INITIALIZER(queue);
 
 static void
-enqueue(const struct addr46 *const ip)
+enqueue(const struct addr *const ip)
 {
    struct qitem *i;
 
    i = xmalloc(sizeof(*i));
    memcpy(&i->ip, ip, sizeof(i->ip));
    STAILQ_INSERT_TAIL(&queue, i, entries);
-   verbosef("DNS: enqueued %s", ip_to_str(ip));
+   verbosef("DNS: enqueued %s", addr_to_str(ip));
 }
 
 /* Return non-zero and populate <ip> pointer if queue isn't empty. */
 static int
-dequeue(struct addr46 *ip)
+dequeue(struct addr *ip)
 {
    struct qitem *i;
 
@@ -283,7 +280,7 @@ dequeue(struct addr46 *ip)
    STAILQ_REMOVE_HEAD(&queue, entries);
    memcpy(ip, &i->ip, sizeof(*ip));
    free(i);
-   verbosef("DNS: dequeued %s", ip_to_str(ip));
+   verbosef("DNS: dequeued %s", addr_to_str(ip));
    return 1;
 }
 
@@ -301,7 +298,7 @@ xwrite(const int d, const void *buf, const size_t nbytes)
 static void
 dns_main(void)
 {
-   struct addr46 ip;
+   struct addr ip;
 
 #ifdef HAVE_SETPROCTITLE
    setproctitle("DNS child");
@@ -365,7 +362,7 @@ dns_main(void)
          }
          fd_set_block(sock[CHILD]);
          xwrite(sock[CHILD], &reply, sizeof(reply));
-         verbosef("DNS: %s is %s", ip_to_str(&reply.addr),
+         verbosef("DNS: %s is %s", addr_to_str(&reply.addr),
             (h_errno == 0)?reply.name:hstrerror(h_errno));
 #else /* !DARKSTAT_USES_HOSTENT */
          struct sockaddr_in sin;
@@ -373,29 +370,26 @@ dns_main(void)
          char host[NI_MAXHOST];
          int ret, flags;
 
-         reply.addr.af = ip.af;
+         reply.addr = ip;
          flags = NI_NAMEREQD;
 #  ifdef NI_IDN
          flags |= NI_IDN;
 #  endif
-         switch (ip.af) {
-            case AF_INET:
-               sin.sin_family = ip.af;
-               memcpy(&reply.addr.addr.ip, &ip.addr.ip, sizeof(reply.addr.addr.ip));
-               memcpy(&sin.sin_addr, &ip.addr.ip, sizeof(sin.sin_addr));
+         switch (ip.family) {
+            case IPv4:
+               sin.sin_family = AF_INET;
+               sin.sin_addr.s_addr = ip.ip.v4;
                ret = getnameinfo((struct sockaddr *) &sin, sizeof(sin),
                                  host, sizeof(host), NULL, 0, flags);
                break;
-            case AF_INET6:
-               sin6.sin6_family = ip.af;
-               memcpy(&reply.addr.addr.ip6, &ip.addr.ip6, sizeof(reply.addr.addr.ip6));
-               memcpy(&sin6.sin6_addr, &ip.addr.ip6, sizeof(sin6.sin6_addr));
+            case IPv6:
+               sin6.sin6_family = AF_INET6;
+               memcpy(&sin6.sin6_addr, &ip.ip.v6, sizeof(sin6.sin6_addr));
                ret = getnameinfo((struct sockaddr *) &sin6, sizeof(sin6),
                                  host, sizeof(host), NULL, 0, flags);
                break;
             default:
                ret = EAI_FAMILY;
-
          }
 
          if (ret != 0) {
@@ -408,7 +402,7 @@ dns_main(void)
          }
          fd_set_block(sock[CHILD]);
          xwrite(sock[CHILD], &reply, sizeof(reply));
-         verbosef("DNS: %s is \"%s\".", ip_to_str(&reply.addr),
+         verbosef("DNS: %s is \"%s\".", addr_to_str(&reply.addr),
             (ret == 0) ? reply.name : gai_strerror(ret));
 #endif /* !DARKSTAT_USES_HOSTENT */
       }
diff --git a/dns.h b/dns.h
index f7fdb3c..775f377 100644 (file)
--- a/dns.h
+++ b/dns.h
@@ -7,11 +7,11 @@
  * GNU General Public License version 2. (see COPYING.GPL)
  */
 
-#include "hosts_db.h"   /* addr46 */
+struct addr;
 
 void dns_init(const char *privdrop_user);
 void dns_stop(void);
-void dns_queue(const struct addr46 *const ip);
+void dns_queue(const struct addr *const ipaddr);
 void dns_poll(void);
 
 /* vim:set ts=3 sw=3 tw=78 expandtab: */
index d72fe47..902774f 100644 (file)
@@ -17,6 +17,7 @@
 #include "html.h"
 #include "ncache.h"
 #include "now.h"
+#include "str.h"
 
 #include <arpa/inet.h> /* inet_aton() */
 #include <netdb.h>     /* struct addrinfo */
@@ -102,9 +103,10 @@ coprime(const uint32_t u)
  * src/sys/netinet/tcp_hostcache.c 1.1
  */
 inline static uint32_t
-ipv4_hash(const struct in_addr *const ip)
+ipv4_hash(const struct addr *const a)
 {
-   return ( (ip->s_addr) ^ ((ip->s_addr) >> 7) ^ ((ip->s_addr) >> 17) );
+   uint32_t ip = a->ip.v4;
+   return ( (ip) ^ ((ip) >> 7) ^ ((ip) >> 17) );
 }
 
 #ifndef s6_addr32
@@ -118,31 +120,30 @@ ipv4_hash(const struct in_addr *const ip)
  * svn rev 122922.
  */
 inline static uint32_t
-ipv6_hash(const struct in6_addr *const ip6)
+ipv6_hash(const struct addr *const a)
 {
-   return ( ip6->s6_addr32[0] ^ ip6->s6_addr32[1] ^ ip6->s6_addr32[2] ^ ip6->s6_addr32[3] );
+   const struct in6_addr *const ip6 = &(a->ip.v6);
+   return ( ip6->s6_addr32[0] ^ ip6->s6_addr32[1] ^
+            ip6->s6_addr32[2] ^ ip6->s6_addr32[3] );
 }
 
 /* ---------------------------------------------------------------------------
  * hash_func collection
  */
-#define CASTKEY(type) (*((const type *)key))
-
 static uint32_t
 hash_func_host(const struct hashtable *h _unused_, const void *key)
 {
-   struct addr46 *ip = (struct addr46 *) key;
-
-   switch (ip->af) {
-      case AF_INET:
-         return (ipv4_hash(&ip->addr.ip));
-      case AF_INET6:
-         return (ipv6_hash(&ip->addr.ip6));
-      default:
-         return 0;
+   const struct addr *a = key;
+   if (a->family == IPv4)
+      return (ipv4_hash(a));
+   else {
+      assert(a->family == IPv6);
+      return (ipv6_hash(a));
    }
 }
 
+#define CASTKEY(type) (*((const type *)key))
+
 static uint32_t
 hash_func_short(const struct hashtable *h, const void *key)
 {
@@ -162,7 +163,7 @@ hash_func_byte(const struct hashtable *h, const void *key)
 static const void *
 key_func_host(const struct bucket *b)
 {
-   return &(b->u.host.ipaddr);
+   return &(b->u.host.addr);
 }
 
 static const void *
@@ -190,23 +191,7 @@ key_func_ip_proto(const struct bucket *b)
 static int
 find_func_host(const struct bucket *b, const void *key)
 {
-   struct addr46 *ipaddr = (struct addr46 *) key;
-
-   if (b->u.host.ipaddr.af != ipaddr->af)
-      return 0; /* not comparable */
-
-   switch (ipaddr->af) {
-      case AF_INET:
-         return (memcmp(&b->u.host.ipaddr.addr.ip,
-                        &ipaddr->addr.ip, sizeof(ipaddr->addr.ip))
-                  == 0);
-      case AF_INET6:
-         return (memcmp(&b->u.host.ipaddr.addr.ip6,
-                        &ipaddr->addr.ip6, sizeof(ipaddr->addr.ip6))
-                  == 0);
-      default:
-         return 0;
-   }
+   return (addr_equal(key, &(b->u.host.addr)));
 }
 
 static int
@@ -244,7 +229,7 @@ static struct bucket *
 make_func_host(const void *key)
 {
    MAKE_BUCKET(b, h, host);
-   memcpy(&h->ipaddr, key, sizeof(h->ipaddr));
+   h->addr = CASTKEY(struct addr);
    h->dns = NULL;
    h->last_seen = now;
    memset(&h->mac_addr, 0, sizeof(h->mac_addr));
@@ -327,7 +312,7 @@ static void
 format_row_host(struct str *buf, const struct bucket *b,
    const char *css_class)
 {
-   const char *ip = ip_to_str( &b->u.host.ipaddr );
+   const char *ip = addr_to_str(&(b->u.host.addr));
 
    str_appendf(buf,
       "<tr class=\"%s\">\n"
@@ -377,7 +362,7 @@ format_row_host(struct str *buf, const struct bucket *b,
 
    /* Only resolve hosts "on demand" */
    if (b->u.host.dns == NULL)
-      dns_queue(&b->u.host.ipaddr);
+      dns_queue(&(b->u.host.addr));
 }
 
 static void
@@ -657,18 +642,18 @@ hashtable_free(struct hashtable *h)
  * Return existing host or insert a new one.
  */
 struct bucket *
-host_get(const struct addr46 *const ip)
+host_get(const struct addr *const a)
 {
-   return (hashtable_find_or_insert(hosts_db, ip));
+   return (hashtable_find_or_insert(hosts_db, a));
 }
 
 /* ---------------------------------------------------------------------------
  * Find host, returns NULL if not in DB.
  */
 struct bucket *
-host_find(const struct addr46 *const ip)
+host_find(const struct addr *const a)
 {
-   return (hashtable_search(hosts_db, ip));
+   return (hashtable_search(hosts_db, a));
 }
 
 /* ---------------------------------------------------------------------------
@@ -677,8 +662,7 @@ host_find(const struct addr46 *const ip)
 static struct bucket *
 host_search(const char *ipstr)
 {
-   struct addr46 ipaddr;
-   struct sockaddr_storage ss;
+   struct addr a;
    struct addrinfo hints, *ai;
 
    memset(&hints, 0, sizeof(hints));
@@ -688,24 +672,23 @@ host_search(const char *ipstr)
    if (getaddrinfo(ipstr, NULL, &hints, &ai))
       return (NULL); /* invalid addr */
 
-   memcpy(&ss, ai->ai_addr, ai->ai_addrlen);
-   freeaddrinfo(ai);
-
-   ipaddr.af = ss.ss_family;
-   switch (ss.ss_family) {
-      case AF_INET:
-         memcpy(&ipaddr.addr.ip, &((struct sockaddr_in *) &ss)->sin_addr,
-               sizeof(ipaddr.addr.ip));
-         break;
-      case AF_INET6:
-         memcpy(&ipaddr.addr.ip6, &((struct sockaddr_in6 *) &ss)->sin6_addr,
-               sizeof(ipaddr.addr.ip6));
-         break;
-      default:
-         return (NULL);
+   if (ai->ai_family == AF_INET) {
+      a.family = IPv4;
+      a.ip.v4 = ((const struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr;
+   }
+   else if (ai->ai_family == AF_INET6) {
+      a.family = IPv6;
+      memcpy(&(a.ip.v6),
+             ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr,
+             sizeof(a.ip.v6));
+   } else {
+      freeaddrinfo(ai);
+      return (NULL); /* unknown family */
    }
+   freeaddrinfo(ai);
 
-   return (hashtable_search(hosts_db, &ipaddr));
+   verbosef("search(%s) turned into %s", ipstr, addr_to_str(&a));
+   return (hashtable_search(hosts_db, &a));
 }
 
 /* ---------------------------------------------------------------------------
@@ -1030,38 +1013,42 @@ html_hosts_detail(const char *ip)
    struct bucket *h;
    struct str *buf, *ls_len;
    char ls_when[100];
+   const char *canonical;
    time_t ls;
 
    h = host_search(ip);
    if (h == NULL)
       return (NULL); /* no such host */
 
+   canonical = addr_to_str(&(h->u.host.addr));
+
    /* Overview. */
    buf = str_make();
    str_append(buf, html_header_1);
    str_appendf(buf, " <title>%s</title>\n", ip);
    str_append(buf, html_header_2);
+   str_appendf(buf, "<h2>%s</h2>\n", ip);
+   if (strcmp(ip, canonical) != 0)
+      str_appendf(buf, "(canonically <b>%s</b>)\n", canonical);
    str_appendf(buf,
-      "<h2>%s</h2>\n"
       "<p>\n"
        "<b>Hostname:</b> %s<br/>\n",
-      ip,
       (h->u.host.dns == NULL)?"(resolving...)":h->u.host.dns);
 
    /* Resolve host "on demand" */
    if (h->u.host.dns == NULL)
-      dns_queue(&h->u.host.ipaddr);
+      dns_queue(&(h->u.host.addr));
 
    if (show_mac_addrs)
-   str_appendf(buf,
-      "<b>MAC Address:</b> "
-      "<tt>%x:%x:%x:%x:%x:%x</tt><br/>\n",
-      h->u.host.mac_addr[0],
-      h->u.host.mac_addr[1],
-      h->u.host.mac_addr[2],
-      h->u.host.mac_addr[3],
-      h->u.host.mac_addr[4],
-      h->u.host.mac_addr[5]);
+      str_appendf(buf,
+         "<b>MAC Address:</b> "
+         "<tt>%x:%x:%x:%x:%x:%x</tt><br/>\n",
+         h->u.host.mac_addr[0],
+         h->u.host.mac_addr[1],
+         h->u.host.mac_addr[2],
+         h->u.host.mac_addr[3],
+         h->u.host.mac_addr[4],
+         h->u.host.mac_addr[5]);
 
    str_append(buf,
       "</p>\n"
@@ -1226,7 +1213,7 @@ static int
 hosts_db_import_host(const int fd)
 {
    struct bucket *host;
-   struct addr46 ipaddr;
+   struct addr a;
    uint8_t hostname_len;
    uint64_t in, out;
    unsigned int pos = xtell(fd);
@@ -1244,11 +1231,10 @@ hosts_db_import_host(const int fd)
       return 0;
    }
 
-   ipaddr.af = AF_INET;
-   if (!readaddr(fd, &ipaddr)) return 0;
-   verbosef("at file pos %u, importing host %s", pos, ip_to_str(&ipaddr));
-   host = host_get(&ipaddr);
-   assert(host->u.host.ipaddr.addr.ip.s_addr == ipaddr.addr.ip.s_addr); /* make fn? */
+   if (!readaddr(fd, &a)) return 0;
+   verbosef("at file pos %u, importing host %s", pos, addr_to_str(&a));
+   host = host_get(&a);
+   assert(addr_equal(&(host->u.host.addr), &a));
 
    if (ver > 1) {
       uint64_t t;
@@ -1326,7 +1312,7 @@ int hosts_db_export(const int fd)
       if (!writen(fd, export_tag_host_ver2, sizeof(export_tag_host_ver2)))
          return 0;
 
-      if (!writeaddr(fd, &b->u.host.ipaddr)) return 0;
+      if (!writeaddr(fd, &(b->u.host.addr))) return 0;
 
       if (!write64(fd, (uint64_t)(b->u.host.last_seen))) return 0;
 
index 4b324ba..f9ed169 100644 (file)
@@ -9,23 +9,12 @@
 #ifndef __DARKSTAT_HOSTS_DB_H
 #define __DARKSTAT_HOSTS_DB_H
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "str.h"
-
-struct addr46 {
-   sa_family_t af;
-   union {
-      struct in_addr ip;
-      struct in6_addr ip6;
-   } addr;
-};
+#include "addr.h"
 
 struct hashtable;
 
 struct host {
-   struct addr46 ipaddr;
+   struct addr addr;
    char *dns;
    uint8_t mac_addr[6];
    time_t last_seen;
@@ -73,8 +62,8 @@ void hosts_db_free(void);
 int hosts_db_import(const int fd);
 int hosts_db_export(const int fd);
 
-struct bucket *host_find(const struct addr46 *const ip); /* can return NULL */
-struct bucket *host_get(const struct addr46 *const ip);
+struct bucket *host_find(const struct addr *const a); /* can return NULL */
+struct bucket *host_get(const struct addr *const a);
 struct bucket *host_get_port_tcp(struct bucket *host, const uint16_t port);
 struct bucket *host_get_port_udp(struct bucket *host, const uint16_t port);
 struct bucket *host_get_ip_proto(struct bucket *host, const uint8_t proto);
index 2980bc9..33f5a71 100644 (file)
--- a/localip.c
+++ b/localip.c
@@ -8,8 +8,8 @@
  */
 
 #include "darkstat.h"
+#include "addr.h"
 #include "conv.h" /* for strlcpy */
-#include "decode.h" /* for ip_to_str */
 #include "err.h"
 #include "localip.h"
 
 #include <unistd.h>
 
 static const char *iface = NULL;
-
-struct in_addr localip = { 0 };
-static struct in_addr last_localip = { 0 };
-
-struct in6_addr localip6;
-static struct in6_addr last_localip6;
+struct addr localip4, localip6;
+static struct addr last_localip4, last_localip6;
 
 void
 localip_init(const char *interface)
@@ -39,15 +35,15 @@ void
 localip_update(void)
 {
    struct ifaddrs *ifas, *ifa;
-   int flags = 0;
+   int got_v4 = 0, got_v6 = 0;
 
-#define HAS_IPV4  0x01
-#define HAS_IPV6  0x02
+   localip4.family = IPv4;
+   localip6.family = IPv6;
 
    if (iface == NULL) {
       /* reading from capfile */
-      memset(&localip, 0, sizeof(localip));
-      memset(&localip6, 0, sizeof(localip6));
+      localip4.ip.v4 = 0;
+      memset(&(localip6.ip.v6), 0, sizeof(localip6.ip.v6));
       return;
    }
 
@@ -55,18 +51,19 @@ localip_update(void)
       err(1, "can't get own IP address on interface \"%s\"", iface);
 
    for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
-      if (flags == (HAS_IPV4 | HAS_IPV6))
+      if (got_v4 && got_v6)
          break;   /* Task is already complete. */
 
       if (strncmp(ifa->ifa_name, iface, IFNAMSIZ))
          continue;   /* Wrong interface. */
 
       /* The first IPv4 name is always functional. */
-      if ( (ifa->ifa_addr->sa_family == AF_INET)
-            && ! (flags & HAS_IPV4) ) {
+      if ((ifa->ifa_addr->sa_family == AF_INET) && !got_v4)
+      {
          /* Good IPv4 address. */
-         localip.s_addr = ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr.s_addr;
-         flags |= HAS_IPV4;
+         localip4.ip.v4 =
+            ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
+         got_v4 = 1;
          continue;
       }
 
@@ -77,41 +74,26 @@ localip_update(void)
          if ( IN6_IS_ADDR_LINKLOCAL(&(sa6->sin6_addr))
               || IN6_IS_ADDR_SITELOCAL(&(sa6->sin6_addr)) )
             continue;
-         else
-            /* Only standard IPv6 can reach this point. */
-            memcpy(&localip6, &sa6->sin6_addr, sizeof(localip6));
-            flags |= HAS_IPV6;
+
+         /* Only standard IPv6 can reach this point. */
+         memcpy(&(localip6.ip.v6), &sa6->sin6_addr, sizeof(localip6.ip.v6));
+         got_v6 = 1;
       }
    }
 
    freeifaddrs(ifas);
 
-   /* Repport an error if IPv4 address could not be found. */
-   if ( !(flags & HAS_IPV4) )
+   /* Report an error if IPv4 address could not be found. */
+   if (!got_v4)
        err(1, "can't get own IPv4 address on interface \"%s\"", iface);
 
-   /* struct sockaddr {
-    *      sa_family_t     sa_family;      * address family, AF_xxx
-    *      char            sa_data[14];    * 14 bytes of protocol address
-    *
-    * struct sockaddr_in {
-    *      sa_family_t           sin_family;     * Address family
-    *      unsigned short int    sin_port;       * Port number
-    *      struct in_addr        sin_addr;       * Internet address
-    *
-    * struct in_addr {
-    *      __u32   s_addr;
-    */
-
-   if (last_localip.s_addr != localip.s_addr) {
-      verbosef("local_ip update(%s) = %s", iface,
-               ip_to_str_af(&localip, AF_INET));
-      memcpy(&last_localip, &localip, sizeof(last_localip));
+   if (!addr_equal(&last_localip4, &localip4)) {
+      verbosef("localip4 update(%s) = %s", iface, addr_to_str(&localip4));
+      last_localip4 = localip4;
    }
-   if (memcmp(&last_localip6, &localip6, sizeof(localip6))) {
-      verbosef("local_ip6 update(%s) = %s", iface,
-               ip_to_str_af(&localip6, AF_INET6));
-      memcpy(&last_localip6, &localip6, sizeof(localip6));
+   if (!addr_equal(&last_localip6, &localip6)) {
+      verbosef("localip6 update(%s) = %s", iface, addr_to_str(&localip6));
+      last_localip6 = localip6;
    }
 }
 
index a16a6a9..37c5649 100644 (file)
--- a/localip.h
+++ b/localip.h
@@ -7,10 +7,7 @@
  * GNU General Public License version 2. (see COPYING.GPL)
  */
 
-#include <netinet/in.h> /* for in_addr, in6_addr */
-
-extern struct in_addr localip;
-extern struct in6_addr localip6;
+extern struct addr localip4, localip6;
 
 void localip_init(const char *interface);
 void localip_update(void);