1 #include "first.h"
2
3 #undef NDEBUG
4 #include <assert.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7
8 #include "configfile-glue.c"
9 #include "fdlog.h"
10
11 const struct {
12 const char *string;
13 const char *rmtstr;
14 int rmtfamily;
15 int expect;
16 } rmtmask[] = {
17 { "1.0.0.1/1", "1.0.0.1", AF_INET, 1 }
18 ,{ "254.254.254.254/1", "254.0.0.1", AF_INET, 1 }
19 ,{ "254.254.254.252/31", "254.254.254.253", AF_INET, 1 }
20 ,{ "254.254.254.253/31", "254.254.254.254", AF_INET, 0 }
21 ,{ "254.254.254.253/32", "254.254.254.254", AF_INET, 0 }
22 ,{ "254.254.254.254/32", "254.254.254.254", AF_INET, 1 }
23 #ifdef HAVE_IPV6
24 ,{ "2001::/3", "2001::1", AF_INET6, 1 }
25 ,{ "2f01::/5", "2701::1", AF_INET6, 0 }
26 ,{ "2f01::/32", "2f01::1", AF_INET6, 1 }
27 ,{ "2f01::/32", "2f02::1", AF_INET6, 0 }
28 ,{ "2001::1/127", "2001::1", AF_INET6, 1 }
29 ,{ "2001::1/127", "2001::2", AF_INET6, 0 }
30 ,{ "2001::2/128", "2001::2", AF_INET6, 1 }
31 ,{ "2001::2/128", "2001::3", AF_INET6, 0 }
32 ,{ "1.0.0.1/1", "::ffff:1.0.0.1", AF_INET6, 1 }
33 ,{ "254.254.254.254/1", "::ffff:254.0.0.1", AF_INET6, 1 }
34 ,{ "254.254.254.252/31", "::ffff:254.254.254.253", AF_INET6, 1 }
35 ,{ "254.254.254.253/31", "::ffff:254.254.254.254", AF_INET6, 0 }
36 ,{ "254.254.254.253/32", "::ffff:254.254.254.254", AF_INET6, 0 }
37 ,{ "254.254.254.254/32", "::ffff:254.254.254.254", AF_INET6, 1 }
38 ,{ "::ffff:1.0.0.1/97", "1.0.0.1", AF_INET, 1 }
39 ,{ "::ffff:254.254.254.254/97", "254.0.0.1", AF_INET, 1 }
40 ,{ "::ffff:254.254.254.252/127", "254.254.254.253", AF_INET, 1 }
41 ,{ "::ffff:254.254.254.253/127", "254.254.254.254", AF_INET, 0 }
42 ,{ "::ffff:254.254.254.253/128", "254.254.254.254", AF_INET, 0 }
43 ,{ "::ffff:254.254.254.254/128", "254.254.254.254", AF_INET, 1 }
44 #endif
45 };
46
test_configfile_addrbuf_eq_remote_ip_mask(void)47 static void test_configfile_addrbuf_eq_remote_ip_mask (void) {
48 request_st r;
49 memset(&r, 0, sizeof(request_st));
50 r.conf.errh = fdlog_init(NULL, -1, FDLOG_FD);
51 r.conf.errh->fd = -1; /* (disable) */
52
53 buffer * const b = buffer_init();
54 buffer * const tb = buffer_init();
55 sock_addr rmt;
56
57 for (int i = 0; i < (int)(sizeof(rmtmask)/sizeof(rmtmask[0])); ++i) {
58 if (1 != sock_addr_inet_pton(&rmt, rmtmask[i].rmtstr, rmtmask[i].rmtfamily, 0)) exit(-1); /*(bad test)*/
59 buffer_copy_string(b, rmtmask[i].string);
60 #if 0
61 if (!config_remoteip_normalize(b, tb)) exit(-1); /*(bad test)*/
62 #else
63 /* modified from configfile.c:config_remoteip_normalize()
64 * to avoid pulling in configfile.c and all dependencies */
65 char *slash = strchr(b->ptr, '/');
66 if (NULL == slash) exit(-1); /*(bad test)*/
67 unsigned long nm_bits = strtoul(slash+1, NULL, 10);
68 uint32_t len = slash - b->ptr;
69 int family = strchr(b->ptr, ':') ? AF_INET6 : AF_INET;
70 char *after = buffer_string_prepare_append(b, 1 + 7 + 28);
71 ++after; /*(increment to pos after string end '\0')*/
72 *(unsigned char *)after = (unsigned char)nm_bits;
73 sock_addr * const saddr = (sock_addr *)(((uintptr_t)after+1+7) & ~7);
74 if (nm_bits) b->ptr[len]='\0'; /*(sock_addr_inet_pton() w/o CIDR mask)*/
75 int rc = sock_addr_inet_pton(saddr, b->ptr, family, 0);
76 if (nm_bits) b->ptr[len]='/';
77 if (1 != rc) exit(-1); /*(bad test)*/
78 #endif
79 const sock_addr * const addr = (sock_addr *)
80 (((uintptr_t)b->ptr + b->used + 1 + 7) & ~7);
81 int bits = ((unsigned char *)b->ptr)[b->used];
82 int m = sock_addr_is_addr_eq_bits(addr, &rmt, bits);
83 if (m != rmtmask[i].expect) {
84 fprintf(stderr, "failed assertion: %s %s %s\n",
85 rmtmask[i].string,
86 rmtmask[i].expect ? "==" : "!=",
87 rmtmask[i].rmtstr);
88 exit(-1);
89 }
90 }
91
92 buffer_free(tb);
93 buffer_free(b);
94 fdlog_free(r.conf.errh);
95 }
96
main(void)97 int main (void) {
98 test_configfile_addrbuf_eq_remote_ip_mask();
99
100 return 0;
101 }
102