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
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 {
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]);
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
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).
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.
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;
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));
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;