Small IPv6 corrections and an IPv6 hash function.
authorMats Erik Andersson <debian@gisladisker.se>
Wed, 29 Sep 2010 21:46:11 +0000 (23:46 +0200)
committerEmil Mikulic <emikulic@gmail.com>
Mon, 9 May 2011 12:40:33 +0000 (22:40 +1000)
decode.c
decode.h
hosts_db.c
hosts_db.h

index 925c50d..344439a 100644 (file)
--- a/decode.c
+++ b/decode.c
@@ -120,13 +120,14 @@ getlinkhdr(int linktype)
 
 /*
  * Returns the minimum snaplen needed to decode everything up to the TCP/UDP
- * packet headers.  Argument lh is not allowed to be NULL.
+ * packet headers.  The IPv6 header is normative.  The argument lh is not
+ * allowed to be NULL.
  */
 int
 getsnaplen(const linkhdr_t *lh)
 {
    assert(lh != NULL);
-   return (lh->hdrlen + IP_HDR_LEN + max(TCP_HDR_LEN, UDP_HDR_LEN));
+   return (lh->hdrlen + IPV6_HDR_LEN + max(TCP_HDR_LEN, UDP_HDR_LEN));
 }
 
 /*
@@ -361,7 +362,7 @@ decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
       return;
    }
    if (hdr->ip_v != 4) {
-      verbosef("ip: version %d (expecting 4)", hdr->ip_v);
+      verbosef("ip: version %d (expecting 4 or 6)", hdr->ip_v);
       return;
    }
 
index 5e70dad..10f443c 100644 (file)
--- a/decode.h
+++ b/decode.h
@@ -9,6 +9,7 @@
 
 #include <pcap.h>
 #include <netinet/in_systm.h>  /* n_time */
+#define __USE_GNU 1
 #include <netinet/in.h> /* in_addr_t */
 #include <netinet/ip.h> /* struct ip */
 
@@ -50,7 +51,7 @@ typedef struct {
    };
    time_t time;
    uint16_t len;
-   uint8_t af;                   /* AF_{UNSPEC, INET, INET6} */
+   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 */
index cf90b6f..4228d82 100644 (file)
@@ -106,6 +106,22 @@ ipv4_hash(const uint32_t ip)
    return ( (ip) ^ ((ip) >> 7) ^ ((ip) >> 17) );
 }
 
+#ifndef s6_addr32
+/* Covers OpenBSD and FreeBSD.  The macro __USE_GNU has
+ * taken care of GNU/Linux and GNU/kfreebsd.  */
+# define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
+/*
+ * This is the IPv6 hash function used by FreeBSD in the same file as above,
+ * svn rev 122922.
+ */
+inline static uint32_t
+ipv6_hash(const struct in6_addr *const ip6)
+{
+   return ( ip6->s6_addr32[0] ^ ip6->s6_addr32[1] ^ ip6->s6_addr32[2] ^ ip6->s6_addr32[3] );
+}
+
 /* ---------------------------------------------------------------------------
  * hash_func collection
  */
@@ -193,7 +209,7 @@ find_func_ip_proto(const struct bucket *b, const void *key)
    struct bucket *next; \
    uint64_t in, out, total; \
    union { struct type t; } u; } _custom_bucket; \
-   struct bucket *name_bucket = xmalloc(sizeof(_custom_bucket)); \
+   struct bucket *name_bucket = xcalloc(1, sizeof(_custom_bucket)); \
    struct type *name_content = &(name_bucket->u.type); \
    name_bucket->next = NULL; \
    name_bucket->in = name_bucket->out = name_bucket->total = 0;
@@ -655,7 +671,7 @@ hashtable_reduce(struct hashtable *ht)
    assert(ht->count_keep < ht->count);
 
    /* Fill table with pointers to buckets in hashtable. */
-   table = xmalloc(sizeof(*table) * ht->count);
+   table = xcalloc(ht->count, sizeof(*table));
    for (pos=0, i=0; i<ht->size; i++) {
       struct bucket *b = ht->table[i];
       while (b != NULL) {
@@ -835,7 +851,7 @@ format_table(struct str *buf, struct hashtable *ht, int start,
    }
 
    /* Fill table with pointers to buckets in hashtable. */
-   table = xmalloc(sizeof(*table) * ht->count);
+   table = xcalloc(ht->count, sizeof(*table));
    for (pos=0, i=0; i<ht->size; i++) {
       struct bucket *b = ht->table[i];
       while (b != NULL) {
index a5686a1..41141be 100644 (file)
 struct hashtable;
 
 struct host {
-   in_addr_t ip;
+   union {
+      in_addr_t ip;
+      struct in6_addr ip6;
+   };
+   sa_family_t af;
    char *dns;
    uint8_t mac_addr[6];
    time_t last_seen;