testIpAddress.cc
Go to the documentation of this file.
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 
30 class TestIpAddress : public CPPUNIT_NS::TestFixture
31 {
49 
52 
53 public:
54 protected:
55  void testDefaults();
56 
57  void testInAddrConstructor();
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();
73  void testgetReverseString();
74  void testMasking();
75 
76  // bugs.
77  void testBugNullingDisplay();
78 };
79 
81 
82 void
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 
96 void
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 
118 void
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 
142 void
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 
171 void
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 
203 void
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 
233 void
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 
257 void
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 
320 void
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 
349 void
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 
461 void
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 
485 void
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 
514 void
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 
551 void
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 
585 void
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 
666 void
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 
730 void
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 
799 int
800 main(int argc, char *argv[])
801 {
802  return TestProgram().run(argc, argv);
803 }
804 
void testSockAddrConstructor()
CPPUNIT_TEST_SUITE(TestIpAddress)
void testSockAddr6Constructor()
bool isAnyAddr() const
Definition: Address.cc:190
implements test program's main() function while enabling customization
Definition: unitTestMain.h:25
void testgetReverseString()
bool getInAddr(struct in_addr &) const
Definition: Address.cc:1040
static void FreeAddr(struct addrinfo *&ai)
Definition: Address.cc:706
CPPUNIT_TEST(testDefaults)
char * toUrl(char *buf, unsigned int len) const
Definition: Address.cc:894
bool isIPv4() const
Definition: Address.cc:178
int matchIPAddr(const Address &rhs) const
Definition: Address.cc:723
void testInAddrConstructor()
int socklen_t
Definition: types.h:137
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:812
int run(int argc, char *argv[])
Definition: unitTestMain.h:44
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
Definition: forward.h:25
unsigned int toHostStr(char *buf, const unsigned int len) const
Definition: Address.cc:862
void testBugNullingDisplay()
void setNoAddr()
Definition: Address.cc:312
struct hostent * xgethostbyname(const char *name)
POSIX gethostbyname(3) equivalent.
Definition: netdb.h:25
void testtoUrl_fromSockAddr()
unsigned short port() const
Definition: Address.cc:798
bool isIPv6() const
Definition: Address.cc:184
int cidr() const
Definition: Address.cc:54
void testCopyConstructor()
CPPUNIT_TEST_SUITE_REGISTRATION(TestIpAddress)
void setEmpty()
Fast reset of the stored content to what would be after default constructor.
Definition: Address.cc:204
bool isNoAddr() const
Definition: Address.cc:304
bool getReverseString(char buf[MAX_IPSTRLEN], int show_type=AF_UNSPEC) const
Definition: Address.cc:358
int applyMask(const Address &mask)
Definition: Address.cc:97
bool isSockAddr() const
Definition: Address.cc:172
int main(int argc, char *argv[])
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
Definition: Address.cc:619
void testInAddr6Constructor()
void testStringConstructor()
void setAnyAddr()
NOTE: Does NOT clear the Port stored. Only the Address and Type.
Definition: Address.cc:197
void testtoUrl_fromInAddr()
void testHostentConstructor()
void getSockAddr(struct sockaddr_storage &addr, const int family) const
Definition: Address.cc:944
void testDefaults()

 

Introduction

Documentation

Support

Miscellaneous