1 /* ircd_in_addr_t.c - Test file for IP address manipulation */
4 #include "ircd_string.h"
9 #include <netinet/in.h>
11 /** Structure to describe a test for IP address parsing and unparsing. */
13 const char *text; /**< Textual address to parse. */
14 const char *canonical; /**< Canonical form of address. */
15 struct irc_in_addr expected; /**< Parsed address. */
16 const char *base64_v4; /**< v4-only compatible base64 encoding. */
17 const char *base64_v6; /**< v6-compatible base64 encoding. */
18 unsigned int is_valid : 1; /**< is address valid? */
19 unsigned int is_ipv4 : 1; /**< is address ipv4? */
20 unsigned int is_loopback : 1; /**< is address loopback? */
23 /** Array of addresses to test with. */
24 static struct address_test test_addrs[] = {
26 {{ 0, 0, 0, 0, 0, 0, 0, 0 }},
27 "AAAAAA", "_", 0, 0, 0 },
29 {{ 0, 0, 0, 0, 0, 0, 0, 1 }},
30 "AAAAAA", "_AAB", 1, 0, 1 },
31 { "127.0.0.1", "127.0.0.1",
32 {{ 0, 0, 0, 0, 0, 0, 0x7f00, 1 }},
33 "B]AAAB", "B]AAAB", 1, 1, 1 },
34 { "::ffff:127.0.0.3", "127.0.0.3",
35 {{ 0, 0, 0, 0, 0, 0xffff, 0x7f00, 3 }},
36 "B]AAAD", "B]AAAD", 1, 1, 1 },
37 { "::127.0.0.1", "127.0.0.1",
38 {{ 0, 0, 0, 0, 0, 0, 0x7f00, 1 }},
39 "B]AAAB", "B]AAAB", 1, 1, 1 },
40 { "2002:7f00:3::1", "2002:7f00:3::1",
41 {{ 0x2002, 0x7f00, 3, 0, 0, 0, 0, 1 }},
42 "B]AAAD", "CACH8AAAD_AAB", 1, 0, 0 },
43 { "8352:0344:0:0:0:0:2001:1204", "8352:344::2001:1204",
44 {{ 0x8352, 0x344, 0, 0, 0, 0, 0x2001, 0x1204 }},
45 "AAAAAA", "INSANE_CABBIE", 1, 0, 0 },
49 /** Perform tests for a single IP address.
50 * @param[in] addr Address test structure.
53 test_address(struct address_test *addr)
55 struct irc_in_addr parsed;
56 unsigned int ii, len, val;
57 char unparsed[64], base64_v4[64], base64_v6[64];
59 /* Convert expected address to network order. */
60 for (ii = 0; ii < 8; ++ii)
61 addr->expected.in6_16[ii] = htons(addr->expected.in6_16[ii]);
62 /* Make sure the text form is parsed as expected. */
63 len = ircd_aton(&parsed, addr->text);
64 assert(len == strlen(addr->text));
65 assert(!irc_in_addr_cmp(&parsed, &addr->expected));
66 /* Make sure it converts back to ASCII. */
67 ircd_ntoa_r(unparsed, &parsed);
68 assert(!strcmp(unparsed, addr->canonical));
69 /* Check IP-to-base64 conversion. */
70 iptobase64(base64_v4, &parsed, sizeof(base64_v4), 0);
71 iptobase64(base64_v6, &parsed, sizeof(base64_v6), 1);
73 assert(!strcmp(base64_v4, addr->base64_v4));
75 assert(!strcmp(base64_v6, addr->base64_v6));
76 /* Check testable attributes. */
77 val = irc_in_addr_valid(&parsed);
78 assert(!!val == addr->is_valid);
79 val = irc_in_addr_is_ipv4(&parsed);
80 assert(!!val == addr->is_ipv4);
81 val = irc_in_addr_is_loopback(&parsed);
82 assert(!!val == addr->is_loopback);
83 printf("Passed: %s (%s/%s)\n", addr->text, base64_v4, base64_v6);
87 main(int argc, char *argv[])
91 for (ii = 0; test_addrs[ii].text; ++ii)
92 test_address(&test_addrs[ii]);