1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
6 #include <boost/test/unit_test.hpp>
10 using namespace boost
;
12 BOOST_AUTO_TEST_SUITE(test_iputils_hh
)
14 BOOST_AUTO_TEST_CASE(test_ComboAddress
) {
15 ComboAddress
local("127.0.0.1", 53);
16 BOOST_CHECK(local
==local
);
17 BOOST_CHECK_EQUAL(local
.sin4
.sin_family
, AF_INET
);
18 BOOST_CHECK_EQUAL(local
.sin4
.sin_port
, htons(53));
19 BOOST_CHECK_EQUAL(local
.sin4
.sin_addr
.s_addr
, htonl(0x7f000001UL
));
21 ComboAddress
remote("130.161.33.15", 53);
22 BOOST_CHECK(!(local
== remote
));
23 BOOST_CHECK_EQUAL(remote
.sin4
.sin_port
, htons(53));
25 ComboAddress
withport("213.244.168.210:53");
26 BOOST_CHECK_EQUAL(withport
.sin4
.sin_port
, htons(53));
28 ComboAddress
withportO("213.244.168.210:53", 5300);
29 BOOST_CHECK_EQUAL(withportO
.sin4
.sin_port
, htons(53));
31 withport
= ComboAddress("[::]:53");
32 BOOST_CHECK_EQUAL(withport
.sin4
.sin_port
, htons(53));
34 withport
= ComboAddress("[::]:5300", 53);
35 BOOST_CHECK_EQUAL(withport
.sin4
.sin_port
, htons(5300));
37 ComboAddress
defaultport("213.244.168.210");
38 BOOST_CHECK_EQUAL(defaultport
.sin4
.sin_port
, htons(0));
40 defaultport
= ComboAddress("[::1]");
41 BOOST_CHECK_EQUAL(defaultport
.sin4
.sin_port
, htons(0));
43 defaultport
= ComboAddress("::1");
44 BOOST_CHECK_EQUAL(defaultport
.sin4
.sin_port
, htons(0));
46 // Verify that 2 'empty' ComboAddresses are equal, used in syncres.hh to
48 ComboAddress a
= ComboAddress();
49 ComboAddress b
= ComboAddress();
52 // Verify that 2 ComboAddresses are not the same
53 ComboAddress c
= ComboAddress("127.0.0.1:53");
54 ComboAddress d
= ComboAddress("127.0.0.1:52");
55 ComboAddress e
= ComboAddress("127.0.0.2:53");
61 BOOST_CHECK(!(a
!= b
));
63 // Verify that we don't allow invalid port numbers
64 BOOST_CHECK_THROW(ComboAddress("127.0.0.1:70000"), PDNSException
); // Port no. too high
65 BOOST_CHECK_THROW(ComboAddress("127.0.0.1:-6"), PDNSException
); // Port no. too low
66 BOOST_CHECK_THROW(ComboAddress("[::1]:70000"), PDNSException
); // Port no. too high
67 BOOST_CHECK_THROW(ComboAddress("[::1]:-6"), PDNSException
); // Port no. too low
70 BOOST_AUTO_TEST_CASE(test_ComboAddressCompare
) {
78 BOOST_AUTO_TEST_CASE(test_ComboAddressTruncate
) {
79 ComboAddress
ca4("130.161.252.29");
81 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.252.0");
83 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.0.0");
87 ca4
= ComboAddress("130.161.252.29");
88 ComboAddress
orig(ca4
);
89 for(int n
=32; n
; --n
) {
93 memcpy(&p
, (char*)&ca4
.sin4
.sin_addr
.s_addr
, 4);
94 std::bitset
<32> result(htonl(p
));
96 memcpy(&p
, (char*)&orig
.sin4
.sin_addr
.s_addr
, 4);
97 std::bitset
<32> manual(htonl(p
));
100 for(int i
=0; i
< tokill
; ++i
)
103 BOOST_CHECK_EQUAL(result
, manual
);
106 ca4
= ComboAddress("130.161.252.29");
108 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.252.28");
111 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.252.28");
114 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.252.24");
117 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.252.0");
120 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.252.0");
123 BOOST_CHECK_EQUAL(ca4
.toString(), "130.161.248.0");
125 ComboAddress
ca6("2001:888:2000:1d::2");
127 BOOST_CHECK_EQUAL(ca6
.toString(), "2001:888:2000:1d::");
129 BOOST_CHECK_EQUAL(ca6
.toString(), "2001:888:2000:1d::");
130 ca6
.truncate(72); // 0102 304 0506 78
131 BOOST_CHECK_EQUAL(ca6
.toString(), "2001:888:2000:1d::");
133 BOOST_CHECK_EQUAL(ca6
.toString(), "2001:888:2000::");
135 BOOST_CHECK_EQUAL(ca6
.toString(), "2001:888:2000::");
137 BOOST_CHECK_EQUAL(ca6
.toString(), "2001:888::");
139 BOOST_CHECK_EQUAL(ca6
.toString(), "2001::");
141 BOOST_CHECK_EQUAL(ca6
.toString(), "2000::");
144 orig
=ca6
=ComboAddress("2001:888:2000:1d::2");
145 for(int n
=128; n
; --n
) {
148 std::bitset
<128> result
, manual
;
149 for(int i
=0; i
< 16; ++i
) {
151 result
|= std::bitset
<128>(*((unsigned char*)&ca6
.sin6
.sin6_addr
.s6_addr
+ i
));
154 manual
|= std::bitset
<128>(*((unsigned char*)&orig
.sin6
.sin6_addr
.s6_addr
+ i
));
158 for(int i
=0; i
< tokill
; ++i
)
161 BOOST_CHECK_EQUAL(result
, manual
);
166 BOOST_AUTO_TEST_CASE(test_Mapping
)
168 ComboAddress
lh("::1");
169 BOOST_CHECK_EQUAL(lh
.toString(), "::1");
172 BOOST_AUTO_TEST_CASE(test_Netmask
) {
173 ComboAddress
local("127.0.0.1", 53);
174 ComboAddress
remote("130.161.252.29", 53);
176 Netmask
nm("127.0.0.1/24");
177 BOOST_CHECK(nm
.getBits() == 24);
178 BOOST_CHECK(nm
.match(local
));
179 BOOST_CHECK(!nm
.match(remote
));
180 BOOST_CHECK(nm
.isIpv4());
181 BOOST_CHECK(!nm
.isIpv6());
183 Netmask
nm6("fe80::92fb:a6ff:fe4a:51da/64");
184 BOOST_CHECK(nm6
.getBits() == 64);
185 BOOST_CHECK(nm6
.match("fe80::92fb:a6ff:fe4a:51db"));
186 BOOST_CHECK(!nm6
.match("fe81::92fb:a6ff:fe4a:51db"));
187 BOOST_CHECK(!nm6
.isIpv4());
188 BOOST_CHECK(nm6
.isIpv6());
190 Netmask
nmp("130.161.252.29/32");
191 BOOST_CHECK(nmp
.match(remote
));
193 Netmask
nmp6("fe80::92fb:a6ff:fe4a:51da/128");
194 BOOST_CHECK(nmp6
.match("fe80::92fb:a6ff:fe4a:51da"));
195 BOOST_CHECK(!nmp6
.match("fe81::92fb:a6ff:fe4a:51db"));
197 Netmask
all("0.0.0.0/0");
198 BOOST_CHECK(all
.match(local
) && all
.match(remote
));
200 Netmask
all6("::/0");
201 BOOST_CHECK(all6
.match("::1") && all6
.match("fe80::92fb:a6ff:fe4a:51da"));
204 Netmask
fromCombo1(ComboAddress("192.0.2.1:53"), 32);
205 Netmask
fromCombo2(ComboAddress("192.0.2.1:54"), 32);
206 BOOST_CHECK(fromCombo1
== fromCombo2
);
207 BOOST_CHECK(fromCombo1
.match("192.0.2.1"));
208 BOOST_CHECK(fromCombo1
.match(ComboAddress("192.0.2.1:80")));
209 BOOST_CHECK(fromCombo1
.getNetwork() == ComboAddress("192.0.2.1"));
210 BOOST_CHECK(fromCombo1
.getMaskedNetwork() == ComboAddress("192.0.2.1"));
212 Netmask
nm25("192.0.2.255/25");
213 BOOST_CHECK(nm25
.getBits() == 25);
214 BOOST_CHECK(nm25
.getNetwork() == ComboAddress("192.0.2.255"));
215 BOOST_CHECK(nm25
.getMaskedNetwork() == ComboAddress("192.0.2.128"));
217 /* Make sure that more specific Netmasks are lesser than less specific ones,
218 as this is very useful when matching. */
219 Netmask
specific32("192.0.0.0/32");
220 Netmask
specific24("192.0.0.0/24");
221 Netmask
specific16("192.0.0.0/16");
222 BOOST_CHECK(specific32
< specific24
);
223 BOOST_CHECK(specific24
> specific32
);
224 BOOST_CHECK(specific24
< specific16
);
225 BOOST_CHECK(specific16
> specific24
);
227 Netmask
sameMask1("192.0.0.0/16");
228 Netmask
sameMask2("192.0.0.1/16");
229 BOOST_CHECK(sameMask1
< sameMask2
);
230 BOOST_CHECK(sameMask2
> sameMask1
);
232 /* An empty Netmask should be larger than
234 Netmask empty
= Netmask();
235 Netmask
full("255.255.255.255/32");
236 BOOST_CHECK(empty
> all
);
237 BOOST_CHECK(all
< empty
);
238 BOOST_CHECK(empty
> full
);
239 BOOST_CHECK(full
< empty
);
242 static std::string
NMGOutputToSorted(const std::string
& str
)
244 std::vector
<std::string
> vect
;
245 stringtok(vect
, str
, ", ");
246 std::sort(vect
.begin(), vect
.end());
248 for (const auto& entry
: vect
) {
249 if (!result
.empty()) {
258 BOOST_AUTO_TEST_CASE(test_NetmaskGroup
) {
262 ng
.addMask("10.0.1.0");
263 BOOST_CHECK(ng
.match(ComboAddress("10.0.1.0")));
264 ng
.toMasks("127.0.0.0/8, 10.0.0.0/24");
265 BOOST_CHECK(ng
.match(ComboAddress("127.0.0.1")));
266 BOOST_CHECK(ng
.match(ComboAddress("10.0.0.3")));
267 BOOST_CHECK(ng
.match(ComboAddress("10.0.1.0")));
268 BOOST_CHECK(!ng
.match(ComboAddress("128.1.2.3")));
269 BOOST_CHECK(!ng
.match(ComboAddress("10.0.1.1")));
270 BOOST_CHECK(!ng
.match(ComboAddress("::1")));
272 BOOST_CHECK(ng
.match(ComboAddress("::1")));
273 BOOST_CHECK(!ng
.match(ComboAddress("::2")));
274 ng
.addMask("fe80::/16");
275 BOOST_CHECK(ng
.match(ComboAddress("fe80::1")));
276 BOOST_CHECK(!ng
.match(ComboAddress("fe81::1")));
277 BOOST_CHECK_EQUAL(NMGOutputToSorted(ng
.toString()), NMGOutputToSorted("10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16"));
279 /* negative entries using the explicit flag */
280 ng
.addMask("172.16.0.0/16", true);
281 BOOST_CHECK(ng
.match(ComboAddress("172.16.1.1")));
282 BOOST_CHECK(ng
.match(ComboAddress("172.16.4.50")));
283 ng
.addMask("172.16.4.0/24", false);
284 BOOST_CHECK(ng
.match(ComboAddress("172.16.1.1")));
285 BOOST_CHECK(!ng
.match(ComboAddress("172.16.4.50")));
286 ng
.addMask("fe80::/24", false);
287 BOOST_CHECK(!ng
.match(ComboAddress("fe80::1")));
288 BOOST_CHECK(!ng
.match(ComboAddress("fe81::1")));
289 /* not in fe80::/24 but in fe80::/16, should match */
290 BOOST_CHECK(ng
.match(ComboAddress("fe80:0100::1")));
292 /* negative entries using '!' */
293 BOOST_CHECK(ng
.match(ComboAddress("172.16.10.80")));
294 ng
.addMask("!172.16.10.0/24");
295 BOOST_CHECK(!ng
.match(ComboAddress("172.16.10.80")));
296 ng
.addMask("2001:db8::/32");
297 ng
.addMask("!2001:db8::/64");
298 BOOST_CHECK(!ng
.match(ComboAddress("2001:db8::1")));
299 /* not in 2001:db8::/64 but in 2001:db8::/32, should match */
300 BOOST_CHECK(ng
.match(ComboAddress("2001:db8:1::1")));
302 BOOST_CHECK_EQUAL(NMGOutputToSorted(ng
.toString()), NMGOutputToSorted("10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16, 172.16.0.0/16, !172.16.4.0/24, !fe80::/24, !172.16.10.0/24, 2001:db8::/32, !2001:db8::/64"));
306 /* this time using Netmask objects instead of strings */
308 ng
.addMask(Netmask("10.0.1.0"));
309 BOOST_CHECK(ng
.match(ComboAddress("10.0.1.0")));
310 ng
.addMask(Netmask("127.0.0.0/8"));
311 ng
.addMask(Netmask("10.0.0.0/24"));
312 BOOST_CHECK(ng
.match(ComboAddress("127.0.0.1")));
313 BOOST_CHECK(ng
.match(ComboAddress("10.0.0.3")));
314 BOOST_CHECK(ng
.match(ComboAddress("10.0.1.0")));
315 BOOST_CHECK(!ng
.match(ComboAddress("128.1.2.3")));
316 BOOST_CHECK(!ng
.match(ComboAddress("10.0.1.1")));
317 BOOST_CHECK(!ng
.match(ComboAddress("::1")));
318 ng
.addMask(Netmask("::1"));
319 BOOST_CHECK(ng
.match(ComboAddress("::1")));
320 BOOST_CHECK(!ng
.match(ComboAddress("::2")));
321 ng
.addMask(Netmask("fe80::/16"));
322 BOOST_CHECK(ng
.match(ComboAddress("fe80::1")));
323 BOOST_CHECK(!ng
.match(ComboAddress("fe81::1")));
324 BOOST_CHECK_EQUAL(NMGOutputToSorted(ng
.toString()), NMGOutputToSorted("10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16"));
326 /* negative entries using the explicit flag */
327 ng
.addMask(Netmask("172.16.0.0/16"), true);
328 BOOST_CHECK(ng
.match(ComboAddress("172.16.1.1")));
329 BOOST_CHECK(ng
.match(ComboAddress("172.16.4.50")));
330 ng
.addMask(Netmask("172.16.4.0/24"), false);
331 BOOST_CHECK(ng
.match(ComboAddress("172.16.1.1")));
332 BOOST_CHECK(!ng
.match(ComboAddress("172.16.4.50")));
333 ng
.addMask("fe80::/24", false);
334 BOOST_CHECK(!ng
.match(ComboAddress("fe80::1")));
335 BOOST_CHECK(!ng
.match(ComboAddress("fe81::1")));
336 /* not in fe80::/24 but in fe80::/16, should match */
337 BOOST_CHECK(ng
.match(ComboAddress("fe80:0100::1")));
339 BOOST_CHECK_EQUAL(NMGOutputToSorted(ng
.toString()), NMGOutputToSorted("10.0.1.0/32, 127.0.0.0/8, 10.0.0.0/24, ::1/128, fe80::/16, 172.16.0.0/16, !172.16.4.0/24, !fe80::/24"));
344 BOOST_AUTO_TEST_CASE(test_NetmaskTree
) {
345 NetmaskTree
<int> nmt
;
346 nmt
.insert(Netmask("130.161.252.0/24")).second
=0;
347 nmt
.insert(Netmask("130.161.0.0/16")).second
=1;
348 nmt
.insert(Netmask("130.0.0.0/8")).second
=2;
350 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("213.244.168.210")), (void*)0);
351 auto found
=nmt
.lookup(ComboAddress("130.161.252.29"));
353 BOOST_CHECK_EQUAL(found
->second
, 0);
354 found
=nmt
.lookup(ComboAddress("130.161.180.1"));
356 BOOST_CHECK_EQUAL(found
->second
, 1);
358 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("130.255.255.255"))->second
, 2);
359 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("130.161.252.255"))->second
, 0);
360 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("130.161.253.255"))->second
, 1);
362 found
=nmt
.lookup(ComboAddress("130.145.180.1"));
364 BOOST_CHECK_EQUAL(found
->second
, 2);
367 BOOST_CHECK(!nmt
.lookup(ComboAddress("130.161.180.1")));
369 nmt
.insert(Netmask("::1")).second
=1;
370 nmt
.insert(Netmask("::/0")).second
=0;
371 nmt
.insert(Netmask("fe80::/16")).second
=2;
372 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("130.161.253.255")), (void*)0);
373 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("::2"))->second
, 0);
374 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("::ffff"))->second
, 0);
375 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("::1"))->second
, 1);
376 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("fe80::1"))->second
, 2);
379 BOOST_AUTO_TEST_CASE(test_single
) {
380 NetmaskTree
<bool> nmt
;
381 nmt
.insert(Netmask("127.0.0.0/8")).second
=1;
382 BOOST_CHECK_EQUAL(nmt
.lookup(ComboAddress("127.0.0.1"))->second
, 1);
385 BOOST_AUTO_TEST_CASE(test_scale
) {
386 string start
="192.168.";
387 NetmaskTree
<int> works
;
388 for(int i
=0; i
< 256; ++i
) {
389 for(int j
=0; j
< 256; ++j
) {
390 works
.insert(Netmask(start
+std::to_string(i
)+"."+std::to_string(j
))).second
=i
*j
;
394 for(int i
=0; i
< 256; ++i
) {
395 for(int j
=0; j
< 256; ++j
) {
396 BOOST_CHECK_EQUAL(works
.lookup(ComboAddress(start
+std::to_string(i
)+"."+std::to_string(j
)))->second
, i
*j
);
401 for(int i
=0; i
< 256; ++i
) {
402 for(int j
=0; j
< 256; ++j
) {
403 BOOST_CHECK_EQUAL(works
.lookup(ComboAddress(start
+std::to_string(i
)+"."+std::to_string(j
))), (void*)0);
408 for(int i
=0; i
< 256; ++i
) {
409 for(int j
=0; j
< 256; ++j
) {
410 works
.insert(Netmask(start
+std::to_string(i
)+":"+std::to_string(j
)+"::/64")).second
=i
*j
;
414 for(int i
=0; i
< 256; ++i
) {
415 for(int j
=0; j
< 256; ++j
) {
416 BOOST_CHECK_EQUAL(works
.lookup(ComboAddress(start
+std::to_string(i
)+":"+std::to_string(j
)+"::"+std::to_string(i
)+":"+std::to_string(j
)))->second
, i
*j
);
421 for(int i
=0; i
< 256; ++i
) {
422 for(int j
=0; j
< 256; ++j
) {
423 BOOST_CHECK_EQUAL(works
.lookup(ComboAddress(start
+std::to_string(i
)+":"+std::to_string(j
)+"::"+std::to_string(i
)+":"+std::to_string(j
))), (void*)0);
428 BOOST_AUTO_TEST_CASE(test_removal
) {
429 std::string prefix
= "192.";
430 NetmaskTree
<int> nmt(true);
433 for(unsigned int i
= 0; i
< 256; ++i
) {
434 for(unsigned int j
= 16; j
<= 32; ++j
) {
435 nmt
.insert(Netmask(prefix
+ std::to_string(i
) +".127.255/"+std::to_string(j
))).second
= j
;
440 BOOST_CHECK_EQUAL(nmt
.size(), count
);
442 for(unsigned int i
= 0; i
< 256; ++i
) {
443 ComboAddress
key(prefix
+ std::to_string(i
) + ".127.255");
444 const auto result
= nmt
.lookup(key
);
445 BOOST_CHECK_EQUAL(result
->first
.getBits(), 32);
446 BOOST_CHECK_EQUAL(result
->first
.getMaskedNetwork().toString(), key
.toString());
447 BOOST_CHECK_EQUAL(result
->second
, 32);
450 for(unsigned int i
= 0; i
< 256; ++i
) {
451 for(unsigned int j
= 32; j
>= 16; --j
) {
452 ComboAddress
key(prefix
+ std::to_string(i
) + ".127.255");
453 nmt
.erase(Netmask(key
, j
));
454 const auto result
= nmt
.lookup(key
);
457 BOOST_REQUIRE(result
!= nullptr);
458 BOOST_CHECK_EQUAL(result
->first
.getBits(), j
-1);
459 BOOST_CHECK_EQUAL(result
->first
.getMaskedNetwork().toString(), Netmask(key
, j
-1).getMaskedNetwork().toString());
460 BOOST_CHECK_EQUAL(result
->second
, j
- 1);
463 BOOST_CHECK(result
== nullptr);
468 BOOST_CHECK_EQUAL(nmt
.size(), 0);
469 BOOST_CHECK(nmt
.empty());
472 BOOST_AUTO_TEST_SUITE_END()