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