]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include "include/ipaddr.h" |
2 | #include "gtest/gtest.h" | |
3 | ||
4 | #if defined(__FreeBSD__) | |
5 | #include <sys/types.h> | |
6 | #include <sys/socket.h> | |
7 | #endif | |
8 | #include <arpa/inet.h> | |
9 | ||
10 | static void ipv4(struct sockaddr_in *addr, const char *s) { | |
11 | int err; | |
12 | ||
13 | addr->sin_family = AF_INET; | |
14 | err = inet_pton(AF_INET, s, &addr->sin_addr); | |
15 | ASSERT_EQ(1, err); | |
16 | } | |
17 | ||
18 | static void ipv6(struct sockaddr_in6 *addr, const char *s) { | |
19 | int err; | |
20 | ||
21 | addr->sin6_family = AF_INET6; | |
22 | err = inet_pton(AF_INET6, s, &addr->sin6_addr); | |
23 | ASSERT_EQ(1, err); | |
24 | } | |
25 | ||
26 | static char eth0[] = "eth0"; | |
27 | static char eth1[] = "eth1"; | |
28 | ||
29 | TEST(CommonIPAddr, TestNotFound) | |
30 | { | |
31 | struct ifaddrs one, two; | |
32 | struct sockaddr_in a_one; | |
33 | struct sockaddr_in6 a_two; | |
34 | struct sockaddr_in net; | |
35 | const struct sockaddr *result; | |
36 | ||
37 | memset(&net, '0', sizeof(net)); | |
38 | ||
39 | one.ifa_next = &two; | |
40 | one.ifa_addr = (struct sockaddr*)&a_one; | |
41 | one.ifa_name = eth0; | |
42 | ||
43 | two.ifa_next = NULL; | |
44 | two.ifa_addr = (struct sockaddr*)&a_two; | |
45 | two.ifa_name = eth1; | |
46 | ||
47 | ipv4(&a_one, "10.11.12.13"); | |
48 | ipv6(&a_two, "2001:1234:5678:90ab::cdef"); | |
49 | ipv4(&net, "10.11.234.56"); | |
50 | ||
51 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 24); | |
52 | ASSERT_EQ(0, result); | |
53 | } | |
54 | ||
55 | TEST(CommonIPAddr, TestV4_Simple) | |
56 | { | |
57 | struct ifaddrs one, two; | |
58 | struct sockaddr_in a_one; | |
59 | struct sockaddr_in6 a_two; | |
60 | struct sockaddr_in net; | |
61 | const struct sockaddr *result; | |
62 | ||
63 | memset(&net, '0', sizeof(net)); | |
64 | ||
65 | one.ifa_next = &two; | |
66 | one.ifa_addr = (struct sockaddr*)&a_one; | |
67 | one.ifa_name = eth0; | |
68 | ||
69 | two.ifa_next = NULL; | |
70 | two.ifa_addr = (struct sockaddr*)&a_two; | |
71 | two.ifa_name = eth1; | |
72 | ||
73 | ipv4(&a_one, "10.11.12.13"); | |
74 | ipv6(&a_two, "2001:1234:5678:90ab::cdef"); | |
75 | ipv4(&net, "10.11.12.42"); | |
76 | ||
77 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 24); | |
78 | ASSERT_EQ((struct sockaddr*)&a_one, result); | |
79 | } | |
80 | ||
81 | TEST(CommonIPAddr, TestV4_Prefix25) | |
82 | { | |
83 | struct ifaddrs one, two; | |
84 | struct sockaddr_in a_one; | |
85 | struct sockaddr_in a_two; | |
86 | struct sockaddr_in net; | |
87 | const struct sockaddr *result; | |
88 | ||
89 | memset(&net, '0', sizeof(net)); | |
90 | ||
91 | one.ifa_next = &two; | |
92 | one.ifa_addr = (struct sockaddr*)&a_one; | |
93 | one.ifa_name = eth0; | |
94 | ||
95 | two.ifa_next = NULL; | |
96 | two.ifa_addr = (struct sockaddr*)&a_two; | |
97 | two.ifa_name = eth1; | |
98 | ||
99 | ipv4(&a_one, "10.11.12.13"); | |
100 | ipv4(&a_two, "10.11.12.129"); | |
101 | ipv4(&net, "10.11.12.128"); | |
102 | ||
103 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 25); | |
104 | ASSERT_EQ((struct sockaddr*)&a_two, result); | |
105 | } | |
106 | ||
107 | TEST(CommonIPAddr, TestV4_Prefix16) | |
108 | { | |
109 | struct ifaddrs one, two; | |
110 | struct sockaddr_in a_one; | |
111 | struct sockaddr_in a_two; | |
112 | struct sockaddr_in net; | |
113 | const struct sockaddr *result; | |
114 | ||
115 | memset(&net, '0', sizeof(net)); | |
116 | ||
117 | one.ifa_next = &two; | |
118 | one.ifa_addr = (struct sockaddr*)&a_one; | |
119 | one.ifa_name = eth0; | |
120 | ||
121 | two.ifa_next = NULL; | |
122 | two.ifa_addr = (struct sockaddr*)&a_two; | |
123 | two.ifa_name = eth1; | |
124 | ||
125 | ipv4(&a_one, "10.1.1.2"); | |
126 | ipv4(&a_two, "10.2.1.123"); | |
127 | ipv4(&net, "10.2.0.0"); | |
128 | ||
129 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 16); | |
130 | ASSERT_EQ((struct sockaddr*)&a_two, result); | |
131 | } | |
132 | ||
133 | TEST(CommonIPAddr, TestV4_PrefixTooLong) | |
134 | { | |
135 | struct ifaddrs one; | |
136 | struct sockaddr_in a_one; | |
137 | struct sockaddr_in net; | |
138 | const struct sockaddr *result; | |
139 | ||
140 | memset(&net, '0', sizeof(net)); | |
141 | ||
142 | one.ifa_next = NULL; | |
143 | one.ifa_addr = (struct sockaddr*)&a_one; | |
144 | one.ifa_name = eth0; | |
145 | ||
146 | ipv4(&a_one, "10.11.12.13"); | |
147 | ipv4(&net, "10.11.12.12"); | |
148 | ||
149 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 42); | |
150 | ASSERT_EQ(0, result); | |
151 | } | |
152 | ||
153 | TEST(CommonIPAddr, TestV4_PrefixZero) | |
154 | { | |
155 | struct ifaddrs one, two; | |
156 | struct sockaddr_in6 a_one; | |
157 | struct sockaddr_in a_two; | |
158 | struct sockaddr_in net; | |
159 | const struct sockaddr *result; | |
160 | ||
161 | memset(&net, '0', sizeof(net)); | |
162 | ||
163 | one.ifa_next = &two; | |
164 | one.ifa_addr = (struct sockaddr*)&a_one; | |
165 | one.ifa_name = eth0; | |
166 | ||
167 | two.ifa_next = NULL; | |
168 | two.ifa_addr = (struct sockaddr*)&a_two; | |
169 | two.ifa_name = eth1; | |
170 | ||
171 | ipv6(&a_one, "2001:1234:5678:900F::cdef"); | |
172 | ipv4(&a_two, "10.1.2.3"); | |
173 | ipv4(&net, "255.0.1.2"); | |
174 | ||
175 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 0); | |
176 | ASSERT_EQ((struct sockaddr*)&a_two, result); | |
177 | } | |
178 | ||
179 | TEST(CommonIPAddr, TestV6_Simple) | |
180 | { | |
181 | struct ifaddrs one, two; | |
182 | struct sockaddr_in a_one; | |
183 | struct sockaddr_in6 a_two; | |
184 | struct sockaddr_in6 net; | |
185 | const struct sockaddr *result; | |
186 | ||
187 | memset(&net, '0', sizeof(net)); | |
188 | ||
189 | one.ifa_next = &two; | |
190 | one.ifa_addr = (struct sockaddr*)&a_one; | |
191 | one.ifa_name = eth0; | |
192 | ||
193 | two.ifa_next = NULL; | |
194 | two.ifa_addr = (struct sockaddr*)&a_two; | |
195 | two.ifa_name = eth1; | |
196 | ||
197 | ipv4(&a_one, "10.11.12.13"); | |
198 | ipv6(&a_two, "2001:1234:5678:90ab::cdef"); | |
199 | ipv6(&net, "2001:1234:5678:90ab::dead:beef"); | |
200 | ||
201 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 64); | |
202 | ASSERT_EQ((struct sockaddr*)&a_two, result); | |
203 | } | |
204 | ||
205 | TEST(CommonIPAddr, TestV6_Prefix57) | |
206 | { | |
207 | struct ifaddrs one, two; | |
208 | struct sockaddr_in6 a_one; | |
209 | struct sockaddr_in6 a_two; | |
210 | struct sockaddr_in6 net; | |
211 | const struct sockaddr *result; | |
212 | ||
213 | memset(&net, '0', sizeof(net)); | |
214 | ||
215 | one.ifa_next = &two; | |
216 | one.ifa_addr = (struct sockaddr*)&a_one; | |
217 | one.ifa_name = eth0; | |
218 | ||
219 | two.ifa_next = NULL; | |
220 | two.ifa_addr = (struct sockaddr*)&a_two; | |
221 | two.ifa_name = eth1; | |
222 | ||
223 | ipv6(&a_one, "2001:1234:5678:900F::cdef"); | |
224 | ipv6(&a_two, "2001:1234:5678:90ab::cdef"); | |
225 | ipv6(&net, "2001:1234:5678:90ab::dead:beef"); | |
226 | ||
227 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 57); | |
228 | ASSERT_EQ((struct sockaddr*)&a_two, result); | |
229 | } | |
230 | ||
231 | TEST(CommonIPAddr, TestV6_PrefixTooLong) | |
232 | { | |
233 | struct ifaddrs one; | |
234 | struct sockaddr_in6 a_one; | |
235 | struct sockaddr_in6 net; | |
236 | const struct sockaddr *result; | |
237 | ||
238 | memset(&net, '0', sizeof(net)); | |
239 | ||
240 | one.ifa_next = NULL; | |
241 | one.ifa_addr = (struct sockaddr*)&a_one; | |
242 | one.ifa_name = eth0; | |
243 | ||
244 | ipv6(&a_one, "2001:1234:5678:900F::cdef"); | |
245 | ipv6(&net, "2001:1234:5678:900F::cdee"); | |
246 | ||
247 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 9000); | |
248 | ASSERT_EQ(0, result); | |
249 | } | |
250 | ||
251 | TEST(CommonIPAddr, TestV6_PrefixZero) | |
252 | { | |
253 | struct ifaddrs one, two; | |
254 | struct sockaddr_in a_one; | |
255 | struct sockaddr_in6 a_two; | |
256 | struct sockaddr_in6 net; | |
257 | const struct sockaddr *result; | |
258 | ||
259 | one.ifa_next = &two; | |
260 | one.ifa_addr = (struct sockaddr*)&a_one; | |
261 | one.ifa_name = eth0; | |
262 | ||
263 | two.ifa_next = NULL; | |
264 | two.ifa_addr = (struct sockaddr*)&a_two; | |
265 | two.ifa_name = eth1; | |
266 | ||
267 | ipv4(&a_one, "10.2.3.4"); | |
268 | ipv6(&a_two, "2001:f00b::1"); | |
269 | ipv6(&net, "ff00::1"); | |
270 | ||
271 | result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 0); | |
272 | ASSERT_EQ((struct sockaddr*)&a_two, result); | |
273 | } | |
274 | ||
275 | TEST(CommonIPAddr, ParseNetwork_Empty) | |
276 | { | |
277 | struct sockaddr_storage network; | |
278 | unsigned int prefix_len; | |
279 | bool ok; | |
280 | ||
281 | ok = parse_network("", &network, &prefix_len); | |
282 | ASSERT_EQ(ok, false); | |
283 | } | |
284 | ||
285 | TEST(CommonIPAddr, ParseNetwork_Bad_Junk) | |
286 | { | |
287 | struct sockaddr_storage network; | |
288 | unsigned int prefix_len; | |
289 | bool ok; | |
290 | ||
291 | ok = parse_network("foo", &network, &prefix_len); | |
292 | ASSERT_EQ(ok, false); | |
293 | } | |
294 | ||
295 | TEST(CommonIPAddr, ParseNetwork_Bad_SlashNum) | |
296 | { | |
297 | struct sockaddr_storage network; | |
298 | unsigned int prefix_len; | |
299 | bool ok; | |
300 | ||
301 | ok = parse_network("/24", &network, &prefix_len); | |
302 | ASSERT_EQ(ok, false); | |
303 | } | |
304 | ||
305 | TEST(CommonIPAddr, ParseNetwork_Bad_Slash) | |
306 | { | |
307 | struct sockaddr_storage network; | |
308 | unsigned int prefix_len; | |
309 | bool ok; | |
310 | ||
311 | ok = parse_network("/", &network, &prefix_len); | |
312 | ASSERT_EQ(ok, false); | |
313 | } | |
314 | ||
315 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv4) | |
316 | { | |
317 | struct sockaddr_storage network; | |
318 | unsigned int prefix_len; | |
319 | bool ok; | |
320 | ||
321 | ok = parse_network("123.123.123.123", &network, &prefix_len); | |
322 | ASSERT_EQ(ok, false); | |
323 | } | |
324 | ||
325 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv4Slash) | |
326 | { | |
327 | struct sockaddr_storage network; | |
328 | unsigned int prefix_len; | |
329 | bool ok; | |
330 | ||
331 | ok = parse_network("123.123.123.123/", &network, &prefix_len); | |
332 | ASSERT_EQ(ok, false); | |
333 | } | |
334 | ||
335 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashNegative) | |
336 | { | |
337 | struct sockaddr_storage network; | |
338 | unsigned int prefix_len; | |
339 | bool ok; | |
340 | ||
341 | ok = parse_network("123.123.123.123/-3", &network, &prefix_len); | |
342 | ASSERT_EQ(ok, false); | |
343 | } | |
344 | ||
345 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashJunk) | |
346 | { | |
347 | struct sockaddr_storage network; | |
348 | unsigned int prefix_len; | |
349 | bool ok; | |
350 | ||
351 | ok = parse_network("123.123.123.123/foo", &network, &prefix_len); | |
352 | ASSERT_EQ(ok, false); | |
353 | } | |
354 | ||
355 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv6) | |
356 | { | |
357 | struct sockaddr_storage network; | |
358 | unsigned int prefix_len; | |
359 | bool ok; | |
360 | ||
361 | ok = parse_network("2001:1234:5678:90ab::dead:beef", &network, &prefix_len); | |
362 | ASSERT_EQ(ok, false); | |
363 | } | |
364 | ||
365 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv6Slash) | |
366 | { | |
367 | struct sockaddr_storage network; | |
368 | unsigned int prefix_len; | |
369 | bool ok; | |
370 | ||
371 | ok = parse_network("2001:1234:5678:90ab::dead:beef/", &network, &prefix_len); | |
372 | ASSERT_EQ(ok, false); | |
373 | } | |
374 | ||
375 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashNegative) | |
376 | { | |
377 | struct sockaddr_storage network; | |
378 | unsigned int prefix_len; | |
379 | bool ok; | |
380 | ||
381 | ok = parse_network("2001:1234:5678:90ab::dead:beef/-3", &network, &prefix_len); | |
382 | ASSERT_EQ(ok, false); | |
383 | } | |
384 | ||
385 | TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashJunk) | |
386 | { | |
387 | struct sockaddr_storage network; | |
388 | unsigned int prefix_len; | |
389 | bool ok; | |
390 | ||
391 | ok = parse_network("2001:1234:5678:90ab::dead:beef/foo", &network, &prefix_len); | |
392 | ASSERT_EQ(ok, false); | |
393 | } | |
394 | ||
395 | TEST(CommonIPAddr, ParseNetwork_IPv4_0) | |
396 | { | |
397 | struct sockaddr_in network; | |
398 | struct sockaddr_storage net_storage; | |
399 | unsigned int prefix_len; | |
400 | bool ok; | |
401 | ||
402 | ok = parse_network("123.123.123.123/0", &net_storage, &prefix_len); | |
403 | network = *(struct sockaddr_in *) &net_storage; | |
404 | ASSERT_EQ(ok, true); | |
405 | ASSERT_EQ(0U, prefix_len); | |
406 | ASSERT_EQ(AF_INET, network.sin_family); | |
407 | ASSERT_EQ(0, network.sin_port); | |
408 | struct sockaddr_in want; | |
409 | ipv4(&want, "123.123.123.123"); | |
410 | ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); | |
411 | } | |
412 | ||
413 | TEST(CommonIPAddr, ParseNetwork_IPv4_13) | |
414 | { | |
415 | struct sockaddr_in network; | |
416 | struct sockaddr_storage net_storage; | |
417 | unsigned int prefix_len; | |
418 | bool ok; | |
419 | ||
420 | ok = parse_network("123.123.123.123/13", &net_storage, &prefix_len); | |
421 | network = *(struct sockaddr_in *) &net_storage; | |
422 | ASSERT_EQ(ok, true); | |
423 | ASSERT_EQ(13U, prefix_len); | |
424 | ASSERT_EQ(AF_INET, network.sin_family); | |
425 | ASSERT_EQ(0, network.sin_port); | |
426 | struct sockaddr_in want; | |
427 | ipv4(&want, "123.123.123.123"); | |
428 | ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); | |
429 | } | |
430 | ||
431 | TEST(CommonIPAddr, ParseNetwork_IPv4_32) | |
432 | { | |
433 | struct sockaddr_in network; | |
434 | struct sockaddr_storage net_storage; | |
435 | unsigned int prefix_len; | |
436 | bool ok; | |
437 | ||
438 | ok = parse_network("123.123.123.123/32", &net_storage, &prefix_len); | |
439 | network = *(struct sockaddr_in *) &net_storage; | |
440 | ASSERT_EQ(ok, true); | |
441 | ASSERT_EQ(32U, prefix_len); | |
442 | ASSERT_EQ(AF_INET, network.sin_family); | |
443 | ASSERT_EQ(0, network.sin_port); | |
444 | struct sockaddr_in want; | |
445 | ipv4(&want, "123.123.123.123"); | |
446 | ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); | |
447 | } | |
448 | ||
449 | TEST(CommonIPAddr, ParseNetwork_IPv4_42) | |
450 | { | |
451 | struct sockaddr_in network; | |
452 | struct sockaddr_storage net_storage; | |
453 | unsigned int prefix_len; | |
454 | bool ok; | |
455 | ||
456 | ok = parse_network("123.123.123.123/42", &net_storage, &prefix_len); | |
457 | network = *(struct sockaddr_in *) &net_storage; | |
458 | ASSERT_EQ(ok, true); | |
459 | ASSERT_EQ(42U, prefix_len); | |
460 | ASSERT_EQ(AF_INET, network.sin_family); | |
461 | ASSERT_EQ(0, network.sin_port); | |
462 | struct sockaddr_in want; | |
463 | ipv4(&want, "123.123.123.123"); | |
464 | ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); | |
465 | } | |
466 | ||
467 | TEST(CommonIPAddr, ParseNetwork_IPv6_0) | |
468 | { | |
469 | struct sockaddr_in6 network; | |
470 | struct sockaddr_storage net_storage; | |
471 | unsigned int prefix_len; | |
472 | bool ok; | |
473 | ||
474 | ok = parse_network("2001:1234:5678:90ab::dead:beef/0", &net_storage, &prefix_len); | |
475 | network = *(struct sockaddr_in6 *) &net_storage; | |
476 | ASSERT_EQ(ok, true); | |
477 | ASSERT_EQ(0U, prefix_len); | |
478 | ASSERT_EQ(AF_INET6, network.sin6_family); | |
479 | ASSERT_EQ(0, network.sin6_port); | |
480 | struct sockaddr_in6 want; | |
481 | ipv6(&want, "2001:1234:5678:90ab::dead:beef"); | |
482 | ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); | |
483 | } | |
484 | ||
485 | TEST(CommonIPAddr, ParseNetwork_IPv6_67) | |
486 | { | |
487 | struct sockaddr_in6 network; | |
488 | struct sockaddr_storage net_storage; | |
489 | unsigned int prefix_len; | |
490 | bool ok; | |
491 | ||
492 | ok = parse_network("2001:1234:5678:90ab::dead:beef/67", &net_storage, &prefix_len); | |
493 | network = *(struct sockaddr_in6 *) &net_storage; | |
494 | ASSERT_EQ(ok, true); | |
495 | ASSERT_EQ(67U, prefix_len); | |
496 | ASSERT_EQ(AF_INET6, network.sin6_family); | |
497 | ASSERT_EQ(0, network.sin6_port); | |
498 | struct sockaddr_in6 want; | |
499 | ipv6(&want, "2001:1234:5678:90ab::dead:beef"); | |
500 | ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); | |
501 | } | |
502 | ||
503 | TEST(CommonIPAddr, ParseNetwork_IPv6_128) | |
504 | { | |
505 | struct sockaddr_in6 network; | |
506 | struct sockaddr_storage net_storage; | |
507 | unsigned int prefix_len; | |
508 | bool ok; | |
509 | ||
510 | ok = parse_network("2001:1234:5678:90ab::dead:beef/128", &net_storage, &prefix_len); | |
511 | network = *(struct sockaddr_in6 *) &net_storage; | |
512 | ASSERT_EQ(ok, true); | |
513 | ASSERT_EQ(128U, prefix_len); | |
514 | ASSERT_EQ(AF_INET6, network.sin6_family); | |
515 | ASSERT_EQ(0, network.sin6_port); | |
516 | struct sockaddr_in6 want; | |
517 | ipv6(&want, "2001:1234:5678:90ab::dead:beef"); | |
518 | ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); | |
519 | } | |
520 | ||
521 | TEST(CommonIPAddr, ParseNetwork_IPv6_9000) | |
522 | { | |
523 | struct sockaddr_in6 network; | |
524 | struct sockaddr_storage net_storage; | |
525 | unsigned int prefix_len; | |
526 | bool ok; | |
527 | ||
528 | ok = parse_network("2001:1234:5678:90ab::dead:beef/9000", &net_storage, &prefix_len); | |
529 | network = *(struct sockaddr_in6 *) &net_storage; | |
530 | ASSERT_EQ(ok, true); | |
531 | ASSERT_EQ(9000U, prefix_len); | |
532 | ASSERT_EQ(AF_INET6, network.sin6_family); | |
533 | ASSERT_EQ(0, network.sin6_port); | |
534 | struct sockaddr_in6 want; | |
535 | ipv6(&want, "2001:1234:5678:90ab::dead:beef"); | |
536 | ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); | |
537 | } |