]> git.ipfire.org Git - thirdparty/squid.git/blame - src/tests/testIpAddress.cc
Fix parsing of malformed quoted squid.conf strings (#2239)
[thirdparty/squid.git] / src / tests / testIpAddress.cc
CommitLineData
bbc27441 1/*
1f7b830e 2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
bbc27441
AJ
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
f7f3304a 9#include "squid.h"
ae022809 10#include "compat/cppunit.h"
5be401dc 11#include "compat/netdb.h"
96d89ea0 12#include "ip/Address.h"
055421ee 13#include "ip/tools.h"
7f861c77
AJ
14#include "unitTestMain.h"
15
b610642c 16#include <cstring>
074d6a40
AJ
17#include <stdexcept>
18#include <string>
27e059d4 19#if HAVE_NETINET_IN_H
41d93087 20#include <netinet/in.h>
27e059d4
AJ
21#endif
22#if HAVE_ARPA_INET_H
41d93087 23#include <arpa/inet.h>
27e059d4 24#endif
41d93087 25
ae022809
FC
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
41e9c9f0 80CPPUNIT_TEST_SUITE_REGISTRATION( TestIpAddress );
41d93087 81
41d93087 82void
41e9c9f0 83TestIpAddress::testDefaults()
41d93087 84{
b7ac5457 85 Ip::Address anIPA;
41d93087 86
87 /* test stored values */
4dd643d5
AJ
88 CPPUNIT_ASSERT( anIPA.isAnyAddr() );
89 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
90 CPPUNIT_ASSERT( !anIPA.isIPv4() );
91 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
9e167fa2 92 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5 93 CPPUNIT_ASSERT( anIPA.isIPv6() );
41d93087 94}
95
96void
41e9c9f0 97TestIpAddress::testInAddrConstructor()
41d93087 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
b7ac5457 105 Ip::Address anIPA(inval);
41d93087 106
107 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 113 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5 114 anIPA.getInAddr(outval);
41d93087 115 CPPUNIT_ASSERT( memcmp(&inval, &outval, sizeof(struct in_addr)) == 0 );
116}
117
41d93087 118void
41e9c9f0 119TestIpAddress::testInAddr6Constructor()
41d93087 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
b7ac5457 129 Ip::Address anIPA(inval);
41d93087 130
131 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 137 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5 138 anIPA.getInAddr(outval);
41d93087 139 CPPUNIT_ASSERT( memcmp( &inval, &outval, sizeof(struct in6_addr)) == 0 );
140}
41d93087 141
142void
41e9c9f0 143TestIpAddress::testSockAddrConstructor()
41d93087 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);
1ef0b9ce
AJ
154#if HAVE_SIN_LEN_IN_SAI
155 insock.sin_len = sizeof(struct sockaddr_in);
156#endif
41d93087 157
68fb74b0 158 Ip::Address anIPA(insock);
41d93087 159
160 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 166 CPPUNIT_ASSERT_EQUAL( (unsigned short) 80, anIPA.port() );
4dd643d5 167 anIPA.getSockAddr(outsock);
41d93087 168 CPPUNIT_ASSERT( memcmp( &insock, &outsock, sizeof(struct sockaddr_in)) == 0 );
169}
170
41d93087 171void
41e9c9f0 172TestIpAddress::testSockAddr6Constructor()
41d93087 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);
1ef0b9ce
AJ
186#if HAVE_SIN6_LEN_IN_SAI
187 insock.sin6_len = sizeof(struct sockaddr_in6);
188#endif
41d93087 189
b7ac5457 190 Ip::Address anIPA((const struct sockaddr_in6)insock);
41d93087 191
192 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 198 CPPUNIT_ASSERT_EQUAL( (unsigned short) 80, anIPA.port() );
4dd643d5 199 anIPA.getSockAddr(outsock);
41d93087 200 CPPUNIT_ASSERT( memcmp( &insock, &outsock, sizeof(struct sockaddr_in6)) == 0 );
201}
41d93087 202
41d93087 203void
41e9c9f0 204TestIpAddress::testCopyConstructor()
41d93087 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);
1ef0b9ce
AJ
215#if HAVE_SIN_LEN_IN_SAI
216 insock.sin_len = sizeof(struct sockaddr_in);
217#endif
41d93087 218
b7ac5457
AJ
219 Ip::Address inIPA(insock);
220 Ip::Address outIPA(inIPA);
41d93087 221
41d93087 222 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 228 CPPUNIT_ASSERT_EQUAL( (unsigned short) 80, outIPA.port() );
4dd643d5 229 outIPA.getSockAddr(outsock);
41d93087 230 CPPUNIT_ASSERT( memcmp( &insock, &outsock, sizeof(struct sockaddr_in)) == 0 );
231}
232
233void
41e9c9f0 234TestIpAddress::testHostentConstructor()
41d93087 235{
41d93087 236 struct in_addr outval;
237 struct in_addr expectval;
238
239 expectval.s_addr = htonl(0xC0A8640C);
240
5be401dc 241 const auto hp = xgethostbyname("192.168.100.12");
aee3523a 242 CPPUNIT_ASSERT( hp != nullptr /* gethostbyname failure.*/ );
41d93087 243
b7ac5457 244 Ip::Address anIPA(*hp);
41d93087 245
246 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 252 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5 253 anIPA.getInAddr(outval);
41d93087 254 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
255}
256
257void
41e9c9f0 258TestIpAddress::testStringConstructor()
41d93087 259{
260 struct in_addr outval;
261 struct in_addr expectval;
262
263 expectval.s_addr = htonl(0xC0A8640C);
264
b7ac5457 265 Ip::Address anIPA = "192.168.100.12";
41d93087 266
267 /* test stored values */
4dd643d5
AJ
268 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
269 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
270 CPPUNIT_ASSERT( anIPA.isIPv4() );
271 CPPUNIT_ASSERT( !anIPA.isIPv6() );
9e167fa2 272 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5
AJ
273 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
274 anIPA.getInAddr(outval);
41d93087 275 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
276
41d93087 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
b7ac5457 285 Ip::Address bnIPA = "2000:800::45";
41d93087 286
055421ee 287//char test[256];
4dd643d5 288//bnIPA.toStr(test, 256);
055421ee
AJ
289//printf("bnIPA: %s\n", test);
290
41d93087 291 /* test stored values */
4dd643d5
AJ
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() );
9e167fa2 297 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, bnIPA.port() );
4dd643d5 298 bnIPA.getInAddr(outval6);
41d93087 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. */
b7ac5457 302 Ip::Address cnIPA = "ffff:ffff:fff0::";
41d93087 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 */
4dd643d5
AJ
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() );
9e167fa2 315 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, cnIPA.port() );
4dd643d5 316 cnIPA.getInAddr(outval6);
41d93087 317 CPPUNIT_ASSERT( memcmp( &expectv6, &outval6, sizeof(struct in6_addr)) == 0 );
41d93087 318}
319
320void
41e9c9f0 321TestIpAddress::testsetEmpty()
41d93087 322{
b7ac5457 323 Ip::Address anIPA;
41d93087 324 struct in_addr inval;
325
326 inval.s_addr = htonl(0xC0A8640C);
327
328 anIPA = inval;
329
330 /* test stored values before empty */
4dd643d5
AJ
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() );
9e167fa2 336 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
41d93087 337
4dd643d5 338 anIPA.setEmpty();
41d93087 339
340 /* test stored values after empty */
4dd643d5
AJ
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() );
9e167fa2 346 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
41d93087 347}
348
349void
41e9c9f0 350TestIpAddress::testBooleans()
41d93087 351{
b7ac5457
AJ
352 Ip::Address lhsIPA;
353 Ip::Address rhsIPA;
41d93087 354 struct in_addr valLow;
355 struct in_addr valHigh;
356
357 valLow.s_addr = htonl(0xC0A8640C);
358 valHigh.s_addr = htonl(0xC0A8640F);
359
26ac0430
AJ
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
6232d0a7 371 /* test equality versus ANYADDR */
4dd643d5
AJ
372 lhsIPA.setAnyAddr();
373 rhsIPA.setAnyAddr();
6232d0a7
AJ
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 */
4dd643d5
AJ
383 lhsIPA.setNoAddr();
384 rhsIPA.setNoAddr();
6232d0a7
AJ
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
26ac0430
AJ
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
6232d0a7 404 /* test inequality versus ANYADDR (less than) */
4dd643d5 405 lhsIPA.setAnyAddr();
6232d0a7
AJ
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;
4dd643d5 417 rhsIPA.setNoAddr();
6232d0a7
AJ
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
26ac0430
AJ
437 /* test inequality (greater than) */
438 lhsIPA = valHigh;
4dd643d5 439 rhsIPA.setAnyAddr();
6232d0a7
AJ
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) */
4dd643d5 449 lhsIPA.setNoAddr();
26ac0430
AJ
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 ) );
41d93087 458
459}
460
461void
41e9c9f0 462TestIpAddress::testtoStr()
41d93087 463{
464 struct in_addr inval;
465 char buf[MAX_IPSTRLEN];
b7ac5457 466 Ip::Address anIPA;
41d93087 467
4dd643d5 468 anIPA.setAnyAddr();
41d93087 469
470 /* test AnyAddr display values */
4dd643d5 471 CPPUNIT_ASSERT( memcmp("::", anIPA.toStr(buf,MAX_IPSTRLEN), 2) == 0 );
41d93087 472
473 inval.s_addr = htonl(0xC0A8640C);
474 anIPA = inval;
475
476 /* test IP display */
4dd643d5 477 CPPUNIT_ASSERT( memcmp("192.168.100.12",anIPA.toStr(buf,MAX_IPSTRLEN), 14) == 0 );
41d93087 478
4dd643d5 479 anIPA.setNoAddr();
41d93087 480
481 /* test NoAddr display values */
4dd643d5 482 CPPUNIT_ASSERT( memcmp("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",anIPA.toStr(buf,MAX_IPSTRLEN), 39) == 0 );
41d93087 483}
484
485void
41e9c9f0 486TestIpAddress::testtoUrl_fromInAddr()
41d93087 487{
26ac0430
AJ
488 char buf[MAX_IPSTRLEN];
489 buf[0] = '\0';
41d93087 490 struct in_addr inval;
491
492 inval.s_addr = htonl(0xC0A8640C);
493
b7ac5457 494 Ip::Address anIPA(inval);
41d93087 495
496 /* test values */
4dd643d5 497 anIPA.toUrl(buf,MAX_IPSTRLEN);
41d93087 498 CPPUNIT_ASSERT( memcmp("192.168.100.12", buf, 14) == 0 );
499
41d93087 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
b7ac5457 508 Ip::Address bnIPA(ip6val);
41d93087 509
4dd643d5 510 bnIPA.toUrl(buf,MAX_IPSTRLEN);
41d93087 511 CPPUNIT_ASSERT( memcmp("[c0a8:640c:ffff:ffff:ffff:ffff:ffff:ffff]", buf, 41) == 0 );
41d93087 512}
513
514void
41e9c9f0 515TestIpAddress::testtoUrl_fromSockAddr()
41d93087 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;
1ef0b9ce
AJ
521#if HAVE_SIN_LEN_IN_SAI
522 sock.sin_len = sizeof(struct sockaddr_in);
523#endif
524
b7ac5457 525 Ip::Address anIPA(sock);
41d93087 526 char buf[MAX_IPSTRLEN];
527
528 /* test values */
4dd643d5 529 anIPA.toUrl(buf,MAX_IPSTRLEN);
41d93087 530 CPPUNIT_ASSERT( memcmp("192.168.100.12:80", buf, 17) == 0 );
531
41d93087 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;
1ef0b9ce
AJ
541#if HAVE_SIN6_LEN_IN_SAI
542 ip6val.sin6_len = sizeof(struct sockaddr_in6);
543#endif
41d93087 544
b7ac5457 545 Ip::Address bnIPA(ip6val);
41d93087 546
4dd643d5 547 bnIPA.toUrl(buf,MAX_IPSTRLEN);
41d93087 548 CPPUNIT_ASSERT( memcmp("[c0a8:640c:ffff:ffff:ffff:ffff:ffff:ffff]:80", buf, 44) == 0 );
41d93087 549}
550
551void
41e9c9f0 552TestIpAddress::testgetReverseString()
41d93087 553{
554 char buf[MAX_IPSTRLEN];
555
556 struct in_addr ipv4val;
557 ipv4val.s_addr = htonl(0xC0A8640C);
558
b7ac5457 559 Ip::Address v4IPA(ipv4val);
41d93087 560
561 /* test IPv4 output */
4dd643d5 562 v4IPA.getReverseString(buf);
41d93087 563 CPPUNIT_ASSERT( memcmp("12.100.168.192.in-addr.arpa.",buf, 28) == 0 );
564
4dd643d5 565 v4IPA.getReverseString(buf,AF_INET);
41d93087 566 CPPUNIT_ASSERT( memcmp("12.100.168.192.in-addr.arpa.",buf, 28) == 0 );
567
4dd643d5 568 v4IPA.getReverseString(buf,AF_INET6);
41d93087 569 CPPUNIT_ASSERT( memcmp("",buf, 1) == 0 );
570
41d93087 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
b7ac5457 578 Ip::Address v6IPA(ip6val);
41d93087 579
580 /* test IPv6 output */
4dd643d5 581 v6IPA.getReverseString(buf);
41d93087 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 );
41d93087 583}
584
585void
41e9c9f0 586TestIpAddress::testMasking()
41d93087 587{
588 char buf[MAX_IPSTRLEN];
b7ac5457
AJ
589 Ip::Address anIPA;
590 Ip::Address maskIPA;
41d93087 591
592 /* Test Basic CIDR Routine */
4dd643d5 593 anIPA.setAnyAddr();
9e167fa2 594 CPPUNIT_ASSERT_EQUAL( 0,anIPA.cidr() );
41d93087 595
4dd643d5 596 anIPA.setNoAddr();
9e167fa2 597 CPPUNIT_ASSERT_EQUAL( 128, anIPA.cidr() );
41d93087 598
599 /* Test Numeric ApplyCIDR */
4dd643d5
AJ
600 anIPA.setNoAddr();
601 CPPUNIT_ASSERT( !anIPA.applyMask(129,AF_INET6) );
602 CPPUNIT_ASSERT( !anIPA.applyMask(33,AF_INET) );
41d93087 603
4dd643d5
AJ
604 anIPA.setNoAddr();
605 CPPUNIT_ASSERT( anIPA.applyMask(31,AF_INET) );
9e167fa2 606 CPPUNIT_ASSERT_EQUAL( 127, anIPA.cidr() );
055421ee 607
4dd643d5
AJ
608 anIPA.setNoAddr();
609 CPPUNIT_ASSERT( anIPA.applyMask(127,AF_INET6) );
9e167fa2 610 CPPUNIT_ASSERT_EQUAL( 127, anIPA.cidr() );
41d93087 611
4dd643d5
AJ
612 anIPA.setNoAddr();
613 anIPA.applyMask(80,AF_INET6);
9e167fa2 614 CPPUNIT_ASSERT_EQUAL( 80, anIPA.cidr() );
055421ee 615
41d93087 616 /* BUG Check: test values by display. */
aee3523a 617 CPPUNIT_ASSERT( anIPA.toStr(buf,MAX_IPSTRLEN) != nullptr );
41d93087 618 CPPUNIT_ASSERT( memcmp("ffff:ffff:ffff:ffff:ffff::", buf, 26) == 0 );
41d93087 619
b7ac5457 620 /* Test Network Bitmask from Ip::Address */
4dd643d5 621 anIPA.setNoAddr();
41d93087 622 maskIPA = "255.255.240.0";
9e167fa2 623 CPPUNIT_ASSERT_EQUAL( 20, maskIPA.cidr() );
4dd643d5 624 anIPA.applyMask(maskIPA);
9e167fa2 625 CPPUNIT_ASSERT_EQUAL( 20, anIPA.cidr() );
41d93087 626
627 /* BUG Check: test values memory after masking. */
628 struct in_addr btest;
4dd643d5
AJ
629 CPPUNIT_ASSERT( anIPA.isIPv4() );
630 CPPUNIT_ASSERT( !anIPA.isIPv6() );
631 anIPA.getInAddr(btest);
9e167fa2 632 CPPUNIT_ASSERT_EQUAL( (uint32_t)htonl(0xFFFFF000), btest.s_addr );
41d93087 633
634 /* BUG Check failing test. Masked values for display. */
4dd643d5 635 CPPUNIT_ASSERT( memcmp("255.255.240.0",anIPA.toStr(buf,MAX_IPSTRLEN), 13) == 0 );
41d93087 636
4dd643d5
AJ
637 anIPA.setNoAddr();
638 maskIPA.setNoAddr();
41d93087 639
26ac0430
AJ
640 /* IPv6 masks MUST be CIDR representations. */
641 /* however as with IPv4 they can technically be represented as a bitmask */
41d93087 642 maskIPA = "ffff:ffff:fff0::";
4dd643d5
AJ
643 CPPUNIT_ASSERT( !maskIPA.isAnyAddr() );
644 CPPUNIT_ASSERT( !maskIPA.isNoAddr() );
645 anIPA.applyMask(maskIPA);
646 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
9e167fa2 647 CPPUNIT_ASSERT_EQUAL( 44, anIPA.cidr() );
41d93087 648
4dd643d5
AJ
649 anIPA.setNoAddr();
650 maskIPA.setNoAddr();
41d93087 651
26ac0430 652 /* IPv4 masks represented in IPv6 as IPv4 bitmasks. */
41d93087 653 maskIPA = "::ffff:ffff:f000";
4dd643d5
AJ
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() );
9e167fa2 663 CPPUNIT_ASSERT_EQUAL( 20, anIPA.cidr() );
41d93087 664}
665
666void
41e9c9f0 667TestIpAddress::testAddrInfo()
41d93087 668{
669 struct addrinfo *expect;
aee3523a 670 struct addrinfo *ipval = nullptr;
41d93087 671 struct addrinfo hints;
672
673 memset(&hints, 0, sizeof(struct addrinfo));
674
675 hints.ai_flags = AI_NUMERICHOST;
676
b7ac5457 677 Ip::Address anIP = "127.0.0.1";
41d93087 678
679 /* assert this just to check that getaddrinfo is working properly */
aee3523a 680 CPPUNIT_ASSERT( getaddrinfo("127.0.0.1", nullptr, &hints, &expect ) == 0 );
41d93087 681
4dd643d5 682 anIP.getAddrInfo(ipval);
41d93087 683
41d93087 684 // check the addrinfo object core. (BUT not the two ptrs at the tail)
be8fdd56 685 // details
686 CPPUNIT_ASSERT_EQUAL( expect->ai_flags, ipval->ai_flags );
687 CPPUNIT_ASSERT_EQUAL( expect->ai_family, ipval->ai_family );
41d93087 688 // check the sockaddr it points to.
689 CPPUNIT_ASSERT_EQUAL( expect->ai_addrlen, ipval->ai_addrlen );
1ef0b9ce 690
1ef0b9ce 691#if HAVE_SS_LEN_IN_SS
12f45551
AJ
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 );
1ef0b9ce
AJ
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 );
12f45551 705#endif
7d553ad9
AJ
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 }
12f45551 723
be8fdd56 724 CPPUNIT_ASSERT( memcmp( expect->ai_addr, ipval->ai_addr, expect->ai_addrlen ) == 0 );
41d93087 725
27bc2077 726 freeaddrinfo(expect);
851614a8 727 Ip::Address::FreeAddr(ipval);
41d93087 728}
729
730void
41e9c9f0 731TestIpAddress::testBugNullingDisplay()
41d93087 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
b7ac5457 746 Ip::Address anIPA = "192.168.100.12";
41d93087 747
26ac0430 748 /* test stored values */
4dd643d5
AJ
749 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
750 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
751 CPPUNIT_ASSERT( anIPA.isIPv4() );
752 CPPUNIT_ASSERT( !anIPA.isIPv6() );
9e167fa2 753 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5
AJ
754 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
755 anIPA.getInAddr(outval);
41d93087 756 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
757
4dd643d5
AJ
758 /* POKE toStr display function to see what it is doing */
759 anIPA.toStr(ntoabuf,MAX_IPSTRLEN);
760 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
26ac0430 761 /* test stored values */
4dd643d5
AJ
762 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
763 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
764 CPPUNIT_ASSERT( anIPA.isIPv4() );
765 CPPUNIT_ASSERT( !anIPA.isIPv6() );
9e167fa2 766 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5
AJ
767 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
768 anIPA.getInAddr(outval);
41d93087 769 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
770
4dd643d5
AJ
771 /* POKE toHostStr display function to see what it is doing */
772 anIPA.toHostStr(hostbuf,MAX_IPSTRLEN);
773 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
26ac0430 774 /* test stored values */
4dd643d5
AJ
775 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
776 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
777 CPPUNIT_ASSERT( anIPA.isIPv4() );
778 CPPUNIT_ASSERT( !anIPA.isIPv6() );
9e167fa2 779 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5
AJ
780 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
781 anIPA.getInAddr(outval);
41d93087 782 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
783
4dd643d5
AJ
784 /* POKE toUrl display function to see what it is doing */
785 anIPA.toUrl(urlbuf,MAX_IPSTRLEN);
786 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
26ac0430 787 /* test stored values */
4dd643d5
AJ
788 CPPUNIT_ASSERT( !anIPA.isAnyAddr() );
789 CPPUNIT_ASSERT( !anIPA.isNoAddr() );
790 CPPUNIT_ASSERT( anIPA.isIPv4() );
791 CPPUNIT_ASSERT( !anIPA.isIPv6() );
9e167fa2 792 CPPUNIT_ASSERT_EQUAL( (unsigned short) 0, anIPA.port() );
4dd643d5
AJ
793 CPPUNIT_ASSERT( !anIPA.isSockAddr() );
794 anIPA.getInAddr(outval);
41d93087 795 CPPUNIT_ASSERT( memcmp( &expectval, &outval, sizeof(struct in_addr)) == 0 );
796
797}
f53969cc 798
53a5a6de
AR
799int
800main(int argc, char *argv[])
801{
802 return TestProgram().run(argc, argv);
803}
804