Fix base64toip() bugs (PR#1197043).
[ircu2.10.12-pk.git] / ircd / test / ircd_in_addr_t.c
1 /* ircd_in_addr_t.c - Test file for IP address manipulation */
2
3 #include "ircd_log.h"
4 #include "ircd_string.h"
5 #include "numnicks.h"
6 #include "res.h"
7 #include <stdio.h>
8 #include <string.h>
9 #include <netinet/in.h>
10
11 /** Structure to describe a test for IP address parsing and unparsing. */
12 struct address_test {
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? */
21 };
22
23 /** Array of addresses to test with. */
24 static struct address_test test_addrs[] = {
25     { "::", "0::",
26       {{ 0, 0, 0, 0, 0, 0, 0, 0 }},
27       "AAAAAA", "_", 0, 0, 0 },
28     { "::1", "0::1",
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 },
46     { "1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8",
47       {{ 1, 2, 3, 4, 5, 6, 7, 8 }},
48       "AAAAAA", "AABAACAADAAEAAFAAGAAHAAI", 1, 0, 0 },
49     { 0 },
50 };
51
52 /** Perform tests for a single IP address.
53  * @param[in] addr Address test structure.
54  */
55 static void
56 test_address(struct address_test *addr)
57 {
58     struct irc_in_addr parsed;
59     unsigned int ii, len, val;
60     char unparsed[64], base64_v4[64], base64_v6[64];
61
62     /* Convert expected address to network order. */
63     for (ii = 0; ii < 8; ++ii)
64         addr->expected.in6_16[ii] = htons(addr->expected.in6_16[ii]);
65     /* Make sure the text form is parsed as expected. */
66     len = ircd_aton(&parsed, addr->text);
67     assert(len == strlen(addr->text));
68     assert(!irc_in_addr_cmp(&parsed, &addr->expected));
69     /* Make sure it converts back to ASCII. */
70     ircd_ntoa_r(unparsed, &parsed);
71     assert(!strcmp(unparsed, addr->canonical));
72     /* Check IP-to-base64 conversion. */
73     iptobase64(base64_v4, &parsed, sizeof(base64_v4), 0);
74     iptobase64(base64_v6, &parsed, sizeof(base64_v6), 1);
75     if (addr->base64_v4)
76         assert(!strcmp(base64_v4, addr->base64_v4));
77     if (addr->base64_v6)
78         assert(!strcmp(base64_v6, addr->base64_v6));
79     /* Check testable attributes. */
80     val = irc_in_addr_valid(&parsed);
81     assert(!!val == addr->is_valid);
82     val = irc_in_addr_is_ipv4(&parsed);
83     assert(!!val == addr->is_ipv4);
84     val = irc_in_addr_is_loopback(&parsed);
85     assert(!!val == addr->is_loopback);
86     /* Check base64-to-IP conversion. */
87     if (addr->is_ipv4) {
88         base64toip(addr->base64_v4, &parsed);
89         assert(!memcmp(parsed.in6_16+6, addr->expected.in6_16+6, 4));
90     } else {
91         base64toip(addr->base64_v6, &parsed);
92         assert(!memcmp(&parsed, &addr->expected, sizeof(parsed)));
93     }
94     /* Tests completed. */
95     printf("Passed: %s (%s/%s)\n", addr->text, base64_v4, base64_v6);
96 }
97
98 int
99 main(int argc, char *argv[])
100 {
101     unsigned int ii;
102
103     for (ii = 0; test_addrs[ii].text; ++ii)
104         test_address(&test_addrs[ii]);
105
106     return 0;
107 }