Define ETHERTYPE_IPV6 ourselves.
[darkstat] / hosts_db.c
index 954daba..754dacc 100644 (file)
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2009 Emil Mikulic.
+ * copyright (c) 2001-2011 Emil Mikulic.
  *
  * hosts_db.c: database of hosts, ports, protocols.
  *
@@ -7,7 +7,7 @@
  * GNU General Public License version 2. (see COPYING.GPL)
  */
 
-#include "darkstat.h"
+#include "cdefs.h"
 #include "conv.h"
 #include "decode.h"
 #include "dns.h"
@@ -17,9 +17,9 @@
 #include "html.h"
 #include "ncache.h"
 #include "now.h"
+#include "opt.h"
 #include "str.h"
 
-#include <arpa/inet.h> /* inet_aton() */
 #include <netdb.h>     /* struct addrinfo */
 #include <assert.h>
 #include <errno.h>
@@ -28,9 +28,7 @@
 #include <string.h> /* memset(), strcmp() */
 #include <unistd.h>
 
-extern int want_lastseen;
-int show_mac_addrs = 0;
-extern const char *interface;
+int hosts_db_show_macs = 0;
 
 /* FIXME: specify somewhere more sane/tunable */
 #define MAX_ENTRIES 30 /* in an HTML table rendered from a hashtable */
@@ -110,9 +108,16 @@ ipv4_hash(const struct addr *const a)
 }
 
 #ifndef s6_addr32
+# ifdef sun
+/*
+ * http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/netinet/in.h#130
+ */
+#  define s6_addr32 _S6_un._S6_u32
+# else
 /* Covers OpenBSD and FreeBSD.  The macro __USE_GNU has
  * taken care of GNU/Linux and GNU/kfreebsd.  */
-# define s6_addr32 __u6_addr.__u6_addr32
+#  define s6_addr32 __u6_addr.__u6_addr32
+# endif
 #endif
 
 /*
@@ -231,7 +236,7 @@ make_func_host(const void *key)
    MAKE_BUCKET(b, h, host);
    h->addr = CASTKEY(struct addr);
    h->dns = NULL;
-   h->last_seen = now;
+   h->lastseen = 0;
    memset(&h->mac_addr, 0, sizeof(h->mac_addr));
    h->ports_tcp = NULL;
    h->ports_udp = NULL;
@@ -296,13 +301,13 @@ format_cols_host(struct str *buf)
       "<tr>\n"
       " <th>IP</th>\n"
       " <th>Hostname</th>\n");
-   if (show_mac_addrs) str_append(buf,
+   if (hosts_db_show_macs) str_append(buf,
       " <th>MAC Address</th>\n");
    str_append(buf,
       " <th><a href=\"?sort=in\">In</a></th>\n"
       " <th><a href=\"?sort=out\">Out</a></th>\n"
       " <th><a href=\"?sort=total\">Total</a></th>\n");
-   if (want_lastseen) str_append(buf,
+   if (opt_want_lastseen) str_append(buf,
       " <th><a href=\"?sort=lastseen\">Last seen</a></th>\n");
    str_append(buf,
       "</tr>\n");
@@ -316,13 +321,13 @@ format_row_host(struct str *buf, const struct bucket *b,
 
    str_appendf(buf,
       "<tr class=\"%s\">\n"
-      " <td><a href=\"/hosts/%s/\">%s</a></td>\n"
+      " <td><a href=\"./%s/\">%s</a></td>\n"
       " <td>%s</td>\n",
       css_class,
       ip, ip,
       (b->u.host.dns == NULL) ? "" : b->u.host.dns);
 
-   if (show_mac_addrs)
+   if (hosts_db_show_macs)
       str_appendf(buf,
          " <td><tt>%x:%x:%x:%x:%x:%x</tt></td>\n",
          b->u.host.mac_addr[0],
@@ -338,20 +343,23 @@ format_row_host(struct str *buf, const struct bucket *b,
       " <td class=\"num\">%'qu</td>\n",
       b->in, b->out, b->total);
 
-   if (want_lastseen) {
-      time_t last_t = b->u.host.last_seen;
-      struct str *lastseen = NULL;
+   if (opt_want_lastseen) {
+      time_t last_t = b->u.host.lastseen;
+      struct str *last_str = NULL;
 
-      if (now >= last_t)
-         lastseen = length_of_time(now - last_t);
+      if ((now >= last_t) && (last_t > 0))
+         last_str = length_of_time(now - last_t);
 
       str_append(buf,
          " <td class=\"num\">");
-      if (lastseen == NULL)
-         str_append(buf, "(clock error)");
-      else {
-         str_appendstr(buf, lastseen);
-         str_free(lastseen);
+      if (last_str == NULL) {
+         if (last_t == 0)
+            str_append(buf, "(never)");
+         else
+            str_append(buf, "(clock error)");
+      } else {
+         str_appendstr(buf, last_str);
+         str_free(last_str);
       }
       str_append(buf,
          "</td>");
@@ -515,7 +523,7 @@ void
 hosts_db_init(void)
 {
    assert(hosts_db == NULL);
-   hosts_db = hashtable_make(HOST_BITS, hosts_max, hosts_keep,
+   hosts_db = hashtable_make(HOST_BITS, opt_hosts_max, opt_hosts_keep,
       hash_func_host, free_func_host, key_func_host, find_func_host,
       make_func_host, format_cols_host, format_row_host);
 }
@@ -806,7 +814,7 @@ host_get_port_tcp(struct bucket *host, const uint16_t port)
    struct host *h = &host->u.host;
    assert(h != NULL);
    if (h->ports_tcp == NULL)
-      h->ports_tcp = hashtable_make(PORT_BITS, ports_max, ports_keep,
+      h->ports_tcp = hashtable_make(PORT_BITS, opt_ports_max, opt_ports_keep,
          hash_func_short, free_func_simple, key_func_port_tcp,
          find_func_port_tcp, make_func_port_tcp,
          format_cols_port_tcp, format_row_port_tcp);
@@ -822,7 +830,7 @@ host_get_port_udp(struct bucket *host, const uint16_t port)
    struct host *h = &host->u.host;
    assert(h != NULL);
    if (h->ports_udp == NULL)
-      h->ports_udp = hashtable_make(PORT_BITS, ports_max, ports_keep,
+      h->ports_udp = hashtable_make(PORT_BITS, opt_ports_max, opt_ports_keep,
          hash_func_short, free_func_simple, key_func_port_udp,
          find_func_port_udp, make_func_port_udp,
          format_cols_port_udp, format_row_port_udp);
@@ -855,7 +863,7 @@ static struct str *html_hosts_detail(const char *ip);
 struct str *
 html_hosts(const char *uri, const char *query)
 {
-   int i, num_elems;
+   unsigned int i, num_elems;
    char **elem = split('/', uri, &num_elems);
    struct str *buf = NULL;
 
@@ -880,11 +888,11 @@ html_hosts(const char *uri, const char *query)
  * Format hashtable into HTML.
  */
 static void
-format_table(struct str *buf, struct hashtable *ht, int start,
+format_table(struct str *buf, struct hashtable *ht, unsigned int start,
    const enum sort_dir sort, const int full)
 {
    const struct bucket **table;
-   uint32_t i, pos, end;
+   unsigned int i, pos, end;
    int alt = 0;
 
    if ((ht == NULL) || (ht->count == 0)) {
@@ -908,7 +916,7 @@ format_table(struct str *buf, struct hashtable *ht, int start,
       start = 0;
       end = ht->count;
    } else
-      end = min(ht->count, (uint32_t)start+MAX_ENTRIES);
+      end = MIN(ht->count, (uint32_t)start+MAX_ENTRIES);
 
    str_appendf(buf, "(%u-%u of %u)<br>\n", start+1, end, ht->count);
    qsort_buckets(table, ht->count, start, end, sort);
@@ -974,14 +982,16 @@ html_hosts_main(const char *qs)
 #define NEXT "next page &gt;&gt;&gt;"
 #define FULL "full table"
 
-   html_open(buf, "Hosts", interface, NULL);
+   html_open(buf, "Hosts", /*path_depth=*/1, /*want_graph_js=*/0);
    format_table(buf, hosts_db, start, sort, full);
 
    /* <prev | full | stats | next> */
    sortstr = qs_sort;
    if (sortstr == NULL) sortstr = "total";
    if (start > 0) {
-      int prev = max(start - MAX_ENTRIES, 0);
+      int prev = start - MAX_ENTRIES;
+      if (prev < 0)
+         prev = 0;
       str_appendf(buf, "<a href=\"?start=%d&sort=%s\">" PREV "</a>",
          prev, sortstr);
    } else
@@ -1031,7 +1041,7 @@ html_hosts_detail(const char *ip)
 
    /* Overview. */
    buf = str_make();
-   html_open(buf, ip, interface, NULL);
+   html_open(buf, ip, /*path_depth=*/2, /*want_graph_js=*/0);
    if (strcmp(ip, canonical) != 0)
       str_appendf(buf, "(canonically <b>%s</b>)\n", canonical);
    str_appendf(buf,
@@ -1043,7 +1053,7 @@ html_hosts_detail(const char *ip)
    if (h->u.host.dns == NULL)
       dns_queue(&(h->u.host.addr));
 
-   if (show_mac_addrs)
+   if (hosts_db_show_macs)
       str_appendf(buf,
          "<b>MAC Address:</b> "
          "<tt>%x:%x:%x:%x:%x:%x</tt><br>\n",
@@ -1059,13 +1069,13 @@ html_hosts_detail(const char *ip)
       "<p>\n"
       "<b>Last seen:</b> ");
 
-   ls = h->u.host.last_seen;
+   ls = h->u.host.lastseen;
    if (strftime(ls_when, sizeof(ls_when),
       "%Y-%m-%d %H:%M:%S %Z%z", localtime(&ls)) != 0)
          str_append(buf, ls_when);
 
-   if (h->u.host.last_seen <= now) {
-      ls_len = length_of_time(now - h->u.host.last_seen);
+   if (h->u.host.lastseen <= now) {
+      ls_len = length_of_time(now - h->u.host.lastseen);
       str_append(buf, " (");
       str_appendstr(buf, ls_len);
       str_free(ls_len);
@@ -1099,7 +1109,7 @@ html_hosts_detail(const char *ip)
 /* ---------------------------------------------------------------------------
  * Database import and export code:
  * Initially written and contributed by Ben Stewart.
- * copyright (c) 2007 Ben Stewart, Emil Mikulic.
+ * copyright (c) 2007-2011 Ben Stewart, Emil Mikulic.
  */
 static int hosts_db_export_ip(const struct hashtable *h, const int fd);
 static int hosts_db_export_tcp(const struct hashtable *h, const int fd);
@@ -1253,7 +1263,7 @@ hosts_db_import_host(const int fd)
    if (ver > 1) {
       uint64_t t;
       if (!read64(fd, &t)) return 0;
-      host->u.host.last_seen = (time_t)t;
+      host->u.host.lastseen = (time_t)t;
    }
 
    assert(sizeof(host->u.host.mac_addr) == 6);
@@ -1328,7 +1338,7 @@ int hosts_db_export(const int fd)
 
       if (!writeaddr(fd, &(b->u.host.addr))) return 0;
 
-      if (!write64(fd, (uint64_t)(b->u.host.last_seen))) return 0;
+      if (!write64(fd, (uint64_t)(b->u.host.lastseen))) return 0;
 
       assert(sizeof(b->u.host.mac_addr) == 6);
       if (!writen(fd, b->u.host.mac_addr, sizeof(b->u.host.mac_addr)))