]> jfr.im git - irc/quakenet/snircd.git/blame - ircd/test/ircd_in_addr_t.c
add sbounce from asuka into snircd tree
[irc/quakenet/snircd.git] / ircd / test / ircd_in_addr_t.c
CommitLineData
189935b1 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. */
12struct 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. */
24static 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 */
55static void
56test_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/** Structure to describe a test for IP mask parsing. */
99struct ipmask_test {
100 const char *text; /**< Textual IP mask to parse. */
101 struct irc_in_addr expected; /**< Canonical form of address. */
102 unsigned int is_ipmask : 1; /**< Parse as an ipmask? */
103 unsigned int is_parseable : 1; /**< Is address parseable? */
104 unsigned int exp_bits : 8; /**< Number of bits expected in netmask */
105};
106
107/** Array of ipmasks to test with. */
108static struct ipmask_test test_masks[] = {
109 { "::", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 1, 128 },
110 { "::/0", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 1, 0 },
111 { "::10.0.0.0", {{ 0, 0, 0, 0, 0, 0, 0xa00, 0 }}, 1, 1, 128 },
112 { "192.168/16", {{ 0, 0, 0, 0, 0, 0xffff, 0xc0a8, 0 }}, 1, 1, 112 },
113 { "192.*", {{ 0, 0, 0, 0, 0, 0xffff, 0xc000, 0 }}, 1, 1, 104 },
114 { "192.*/8", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 0, 0 },
115 { "192*", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 0, 0 },
116 { "192.168.0.0/16", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0, 0, 0 },
117 { "ab.*", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 0, 0 },
118 { "a*", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 0, 0 },
119 { "*", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 1, 0 },
120 { "a:b", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 0, 0 },
121 { "a::*", {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 1, 0, 0 },
122 { "a:*", {{ 0xa, 0, 0, 0, 0, 0, 0, 0 }}, 1, 1, 16 },
123 { "a:/16", {{ 0xa, 0, 0, 0, 0, 0, 0, 0 }}, 1, 1, 16 },
124 { 0 }
125};
126
127/** Perform tests for a single IP mask.
128 * @param[in] mask IP mask test structure.
129 */
130static void
131test_ipmask(struct ipmask_test *mask)
132{
133 struct irc_in_addr parsed;
134 unsigned int len, ii;
135 unsigned char bits = 0;
136
137 /* Convert expected address to network order. */
138 for (ii = 0; ii < 8; ++ii)
139 mask->expected.in6_16[ii] = htons(mask->expected.in6_16[ii]);
140 /* Try to parse; make sure its parseability and netmask length are
141 * as expected. */
142 len = ipmask_parse(mask->text, &parsed, mask->is_ipmask ? &bits : 0);
143 assert(!!len == mask->is_parseable);
144 if (!len) {
145 printf("X-Fail: %s\n", mask->text);
146 return;
147 }
148 if (mask->is_ipmask)
149 assert(bits == mask->exp_bits);
150 assert(!memcmp(&parsed, &mask->expected, sizeof(parsed)));
151 printf("Passed: %s (%s/%u)\n", mask->text, ircd_ntoa(&parsed), bits);
152}
153
154int
155main(int argc, char *argv[])
156{
157 unsigned int ii;
158
159 printf("Testing address parsing..\n");
160 for (ii = 0; test_addrs[ii].text; ++ii)
161 test_address(&test_addrs[ii]);
162
163 printf("\nTesting ipmask parsing..\n");
164 for (ii = 0; test_masks[ii].text; ++ii)
165 test_ipmask(&test_masks[ii]);
166
167 return 0;
168}