]> git.ipfire.org Git - thirdparty/squid.git/blame_incremental - src/tests/testIpAddress.cc
Fix parsing of malformed quoted squid.conf strings (#2239)
[thirdparty/squid.git] / src / tests / testIpAddress.cc
... / ...
CommitLineData
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10#include "compat/cppunit.h"
11#include "compat/netdb.h"
12#include "ip/Address.h"
13#include "ip/tools.h"
14#include "unitTestMain.h"
15
16#include <cstring>
17#include <stdexcept>
18#include <string>
19#if HAVE_NETINET_IN_H
20#include <netinet/in.h>
21#endif
22#if HAVE_ARPA_INET_H
23#include <arpa/inet.h>
24#endif
25
26/*
27 * test the IP storage type
28 */
29
30class TestIpAddress : public CPPUNIT_NS::TestFixture
31{
32 CPPUNIT_TEST_SUITE(TestIpAddress);
33 CPPUNIT_TEST(testDefaults);
34 CPPUNIT_TEST(testInAddrConstructor);
35 CPPUNIT_TEST(testInAddr6Constructor);
36 CPPUNIT_TEST(testSockAddrConstructor);
37 CPPUNIT_TEST(testSockAddr6Constructor);
38 CPPUNIT_TEST(testHostentConstructor);
39 CPPUNIT_TEST(testStringConstructor);
40 CPPUNIT_TEST(testCopyConstructor);
41 CPPUNIT_TEST(testsetEmpty);
42 CPPUNIT_TEST(testBooleans);
43 CPPUNIT_TEST(testAddrInfo);
44 CPPUNIT_TEST(testtoStr);
45 CPPUNIT_TEST(testtoUrl_fromInAddr);
46 CPPUNIT_TEST(testtoUrl_fromSockAddr);
47 CPPUNIT_TEST(testgetReverseString);
48 CPPUNIT_TEST(testMasking);
49
50 CPPUNIT_TEST(testBugNullingDisplay);
51 CPPUNIT_TEST_SUITE_END();
52
53public:
54protected:
55 void testDefaults();
56
57 void testInAddrConstructor();
58 void testInAddr6Constructor();
59 void testSockAddrConstructor();
60 void testSockAddr6Constructor();
61 void testHostentConstructor();
62 void testStringConstructor();
63 void testCopyConstructor();
64
65 void testsetEmpty();
66 void testBooleans();
67
68 void testAddrInfo();
69
70 void testtoStr();
71 void testtoUrl_fromInAddr();
72 void testtoUrl_fromSockAddr();
73 void testgetReverseString();
74 void testMasking();
75
76 // bugs.
77 void testBugNullingDisplay();
78};
79
80CPPUNIT_TEST_SUITE_REGISTRATION( TestIpAddress );
81
82void
83TestIpAddress::testDefaults()
84{
85 Ip::Address anIPA;
86
87 /* test stored values */
88 CPPUNIT_ASSERT( anIPA.isAnyAddr() );
89 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
90 CPPUNIT_ASSERT( !anIPA.isIPv4() );
91 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
92 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
93 CPPUNIT_ASSERT( anIPA.isIPv6() );
94}
95
96void
97TestIpAddress::testInAddrConstructor()
98{
99 struct in_addr inval;
100 struct in_addr outval;
101
102 inval.s_addr = htonl(0xC0A8640C);
103 outval.s_addr = htonl(0x00000000);
104
105 Ip::Address anIPA(inval);
106
107 /* test stored values */
108 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
109 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
110 CPPUNIT_ASSERT( anIPA.isIPv4() );
111 CPPUNIT_ASSERT( !anIPA.isIPv6() );
112 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
113 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
114 anIPA.getInAddr(outval);
115 CPPUNIT_ASSERT( memcmp(&inval, &outval, sizeof(struct in_addr)) == 0 );
116}
117
118void
119TestIpAddress::testInAddr6Constructor()
120{
121 struct in6_addr inval;
122 struct in6_addr outval = IN6ADDR_ANY_INIT;
123
124 inval.s6_addr32[0] = htonl(0xC0A8640C);
125 inval.s6_addr32[1] = htonl(0xFFFFFFFF);
126 inval.s6_addr32[2] = htonl(0xFFFFFFFF);
127 inval.s6_addr32[3] = htonl(0xFFFFFFFF);
128
129 Ip::Address anIPA(inval);
130
131 /* test stored values */
132 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
133 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
134 CPPUNIT_ASSERT( !anIPA.isIPv4() );
135 CPPUNIT_ASSERT( anIPA.isIPv6() );
136 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
137 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
138 anIPA.getInAddr(outval);
139 CPPUNIT_ASSERT( memcmp( &inval, &outval, sizeof(struct in6_addr)) == 0 );
140}
141
142void
143TestIpAddress::testSockAddrConstructor()
144{
145 struct sockaddr_in insock;
146 struct sockaddr_in outsock;
147
148 memset(&insock, 0, sizeof(struct sockaddr_in));
149 memset(&outsock, 0, sizeof(struct sockaddr_in));
150
151 insock.sin_family = AF_INET;
152 insock.sin_port = htons(80);
153 insock.sin_addr.s_addr = htonl(0xC0A8640C);
154#if HAVE_SIN_LEN_IN_SAI
155 insock.sin_len = sizeof(struct sockaddr_in);
156#endif
157
158 Ip::Address anIPA(insock);
159
160 /* test stored values */
161 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
162 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
163 CPPUNIT_ASSERT( anIPA.isIPv4() );
164 CPPUNIT_ASSERT( !anIPA.isIPv6() );
165 CPPUNIT_ASSERT( anIPA.isSockAddr() );
166 CPPUNIT_ASSERT_EQUAL( (unsigned short) 80, anIPA.port() );
167 anIPA.getSockAddr(outsock);
168 CPPUNIT_ASSERT( memcmp( &insock, &outsock, sizeof(struct sockaddr_in)) == 0 );
169}
170
171void
172TestIpAddress::testSockAddr6Constructor()
173{
174 struct sockaddr_in6 insock;
175 struct sockaddr_in6 outsock;
176
177 memset(&insock, 0, sizeof(struct sockaddr_in6));
178 memset(&outsock, 0, sizeof(struct sockaddr_in6));
179
180 insock.sin6_family = AF_INET6;
181 insock.sin6_port = htons(80);
182 insock.sin6_addr.s6_addr32[0] = htonl(0xFFFFFFFF);
183 insock.sin6_addr.s6_addr32[1] = htonl(0x00000000);
184 insock.sin6_addr.s6_addr32[2] = htonl(0x0000FFFF);
185 insock.sin6_addr.s6_addr32[3] = htonl(0xC0A8640C);
186#if HAVE_SIN6_LEN_IN_SAI
187 insock.sin6_len = sizeof(struct sockaddr_in6);
188#endif
189
190 Ip::Address anIPA((const struct sockaddr_in6)insock);
191
192 /* test stored values */
193 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
194 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
195 CPPUNIT_ASSERT( !anIPA.isIPv4() );
196 CPPUNIT_ASSERT( anIPA.isIPv6() );
197 CPPUNIT_ASSERT( anIPA.isSockAddr() );
198 CPPUNIT_ASSERT_EQUAL( (unsigned short) 80, anIPA.port() );
199 anIPA.getSockAddr(outsock);
200 CPPUNIT_ASSERT( memcmp( &insock, &outsock, sizeof(struct sockaddr_in6)) == 0 );
201}
202
203void
204TestIpAddress::testCopyConstructor()
205{
206 struct sockaddr_in insock;
207 struct sockaddr_in outsock;
208
209 memset(&insock, 0, sizeof(struct sockaddr_in));
210 memset(&outsock, 0, sizeof(struct sockaddr_in));
211
212 insock.sin_family = AF_INET;
213 insock.sin_port = htons(80);
214 insock.sin_addr.s_addr = htonl(0xC0A8640C);
215#if HAVE_SIN_LEN_IN_SAI
216 insock.sin_len = sizeof(struct sockaddr_in);
217#endif
218
219 Ip::Address inIPA(insock);
220 Ip::Address outIPA(inIPA);
221
222 /* test stored values */
223 CPPUNIT_ASSERT( !outIPA.isAnyAddr() );
224 CPPUNIT_ASSERT( !outIPA.isNoAddr() );
225 CPPUNIT_ASSERT( outIPA.isIPv4() );
226 CPPUNIT_ASSERT( !outIPA.isIPv6() );
227 CPPUNIT_ASSERT( outIPA.isSockAddr() );
228 CPPUNIT_ASSERT_EQUAL( (unsigned short) 80, outIPA.port() );
229 outIPA.getSockAddr(outsock);
230 CPPUNIT_ASSERT( memcmp( &insock, &outsock, sizeof(struct sockaddr_in)) == 0 );
231}
232
233void
234TestIpAddress::testHostentConstructor()
235{
236 struct in_addr outval;
237 struct in_addr expectval;
238
239 expectval.s_addr = htonl(0xC0A8640C);
240
241 const auto hp = xgethostbyname("192.168.100.12");
242 CPPUNIT_ASSERT( hp != nullptr /* gethostbyname failure.*/ );
243
244 Ip::Address anIPA(*hp);
245
246 /* test stored values */
247 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
248 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
249 CPPUNIT_ASSERT( anIPA.isIPv4() );
250 CPPUNIT_ASSERT( !anIPA.isIPv6() );
251 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
252 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
253 anIPA.getInAddr(outval);
254 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
255}
256
257void
258TestIpAddress::testStringConstructor()
259{
260 struct in_addr outval;
261 struct in_addr expectval;
262
263 expectval.s_addr = htonl(0xC0A8640C);
264
265 Ip::Address anIPA = "192.168.100.12";
266
267 /* test stored values */
268 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
269 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
270 CPPUNIT_ASSERT( anIPA.isIPv4() );
271 CPPUNIT_ASSERT( !anIPA.isIPv6() );
272 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
273 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
274 anIPA.getInAddr(outval);
275 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
276
277 struct in6_addr expectv6;
278 struct in6_addr outval6;
279
280 expectv6.s6_addr32[0] = htonl(0x20000800);
281 expectv6.s6_addr32[1] = htonl(0x00000000);
282 expectv6.s6_addr32[2] = htonl(0x00000000);
283 expectv6.s6_addr32[3] = htonl(0x00000045);
284
285 Ip::Address bnIPA = "2000:800::45";
286
287//char test[256];
288//bnIPA.toStr(test, 256);
289//printf("bnIPA: %s\n", test);
290
291 /* test stored values */
292 CPPUNIT_ASSERT( !bnIPA.isAnyAddr() );
293 CPPUNIT_ASSERT( !bnIPA.isNoAddr() );
294 CPPUNIT_ASSERT( !bnIPA.isIPv4() );
295 CPPUNIT_ASSERT( bnIPA.isIPv6() );
296 CPPUNIT_ASSERT( !bnIPA.isSockAddr() );
297 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, bnIPA.port() );
298 bnIPA.getInAddr(outval6);
299 CPPUNIT_ASSERT( memcmp( &expectv6, &outval6, sizeof(struct in6_addr)) == 0 );
300
301 /* test IPv6 as an old netmask format. This is invalid but sometimes use. */
302 Ip::Address cnIPA = "ffff:ffff:fff0::";
303
304 expectv6.s6_addr32[0] = htonl(0xFFFFFFFF);
305 expectv6.s6_addr32[1] = htonl(0xFFF00000);
306 expectv6.s6_addr32[2] = htonl(0x00000000);
307 expectv6.s6_addr32[3] = htonl(0x00000000);
308
309 /* test stored values */
310 CPPUNIT_ASSERT( !cnIPA.isAnyAddr() );
311 CPPUNIT_ASSERT( !cnIPA.isNoAddr() );
312 CPPUNIT_ASSERT( !cnIPA.isIPv4() );
313 CPPUNIT_ASSERT( cnIPA.isIPv6() );
314 CPPUNIT_ASSERT( !cnIPA.isSockAddr() );
315 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, cnIPA.port() );
316 cnIPA.getInAddr(outval6);
317 CPPUNIT_ASSERT( memcmp( &expectv6, &outval6, sizeof(struct in6_addr)) == 0 );
318}
319
320void
321TestIpAddress::testsetEmpty()
322{
323 Ip::Address anIPA;
324 struct in_addr inval;
325
326 inval.s_addr = htonl(0xC0A8640C);
327
328 anIPA = inval;
329
330 /* test stored values before empty */
331 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
332 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
333 CPPUNIT_ASSERT( anIPA.isIPv4() );
334 CPPUNIT_ASSERT( !anIPA.isIPv6() );
335 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
336 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
337
338 anIPA.setEmpty();
339
340 /* test stored values after empty */
341 CPPUNIT_ASSERT( anIPA.isAnyAddr() );
342 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
343 CPPUNIT_ASSERT( !anIPA.isIPv4() );
344 CPPUNIT_ASSERT( anIPA.isIPv6() );
345 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
346 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
347}
348
349void
350TestIpAddress::testBooleans()
351{
352 Ip::Address lhsIPA;
353 Ip::Address rhsIPA;
354 struct in_addr valLow;
355 struct in_addr valHigh;
356
357 valLow.s_addr = htonl(0xC0A8640C);
358 valHigh.s_addr = htonl(0xC0A8640F);
359
360 /* test equality */
361 lhsIPA = valLow;
362 rhsIPA = valLow;
363 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) == 0 );
364 CPPUNIT_ASSERT( ( lhsIPA == rhsIPA ) );
365 CPPUNIT_ASSERT( !( lhsIPA != rhsIPA ) );
366 CPPUNIT_ASSERT( ( lhsIPA >= rhsIPA ) );
367 CPPUNIT_ASSERT( !( lhsIPA > rhsIPA ) );
368 CPPUNIT_ASSERT( ( lhsIPA <= rhsIPA ) );
369 CPPUNIT_ASSERT( !( lhsIPA < rhsIPA ) );
370
371 /* test equality versus ANYADDR */
372 lhsIPA.setAnyAddr();
373 rhsIPA.setAnyAddr();
374 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) == 0 );
375 CPPUNIT_ASSERT( ( lhsIPA == rhsIPA ) );
376 CPPUNIT_ASSERT( !( lhsIPA != rhsIPA ) );
377 CPPUNIT_ASSERT( ( lhsIPA >= rhsIPA ) );
378 CPPUNIT_ASSERT( !( lhsIPA > rhsIPA ) );
379 CPPUNIT_ASSERT( ( lhsIPA <= rhsIPA ) );
380 CPPUNIT_ASSERT( !( lhsIPA < rhsIPA ) );
381
382 /* test equality versus NOADDR */
383 lhsIPA.setNoAddr();
384 rhsIPA.setNoAddr();
385 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) == 0 );
386 CPPUNIT_ASSERT( ( lhsIPA == rhsIPA ) );
387 CPPUNIT_ASSERT( !( lhsIPA != rhsIPA ) );
388 CPPUNIT_ASSERT( ( lhsIPA >= rhsIPA ) );
389 CPPUNIT_ASSERT( !( lhsIPA > rhsIPA ) );
390 CPPUNIT_ASSERT( ( lhsIPA <= rhsIPA ) );
391 CPPUNIT_ASSERT( !( lhsIPA < rhsIPA ) );
392
393 /* test inequality (less than) */
394 lhsIPA = valLow;
395 rhsIPA = valHigh;
396 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) < 0 );
397 CPPUNIT_ASSERT( !( lhsIPA == rhsIPA ) );
398 CPPUNIT_ASSERT( ( lhsIPA != rhsIPA ) );
399 CPPUNIT_ASSERT( !( lhsIPA >= rhsIPA ) );
400 CPPUNIT_ASSERT( !( lhsIPA > rhsIPA ) );
401 CPPUNIT_ASSERT( ( lhsIPA <= rhsIPA ) );
402 CPPUNIT_ASSERT( ( lhsIPA < rhsIPA ) );
403
404 /* test inequality versus ANYADDR (less than) */
405 lhsIPA.setAnyAddr();
406 rhsIPA = valHigh;
407 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) < 0 );
408 CPPUNIT_ASSERT( !( lhsIPA == rhsIPA ) );
409 CPPUNIT_ASSERT( ( lhsIPA != rhsIPA ) );
410 CPPUNIT_ASSERT( !( lhsIPA >= rhsIPA ) );
411 CPPUNIT_ASSERT( !( lhsIPA > rhsIPA ) );
412 CPPUNIT_ASSERT( ( lhsIPA <= rhsIPA ) );
413 CPPUNIT_ASSERT( ( lhsIPA < rhsIPA ) );
414
415 /* test inequality versus NOADDR (less than) */
416 lhsIPA = valLow;
417 rhsIPA.setNoAddr();
418 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) < 0 );
419 CPPUNIT_ASSERT( !( lhsIPA == rhsIPA ) );
420 CPPUNIT_ASSERT( ( lhsIPA != rhsIPA ) );
421 CPPUNIT_ASSERT( !( lhsIPA >= rhsIPA ) );
422 CPPUNIT_ASSERT( !( lhsIPA > rhsIPA ) );
423 CPPUNIT_ASSERT( ( lhsIPA <= rhsIPA ) );
424 CPPUNIT_ASSERT( ( lhsIPA < rhsIPA ) );
425
426 /* test inequality (greater than) */
427 lhsIPA = valHigh;
428 rhsIPA = valLow;
429 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) > 0 );
430 CPPUNIT_ASSERT( !( lhsIPA == rhsIPA ) );
431 CPPUNIT_ASSERT( ( lhsIPA != rhsIPA ) );
432 CPPUNIT_ASSERT( ( lhsIPA >= rhsIPA ) );
433 CPPUNIT_ASSERT( ( lhsIPA > rhsIPA ) );
434 CPPUNIT_ASSERT( !( lhsIPA <= rhsIPA ) );
435 CPPUNIT_ASSERT( !( lhsIPA < rhsIPA ) );
436
437 /* test inequality (greater than) */
438 lhsIPA = valHigh;
439 rhsIPA.setAnyAddr();
440 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) > 0 );
441 CPPUNIT_ASSERT( !( lhsIPA == rhsIPA ) );
442 CPPUNIT_ASSERT( ( lhsIPA != rhsIPA ) );
443 CPPUNIT_ASSERT( ( lhsIPA >= rhsIPA ) );
444 CPPUNIT_ASSERT( ( lhsIPA > rhsIPA ) );
445 CPPUNIT_ASSERT( !( lhsIPA <= rhsIPA ) );
446 CPPUNIT_ASSERT( !( lhsIPA < rhsIPA ) );
447
448 /* test inequality versus NOADDR (greater than) */
449 lhsIPA.setNoAddr();
450 rhsIPA = valLow;
451 CPPUNIT_ASSERT( lhsIPA.matchIPAddr(rhsIPA) > 0 );
452 CPPUNIT_ASSERT( !( lhsIPA == rhsIPA ) );
453 CPPUNIT_ASSERT( ( lhsIPA != rhsIPA ) );
454 CPPUNIT_ASSERT( ( lhsIPA >= rhsIPA ) );
455 CPPUNIT_ASSERT( ( lhsIPA > rhsIPA ) );
456 CPPUNIT_ASSERT( !( lhsIPA <= rhsIPA ) );
457 CPPUNIT_ASSERT( !( lhsIPA < rhsIPA ) );
458
459}
460
461void
462TestIpAddress::testtoStr()
463{
464 struct in_addr inval;
465 char buf[MAX_IPSTRLEN];
466 Ip::Address anIPA;
467
468 anIPA.setAnyAddr();
469
470 /* test AnyAddr display values */
471 CPPUNIT_ASSERT( memcmp("::", anIPA.toStr(buf,MAX_IPSTRLEN), 2) == 0 );
472
473 inval.s_addr = htonl(0xC0A8640C);
474 anIPA = inval;
475
476 /* test IP display */
477 CPPUNIT_ASSERT( memcmp("192.168.100.12",anIPA.toStr(buf,MAX_IPSTRLEN), 14) == 0 );
478
479 anIPA.setNoAddr();
480
481 /* test NoAddr display values */
482 CPPUNIT_ASSERT( memcmp("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",anIPA.toStr(buf,MAX_IPSTRLEN), 39) == 0 );
483}
484
485void
486TestIpAddress::testtoUrl_fromInAddr()
487{
488 char buf[MAX_IPSTRLEN];
489 buf[0] = '\0';
490 struct in_addr inval;
491
492 inval.s_addr = htonl(0xC0A8640C);
493
494 Ip::Address anIPA(inval);
495
496 /* test values */
497 anIPA.toUrl(buf,MAX_IPSTRLEN);
498 CPPUNIT_ASSERT( memcmp("192.168.100.12", buf, 14) == 0 );
499
500 /* test output when constructed from in6_addr with IPv6 */
501 struct in6_addr ip6val;
502
503 ip6val.s6_addr32[0] = htonl(0xC0A8640C);
504 ip6val.s6_addr32[1] = htonl(0xFFFFFFFF);
505 ip6val.s6_addr32[2] = htonl(0xFFFFFFFF);
506 ip6val.s6_addr32[3] = htonl(0xFFFFFFFF);
507
508 Ip::Address bnIPA(ip6val);
509
510 bnIPA.toUrl(buf,MAX_IPSTRLEN);
511 CPPUNIT_ASSERT( memcmp("[c0a8:640c:ffff:ffff:ffff:ffff:ffff:ffff]", buf, 41) == 0 );
512}
513
514void
515TestIpAddress::testtoUrl_fromSockAddr()
516{
517 struct sockaddr_in sock;
518 sock.sin_addr.s_addr = htonl(0xC0A8640C);
519 sock.sin_port = htons(80);
520 sock.sin_family = AF_INET;
521#if HAVE_SIN_LEN_IN_SAI
522 sock.sin_len = sizeof(struct sockaddr_in);
523#endif
524
525 Ip::Address anIPA(sock);
526 char buf[MAX_IPSTRLEN];
527
528 /* test values */
529 anIPA.toUrl(buf,MAX_IPSTRLEN);
530 CPPUNIT_ASSERT( memcmp("192.168.100.12:80", buf, 17) == 0 );
531
532 /* test output when constructed from in6_addr with IPv6 */
533 struct sockaddr_in6 ip6val;
534
535 ip6val.sin6_addr.s6_addr32[0] = htonl(0xC0A8640C);
536 ip6val.sin6_addr.s6_addr32[1] = htonl(0xFFFFFFFF);
537 ip6val.sin6_addr.s6_addr32[2] = htonl(0xFFFFFFFF);
538 ip6val.sin6_addr.s6_addr32[3] = htonl(0xFFFFFFFF);
539 ip6val.sin6_port = htons(80);
540 ip6val.sin6_family = AF_INET6;
541#if HAVE_SIN6_LEN_IN_SAI
542 ip6val.sin6_len = sizeof(struct sockaddr_in6);
543#endif
544
545 Ip::Address bnIPA(ip6val);
546
547 bnIPA.toUrl(buf,MAX_IPSTRLEN);
548 CPPUNIT_ASSERT( memcmp("[c0a8:640c:ffff:ffff:ffff:ffff:ffff:ffff]:80", buf, 44) == 0 );
549}
550
551void
552TestIpAddress::testgetReverseString()
553{
554 char buf[MAX_IPSTRLEN];
555
556 struct in_addr ipv4val;
557 ipv4val.s_addr = htonl(0xC0A8640C);
558
559 Ip::Address v4IPA(ipv4val);
560
561 /* test IPv4 output */
562 v4IPA.getReverseString(buf);
563 CPPUNIT_ASSERT( memcmp("12.100.168.192.in-addr.arpa.",buf, 28) == 0 );
564
565 v4IPA.getReverseString(buf,AF_INET);
566 CPPUNIT_ASSERT( memcmp("12.100.168.192.in-addr.arpa.",buf, 28) == 0 );
567
568 v4IPA.getReverseString(buf,AF_INET6);
569 CPPUNIT_ASSERT( memcmp("",buf, 1) == 0 );
570
571 struct in6_addr ip6val;
572
573 ip6val.s6_addr32[0] = htonl(0xC0A8640C);
574 ip6val.s6_addr32[1] = htonl(0xFFFFFFFF);
575 ip6val.s6_addr32[2] = htonl(0xFFFFFFFF);
576 ip6val.s6_addr32[3] = htonl(0xFFFFFFFF);
577
578 Ip::Address v6IPA(ip6val);
579
580 /* test IPv6 output */
581 v6IPA.getReverseString(buf);
582 CPPUNIT_ASSERT( memcmp("f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.c.0.4.6.8.a.0.c.ip6.arpa.",buf,73) == 0 );
583}
584
585void
586TestIpAddress::testMasking()
587{
588 char buf[MAX_IPSTRLEN];
589 Ip::Address anIPA;
590 Ip::Address maskIPA;
591
592 /* Test Basic CIDR Routine */
593 anIPA.setAnyAddr();
594 CPPUNIT_ASSERT_EQUAL( 0,anIPA.cidr() );
595
596 anIPA.setNoAddr();
597 CPPUNIT_ASSERT_EQUAL( 128, anIPA.cidr() );
598
599 /* Test Numeric ApplyCIDR */
600 anIPA.setNoAddr();
601 CPPUNIT_ASSERT( !anIPA.applyMask(129,AF_INET6) );
602 CPPUNIT_ASSERT( !anIPA.applyMask(33,AF_INET) );
603
604 anIPA.setNoAddr();
605 CPPUNIT_ASSERT( anIPA.applyMask(31,AF_INET) );
606 CPPUNIT_ASSERT_EQUAL( 127, anIPA.cidr() );
607
608 anIPA.setNoAddr();
609 CPPUNIT_ASSERT( anIPA.applyMask(127,AF_INET6) );
610 CPPUNIT_ASSERT_EQUAL( 127, anIPA.cidr() );
611
612 anIPA.setNoAddr();
613 anIPA.applyMask(80,AF_INET6);
614 CPPUNIT_ASSERT_EQUAL( 80, anIPA.cidr() );
615
616 /* BUG Check: test values by display. */
617 CPPUNIT_ASSERT( anIPA.toStr(buf,MAX_IPSTRLEN) != nullptr );
618 CPPUNIT_ASSERT( memcmp("ffff:ffff:ffff:ffff:ffff::", buf, 26) == 0 );
619
620 /* Test Network Bitmask from Ip::Address */
621 anIPA.setNoAddr();
622 maskIPA = "255.255.240.0";
623 CPPUNIT_ASSERT_EQUAL( 20, maskIPA.cidr() );
624 anIPA.applyMask(maskIPA);
625 CPPUNIT_ASSERT_EQUAL( 20, anIPA.cidr() );
626
627 /* BUG Check: test values memory after masking. */
628 struct in_addr btest;
629 CPPUNIT_ASSERT( anIPA.isIPv4() );
630 CPPUNIT_ASSERT( !anIPA.isIPv6() );
631 anIPA.getInAddr(btest);
632 CPPUNIT_ASSERT_EQUAL( (uint32_t)htonl(0xFFFFF000), btest.s_addr );
633
634 /* BUG Check failing test. Masked values for display. */
635 CPPUNIT_ASSERT( memcmp("255.255.240.0",anIPA.toStr(buf,MAX_IPSTRLEN), 13) == 0 );
636
637 anIPA.setNoAddr();
638 maskIPA.setNoAddr();
639
640 /* IPv6 masks MUST be CIDR representations. */
641 /* however as with IPv4 they can technically be represented as a bitmask */
642 maskIPA = "ffff:ffff:fff0::";
643 CPPUNIT_ASSERT( !maskIPA.isAnyAddr() );
644 CPPUNIT_ASSERT( !maskIPA.isNoAddr() );
645 anIPA.applyMask(maskIPA);
646 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
647 CPPUNIT_ASSERT_EQUAL( 44, anIPA.cidr() );
648
649 anIPA.setNoAddr();
650 maskIPA.setNoAddr();
651
652 /* IPv4 masks represented in IPv6 as IPv4 bitmasks. */
653 maskIPA = "::ffff:ffff:f000";
654 CPPUNIT_ASSERT( !maskIPA.isAnyAddr() );
655 CPPUNIT_ASSERT( !maskIPA.isNoAddr() );
656 CPPUNIT_ASSERT( maskIPA.isIPv4() );
657 CPPUNIT_ASSERT( !maskIPA.isIPv6() );
658 anIPA.applyMask(maskIPA);
659 CPPUNIT_ASSERT( !maskIPA.isAnyAddr() );
660 CPPUNIT_ASSERT( !maskIPA.isNoAddr() );
661 CPPUNIT_ASSERT( maskIPA.isIPv4() );
662 CPPUNIT_ASSERT( !maskIPA.isIPv6() );
663 CPPUNIT_ASSERT_EQUAL( 20, anIPA.cidr() );
664}
665
666void
667TestIpAddress::testAddrInfo()
668{
669 struct addrinfo *expect;
670 struct addrinfo *ipval = nullptr;
671 struct addrinfo hints;
672
673 memset(&hints, 0, sizeof(struct addrinfo));
674
675 hints.ai_flags = AI_NUMERICHOST;
676
677 Ip::Address anIP = "127.0.0.1";
678
679 /* assert this just to check that getaddrinfo is working properly */
680 CPPUNIT_ASSERT( getaddrinfo("127.0.0.1", nullptr, &hints, &expect ) == 0 );
681
682 anIP.getAddrInfo(ipval);
683
684 // check the addrinfo object core. (BUT not the two ptrs at the tail)
685 // details
686 CPPUNIT_ASSERT_EQUAL( expect->ai_flags, ipval->ai_flags );
687 CPPUNIT_ASSERT_EQUAL( expect->ai_family, ipval->ai_family );
688 // check the sockaddr it points to.
689 CPPUNIT_ASSERT_EQUAL( expect->ai_addrlen, ipval->ai_addrlen );
690
691#if HAVE_SS_LEN_IN_SS
692 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_storage*)expect->ai_addr)->ss_len,
693 ((struct sockaddr_storage*)ipval->ai_addr)->ss_len );
694 CPPUNIT_ASSERT_EQUAL( (socklen_t)((struct sockaddr_storage*)ipval->ai_addr)->ss_len, ipval->ai_addrlen );
695#endif
696#if HAVE_SIN6_LEN_IN_SAI
697 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_in6*)expect->ai_addr)->sin6_len,
698 ((struct sockaddr_in6*)ipval->ai_addr)->sin6_len );
699 CPPUNIT_ASSERT_EQUAL( (socklen_t)((struct sockaddr_in6*)ipval->ai_addr)->sin6_len, ipval->ai_addrlen );
700#endif
701#if HAVE_SIN_LEN_IN_SAI
702 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_in*)expect->ai_addr)->sin_len,
703 ((struct sockaddr_in*)ipval->ai_addr)->sin_len );
704 CPPUNIT_ASSERT_EQUAL( (socklen_t)((struct sockaddr_in*)ipval->ai_addr)->sin_len, ipval->ai_addrlen );
705#endif
706
707 if (expect->ai_addrlen == sizeof(struct sockaddr_in)) {
708//printf("FAMILY %d %d\n", ((struct sockaddr_in*)expect->ai_addr)->sin_family, ((struct sockaddr_in*)ipval->ai_addr)->sin_family);
709 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_in*)expect->ai_addr)->sin_family,
710 ((struct sockaddr_in*)ipval->ai_addr)->sin_family );
711//printf("PORT %d %d\n", ((struct sockaddr_in*)expect->ai_addr)->sin_port, ((struct sockaddr_in*)ipval->ai_addr)->sin_port);
712 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_in*)expect->ai_addr)->sin_port,
713 ((struct sockaddr_in*)ipval->ai_addr)->sin_port );
714 }
715 if (expect->ai_addrlen == sizeof(struct sockaddr_in6)) {
716//printf("FAMILY %d %d\n", ((struct sockaddr_in6*)expect->ai_addr)->sin6_family, ((struct sockaddr_in6*)ipval->ai_addr)->sin6_family);
717 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_in6*)expect->ai_addr)->sin6_family,
718 ((struct sockaddr_in6*)ipval->ai_addr)->sin6_family );
719//printf("PORT %d %d\n", ((struct sockaddr_in6*)expect->ai_addr)->sin6_port, ((struct sockaddr_in6*)ipval->ai_addr)->sin6_port);
720 CPPUNIT_ASSERT_EQUAL( ((struct sockaddr_in6*)expect->ai_addr)->sin6_port,
721 ((struct sockaddr_in6*)ipval->ai_addr)->sin6_port );
722 }
723
724 CPPUNIT_ASSERT( memcmp( expect->ai_addr, ipval->ai_addr, expect->ai_addrlen ) == 0 );
725
726 freeaddrinfo(expect);
727 Ip::Address::FreeAddr(ipval);
728}
729
730void
731TestIpAddress::testBugNullingDisplay()
732{
733 // Weird Bug: address set to empty during string conversion somewhere.
734 // initial string gets created and returned OK.
735 // but at the end of the process m_SocketAddr is left NULL'ed
736
737 char ntoabuf[MAX_IPSTRLEN];
738 char hostbuf[MAX_IPSTRLEN];
739 char urlbuf[MAX_IPSTRLEN];
740
741 struct in_addr outval;
742 struct in_addr expectval;
743
744 expectval.s_addr = htonl(0xC0A8640C);
745
746 Ip::Address anIPA = "192.168.100.12";
747
748 /* test stored values */
749 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
750 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
751 CPPUNIT_ASSERT( anIPA.isIPv4() );
752 CPPUNIT_ASSERT( !anIPA.isIPv6() );
753 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
754 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
755 anIPA.getInAddr(outval);
756 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
757
758 /* POKE toStr display function to see what it is doing */
759 anIPA.toStr(ntoabuf,MAX_IPSTRLEN);
760 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
761 /* test stored values */
762 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
763 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
764 CPPUNIT_ASSERT( anIPA.isIPv4() );
765 CPPUNIT_ASSERT( !anIPA.isIPv6() );
766 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
767 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
768 anIPA.getInAddr(outval);
769 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
770
771 /* POKE toHostStr display function to see what it is doing */
772 anIPA.toHostStr(hostbuf,MAX_IPSTRLEN);
773 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
774 /* test stored values */
775 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
776 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
777 CPPUNIT_ASSERT( anIPA.isIPv4() );
778 CPPUNIT_ASSERT( !anIPA.isIPv6() );
779 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
780 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
781 anIPA.getInAddr(outval);
782 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
783
784 /* POKE toUrl display function to see what it is doing */
785 anIPA.toUrl(urlbuf,MAX_IPSTRLEN);
786 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
787 /* test stored values */
788 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
789 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
790 CPPUNIT_ASSERT( anIPA.isIPv4() );
791 CPPUNIT_ASSERT( !anIPA.isIPv6() );
792 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
793 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
794 anIPA.getInAddr(outval);
795 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
796
797}
798
799int
800main(int argc, char *argv[])
801{
802 return TestProgram().run(argc, argv);
803}
804