Implement export/import of struct addr.
authorEmil Mikulic <emikulic@gmail.com>
Sun, 15 May 2011 09:09:47 +0000 (19:09 +1000)
committerEmil Mikulic <emikulic@gmail.com>
Sat, 28 May 2011 10:10:53 +0000 (20:10 +1000)
db.c
db.h
export-format.txt
hosts_db.c

diff --git a/db.c b/db.c
index 7dd7901..37f90d8 100644 (file)
--- a/db.c
+++ b/db.c
@@ -152,18 +152,37 @@ read32(const int fd, uint32_t *dest)
    return 1;
 }
 
+/* Read an IPv4 addr from a file.  This is for backward compatibility with
+ * host records version 1 and 2.
+ */
+int
+readaddr_ipv4(const int fd, struct addr *dest)
+{
+   dest->family = IPv4;
+   return readn(fd, &(dest->ip.v4), sizeof(dest->ip.v4));
+}
+
 /* 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?)
  */
 int
 readaddr(const int fd, struct addr *dest)
 {
-   assert(dest->family == IPv4 || dest->family == AF_INET6);
+   unsigned char family;
+
+   if (!read8(fd, &family))
+      return 0;
 
-   if (dest->family == IPv4)
+   if (family == 4) {
+      dest->family = IPv4;
       return readn(fd, &(dest->ip.v4), sizeof(dest->ip.v4));
-   else
+   }
+   else if (family == 6) {
+      dest->family = IPv6;
       return readn(fd, dest->ip.v6.s6_addr, sizeof(dest->ip.v6.s6_addr));
+   }
+   else
+      return 0; /* no address family I ever heard of */
 }
 
 /* Read a network order uint64_t from a file
@@ -248,6 +267,9 @@ write64(const int fd, const uint64_t i)
 int
 writeaddr(const int fd, const struct addr *const a)
 {
+   if (!write8(fd, a->family))
+      return 0;
+
    if (a->family == IPv4)
       return writen(fd, &(a->ip.v4), sizeof(a->ip.v4));
    else {
diff --git a/db.h b/db.h
index 866b17c..05ce06a 100644 (file)
--- a/db.h
+++ b/db.h
@@ -25,6 +25,7 @@ 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 read64(const int fd, uint64_t *dest);
+int readaddr_ipv4(const int fd, struct addr *dest);
 int readaddr(const int fd, struct addr *dest);
 int read_file_header(const int fd, const uint8_t expected[4]);
 
index 11d7978..7f10efb 100644 (file)
@@ -5,8 +5,12 @@ FILE HEADER 0xDA314159                              darkstat export format
     SECTION HEADER 0xDA 'H' 'S' 0x01                hosts_db ver1
         HOST COUNT 0x00000001                       1 host follows
         For each host:
-            HOST HEADER 'H' 'S' 'T' 0x02            host ver2
-            IP ADDR 0x0A010101                      IPv4 10.1.1.1
+            HOST HEADER 'H' 'S' 'T' 0x03            host ver3
+            ADDRESS FAMILY 0x04                     Either 4 or 6.
+              IPv4 ADDR 0x0A010101                  IPv4 10.1.1.1
+              or for 0x06:
+              IPv6 ADDR 0x0000 0000 0000 0000 0000 0000 0000 0001
+                                                    meaning IPv6 ::1
             MACADDR 0x001122334455                  00:11:22:33:44:55
             LAST_SEEN 0x0000000048000123 (time_t)   2008-04-12 00:24:03 UTC
             HOSTNAME 0x09 "localhost"               9 is the string length
@@ -44,3 +48,6 @@ FILE HEADER 0xDA314159                              darkstat export format
                 64 bits - bytes out
 
 Host header version 1 is just version 2 without the last_seen time.
+
+Host header version 2 is just version 3 without the address family
+byte (or the possibility of an IPv6 address).
index ce465fd..3f57672 100644 (file)
@@ -1117,7 +1117,8 @@ static const char
 
 static const unsigned char
    export_tag_host_ver1[] = {'H', 'S', 'T', 0x01},
-   export_tag_host_ver2[] = {'H', 'S', 'T', 0x02};
+   export_tag_host_ver2[] = {'H', 'S', 'T', 0x02},
+   export_tag_host_ver3[] = {'H', 'S', 'T', 0x03};
 
 /* ---------------------------------------------------------------------------
  * Load a host's ip_proto table from a file.
@@ -1230,7 +1231,9 @@ hosts_db_import_host(const int fd)
    int ver = 0;
 
    if (!readn(fd, hdr, sizeof(hdr))) return 0;
-   if (memcmp(hdr, export_tag_host_ver2, sizeof(hdr)) == 0)
+   if (memcmp(hdr, export_tag_host_ver3, sizeof(hdr)) == 0)
+      ver = 3;
+   else if (memcmp(hdr, export_tag_host_ver2, sizeof(hdr)) == 0)
       ver = 2;
    else if (memcmp(hdr, export_tag_host_ver1, sizeof(hdr)) == 0)
       ver = 1;
@@ -1240,7 +1243,14 @@ hosts_db_import_host(const int fd)
       return 0;
    }
 
-   if (!readaddr(fd, &a)) return 0;
+   if (ver == 3) {
+      if (!readaddr(fd, &a))
+         return 0;
+   } else {
+      assert((ver == 1) || (ver == 2));
+      if (!readaddr_ipv4(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));
@@ -1318,7 +1328,7 @@ int hosts_db_export(const int fd)
    for (i = 0; i<hosts_db->size; i++)
    for (b = hosts_db->table[i]; b != NULL; b = b->next) {
       /* For each host: */
-      if (!writen(fd, export_tag_host_ver2, sizeof(export_tag_host_ver2)))
+      if (!writen(fd, export_tag_host_ver3, sizeof(export_tag_host_ver3)))
          return 0;
 
       if (!writeaddr(fd, &(b->u.host.addr))) return 0;