]>
Commit | Line | Data |
---|---|---|
974e3884 A |
1 | #include <sys/types.h> |
2 | #include <sys/socket.h> | |
3 | #include <net/if_dl.h> | |
4 | #include <netinet/in.h> | |
5 | #include <arpa/inet.h> | |
6 | #include <string.h> | |
7 | #include <stdio.h> | |
8 | #include <darwintest.h> | |
9 | ||
10 | T_DECL(link_ntoa_basic, "link_ntoa converts to proper string") | |
11 | { | |
12 | // u_char sdl_len; /* Total length of sockaddr */ | |
13 | // u_char sdl_family; /* AF_LINK */ | |
14 | // u_short sdl_index; /* if != 0, system given index for interface */ | |
15 | // u_char sdl_type; /* interface type */ | |
16 | // u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */ | |
17 | // u_char sdl_alen; /* link level address length */ | |
18 | // u_char sdl_slen; /* link layer selector length */ | |
19 | // char sdl_data[12]; /* minimum work area, can be larger; | |
20 | // contains both if name and ll address */ | |
21 | ||
22 | struct sockaddr_dl sad; | |
23 | bzero(&sad, sizeof(sad)); | |
24 | sad.sdl_nlen = 3; | |
25 | sad.sdl_len = 0; | |
26 | sad.sdl_data[0] = 'l'; | |
27 | sad.sdl_data[1] = 'e'; | |
28 | sad.sdl_data[2] = '0'; | |
29 | sad.sdl_data[3] = 0x01; | |
30 | sad.sdl_data[4] = 0x80; | |
31 | sad.sdl_data[5] = 0xc2; | |
32 | sad.sdl_data[6] = 0x00; | |
33 | sad.sdl_data[7] = 0x00; | |
34 | sad.sdl_data[8] = 0x02; | |
35 | sad.sdl_data[9] = 0xaa; | |
36 | sad.sdl_data[10] = 0xbb; | |
37 | sad.sdl_data[11] = 0xcc; | |
38 | sad.sdl_alen = 6; | |
39 | ||
40 | char *foo = link_ntoa(&sad); | |
41 | ||
42 | T_EXPECT_EQ_STR("le0:1.80.c2.0.0.2", foo, NULL); | |
43 | } | |
44 | ||
45 | T_DECL(link_ntoa_overflow, "link_ntoa try to overflow") | |
46 | { | |
47 | char sockraw[64]; | |
48 | struct sockaddr_dl *sad; | |
49 | sad = (struct sockaddr_dl *)&sockraw; | |
50 | bzero(sad, sizeof(*sad)); | |
51 | sad->sdl_nlen = 3; | |
52 | sad->sdl_len = 0; | |
53 | sad->sdl_data[0] = 'l'; | |
54 | sad->sdl_data[1] = 'e'; | |
55 | sad->sdl_data[2] = '0'; | |
56 | sad->sdl_data[3] = 0x11; | |
57 | sad->sdl_data[4] = 0x80; | |
58 | sad->sdl_data[5] = 0xc2; | |
59 | sad->sdl_data[6] = 0x11; | |
60 | sad->sdl_data[7] = 0x11; | |
61 | sad->sdl_data[8] = 0xa2; | |
62 | sad->sdl_data[9] = 0xaa; | |
63 | sad->sdl_data[10] = 0xbb; | |
64 | sad->sdl_data[11] = 0xcc; | |
65 | sockraw[20] = 0xdd; | |
66 | sockraw[21] = 0xee; | |
67 | sockraw[22] = 0xff; | |
68 | sockraw[23] = 0x1a; | |
69 | sockraw[24] = 0x1b; | |
70 | sockraw[25] = 0x1c; | |
71 | sockraw[26] = 0x1d; | |
72 | sockraw[27] = 0x1e; | |
73 | sockraw[28] = 0x1f; | |
74 | sockraw[29] = 0x2a; | |
75 | sockraw[30] = 0x2b; | |
76 | sockraw[31] = 0x2c; | |
77 | ||
78 | /* set the length to something that will fit in the buffer */ | |
79 | sad->sdl_alen = 20; | |
80 | ||
81 | char *foo = link_ntoa(sad); | |
82 | ||
83 | char over = foo[64]; | |
84 | char over2 = foo[65]; | |
85 | ||
86 | /* this string should be 66 bytes long and exceed the buffer */ | |
87 | sad->sdl_alen = 21; | |
88 | ||
89 | foo = link_ntoa(sad); | |
90 | ||
91 | T_EXPECT_EQ_STR("", foo, NULL); | |
92 | ||
93 | T_EXPECT_EQ(over, foo[64], "did not overflow"); | |
94 | T_EXPECT_EQ(over2, foo[65], "did not overflow either"); | |
95 | } | |
96 | ||
97 | T_DECL(inet_ntop, "inet_ntop") | |
98 | { | |
99 | char *addresses4[] = { "1.2.3.4", "10.0.0.1", "2.2.2.2" }; | |
b061a43b | 100 | char *addresses6[] = { "2001:db8:85a3::8a2e:370:7334", "::1", "::" }; |
974e3884 A |
101 | for (int i = 0; i < sizeof(addresses4)/sizeof(addresses4[0]); i++){ |
102 | struct in_addr addr4; | |
103 | char buf[64]; | |
104 | T_EXPECT_EQ(inet_pton(AF_INET, addresses4[i], &addr4), 1, "inet_pton(AF_INET, %s)", addresses4[i]); | |
105 | char *str = inet_ntop(AF_INET, &addr4, buf, sizeof(buf)); | |
106 | T_EXPECT_NOTNULL(str, "inet_ntop(AF_INET) of %s", addresses4[i]); | |
107 | T_EXPECT_EQ_STR(str, addresses4[i], "round-trip of %s", addresses4[i]); | |
108 | } | |
109 | for (int i = 0; i < sizeof(addresses6)/sizeof(addresses6[0]); i++){ | |
110 | struct in6_addr addr6; | |
111 | char buf[64]; | |
112 | T_EXPECT_EQ(inet_pton(AF_INET6, addresses6[i], &addr6), 1, "inet_pton(AF_INET6, %s)", addresses6[i]); | |
113 | char *str = inet_ntop(AF_INET6, &addr6, buf, sizeof(buf)); | |
b061a43b | 114 | T_EXPECT_NOTNULL(str, "inet_ntop(AF_INET6) of %s", addresses6[i]); |
974e3884 A |
115 | T_EXPECT_EQ_STR(str, addresses6[i], "round-trip of %s", addresses6[i]); |
116 | } | |
117 | } | |
b061a43b A |
118 | |
119 | struct testcase { | |
120 | const char *in_addr; | |
121 | const char *expected_out_addr; | |
122 | }; | |
123 | ||
124 | static const struct testcase test_addrs[] = { | |
125 | { "1:2:3:4:5::1.2.3.4", "1:2:3:4:5:0:102:304" }, | |
126 | { "1:0:3:0:5:0:7:8", "1:0:3:0:5:0:7:8" }, | |
127 | { "0:0:3:0:0:0:7:8", "0:0:3::7:8" }, | |
128 | { "0:0:3:0:5:0:7:8", "::3:0:5:0:7:8" }, | |
129 | { "0:0:0:0:0:0:0:0", "::" }, | |
130 | { "0:0:0:0:0:1:0:0", "::1:0:0" }, | |
131 | { "1:0:0:0:0:0:0:0", "1::" }, | |
132 | { "0:0:0:1:0:0:0:0", "0:0:0:1::" }, | |
133 | { "1:0:0:0:0:0:0:1", "1::1" }, | |
134 | { "1:2:3:4:5:6:0:0", "1:2:3:4:5:6::" }, | |
135 | { "1:2:3:4:5:0:0:0", "1:2:3:4:5::" }, | |
136 | }; | |
137 | ||
138 | T_DECL(inet_ntop_resolve_zeroes, "Check for proper behavior when shortening zeroes w/ inet_ntop") | |
139 | { | |
140 | // Take ip addrs as text, convert to binary and back. | |
141 | // Upon converting back, they should adhere to the IPv6 guidelines. | |
142 | for (int i = 0; i < sizeof(test_addrs)/sizeof(struct testcase); ++i) { | |
143 | struct in6_addr addr6; | |
144 | char buf[64]; | |
145 | char *in_addr = test_addrs[i].in_addr; | |
146 | char *expected_out_addr = test_addrs[i].expected_out_addr; | |
147 | T_EXPECT_EQ(inet_pton(AF_INET6, in_addr, &addr6), 1, "inet_pton(AF_INET6, %s)", in_addr); | |
148 | char *str = inet_ntop(AF_INET6, &addr6, buf, sizeof(buf)); | |
149 | T_EXPECT_NOTNULL(str, "inet_ntop(AF_INET6) of %s", in_addr); | |
b061a43b A |
150 | T_EXPECT_EQ_STR(str, expected_out_addr, NULL); |
151 | } | |
152 | ||
153 | // Same test, but step through the possible range of ipv6 values. | |
154 | for (int i = 0x0; i < 0x10000; ++i) { | |
155 | struct in6_addr addr6; | |
156 | char buf[64]; | |
157 | char in_addr[64]; | |
158 | sprintf(in_addr, "1:1:1:1:1:1:1:%x", i); | |
159 | char *expected_out_addr = in_addr; | |
160 | T_QUIET; | |
161 | T_EXPECT_EQ(inet_pton(AF_INET6, in_addr, &addr6), 1, "inet_pton(AF_INET6, %s)", in_addr); | |
162 | char *str = inet_ntop(AF_INET6, &addr6, buf, sizeof(buf)); | |
163 | T_QUIET; | |
164 | T_EXPECT_NOTNULL(str, "inet_ntop(AF_INET6) of %s", in_addr); | |
165 | T_QUIET; | |
b061a43b A |
166 | T_EXPECT_EQ_STR(str, expected_out_addr, NULL); |
167 | } | |
168 | T_PASS("Passed ipv6 value testing"); | |
169 | ||
170 | } | |
507116e3 A |
171 | |
172 | static void | |
173 | conv(const char *addr) | |
174 | { | |
175 | int ret; | |
176 | void *retp; | |
177 | ||
178 | struct in6_addr addr6; | |
179 | memset(&addr6, 0, sizeof addr6); | |
180 | ret = inet_pton(AF_INET6, addr, &addr6); | |
181 | T_ASSERT_EQ(ret, 1, "inet_pton"); | |
182 | ||
183 | T_LOG("%s: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", addr, | |
184 | ((unsigned char *) &addr6)[0], ((unsigned char *) &addr6)[1], ((unsigned char *) &addr6)[2], ((unsigned char *) &addr6)[3], | |
185 | ((unsigned char *) &addr6)[4], ((unsigned char *) &addr6)[5], ((unsigned char *) &addr6)[6], ((unsigned char *) &addr6)[7], | |
186 | ((unsigned char *) &addr6)[8], ((unsigned char *) &addr6)[9], ((unsigned char *) &addr6)[10], ((unsigned char *) &addr6)[11], | |
187 | ((unsigned char *) &addr6)[12], ((unsigned char *) &addr6)[13], ((unsigned char *) &addr6)[14], ((unsigned char *) &addr6)[15]); | |
188 | ||
189 | char buf6[INET6_ADDRSTRLEN]; | |
190 | memset(buf6, 0, sizeof buf6); | |
191 | retp = inet_ntop(AF_INET6, &addr6, buf6, (socklen_t) sizeof buf6); | |
192 | T_ASSERT_NOTNULL(retp, "inet_ntop"); | |
193 | ||
194 | T_LOG("%s: %s\n", addr, buf6); | |
195 | ||
196 | T_EXPECT_EQ_STR(addr, buf6, NULL); | |
197 | } | |
198 | ||
199 | T_DECL(inet_ntop_PR46867324, "Regression test for PR46867324") | |
200 | { | |
201 | conv("2001:db8::1"); | |
202 | conv("::192.168.1.2"); | |
203 | conv("::ffff:10.11.12.13"); | |
204 | } |