1 /*
2 ** Copyright (C) 2007-2020 by Carnegie Mellon University.
3 **
4 ** @OPENSOURCE_LICENSE_START@
5 ** See license information in ../../LICENSE.txt
6 ** @OPENSOURCE_LICENSE_END@
7 */
8
9 /*
10 ** Miscellaneous functions for dealing with IP addresses.
11 **
12 */
13
14
15 #include <silk/silk.h>
16
17 RCSIDENT("$SiLK: sku-ips.c ef14e54179be 2020-04-14 21:57:45Z mthomas $");
18
19 #include <silk/skipaddr.h>
20 #include <silk/utils.h>
21
22
23 /* TYPEDEFS AND MACROS */
24
25 #define SILK_IPV6_POLICY_ENVAR "SILK_IPV6_POLICY"
26
27
28 /* PUBLIC CONSTANTS USED IN MACROS */
29
30 const uint8_t sk_ipv6_zero[SK_IPV6_ZERO_LEN] =
31 {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
32 const uint8_t sk_ipv6_v4inv6[SK_IPV6_V4INV6_LEN] =
33 {0,0,0,0, 0,0,0,0, 0,0,0xFF,0xFF};
34
35 /* Constant returned by skSockaddrArrayGetHostname() when no
36 * host-name/-address was specified to skStringParseHostPortPair(). */
37 const char *sk_sockaddr_array_anyhostname = "*";
38
39
40 /* LOCAL VARIABLES */
41
42 #if SK_ENABLE_IPV6
43 static const uint8_t max_ip6[16] = {
44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
46 };
47 #endif
48
49 /* masks of various sizes used when computing CIDR blocks */
50 static const uint32_t bitmask[] = {
51 /* 0- 3 */ 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
52 /* 4- 7 */ 0xfffffff, 0x7ffffff, 0x3ffffff, 0x1ffffff,
53 /* 8-11 */ 0xffffff, 0x7fffff, 0x3fffff, 0x1fffff,
54 /* 12-15 */ 0xfffff, 0x7ffff, 0x3ffff, 0x1ffff,
55 /* 16-19 */ 0xffff, 0x7fff, 0x3fff, 0x1fff,
56 /* 20-23 */ 0xfff, 0x7ff, 0x3ff, 0x1ff,
57 /* 24-27 */ 0xff, 0x7f, 0x3f, 0x1f,
58 /* 28-31 */ 0xf, 0x7, 0x3, 0x1,
59 /* 32 */ 0x0
60 };
61
62
63 /* this is used to find the log-base-2 of the CIDR block difference.
64 * http://graphics.stanford.edu/~seander/bithacks.html */
65 static const uint8_t log_table_256[256] =
66 {
67 /* 0- 15 */ 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
68 /* 16- 31 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
69 /* 32- 47 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
70 /* 48- 63 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
71 /* 64- 79 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
72 /* 80- 95 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
73 /* 96-111 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
74 /* 112-127 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
75 /* 128-143 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
76 /* 144-159 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
77 /* 160-175 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
78 /* 176-191 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
79 /* 192-207 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
80 /* 208-223 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
81 /* 224-239 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
82 /* 240-255 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
83 };
84
85
86
87 /* FUNCTION DEFINITIONS */
88
89
90 /* compute the log2() of 'value' */
91 int
skIntegerLog2(uint64_t value)92 skIntegerLog2(
93 uint64_t value)
94 {
95 uint64_t tmp1;
96 uint64_t tmp2;
97
98 /* The comments use 63 for most significant bit and 0 for LSB */
99
100 if ((tmp1 = value >> 32)) { /* MSB is in bits 63-32 */
101 if ((tmp2 = tmp1 >> 16)) { /* MSB is in bits 63-48 */
102 if ((tmp1 = tmp2 >> 8)) { /* MSB is in bits 63-56 */
103 return 56 + log_table_256[tmp1];
104 } else { /* MSB is in bits 55-48 */
105 return 48 + log_table_256[tmp2];
106 }
107 } else { /* MSB is in bits 47-32 */
108 if ((tmp2 = tmp1 >> 8)) { /* MSB is in bits 47-40 */
109 return 40 + log_table_256[tmp2];
110 } else { /* MSB is in bits 39-32 */
111 return 32 + log_table_256[tmp1];
112 }
113 }
114 } else { /* MSB is in bits 31- 0 */
115 if ((tmp1 = value >> 16)) { /* MSB is in bits 31-16 */
116 if ((tmp2 = tmp1 >> 8)) { /* MSB is in bits 31-24 */
117 return 24 + log_table_256[tmp2];
118 } else { /* MSB is in bits 23-16 */
119 return 16 + log_table_256[tmp1];
120 }
121 } else { /* MSB is in bits 15- 0 */
122 if ((tmp1 = value >> 8)) { /* MSB is in bits 15- 8 */
123 return 8 + log_table_256[tmp1];
124 } else { /* MSB is in bits 7- 0 */
125 return log_table_256[value];
126 }
127 }
128 }
129 }
130
131
132 /* compute a CIDR block */
133 int
skComputeCIDR(uint32_t start_ip,uint32_t end_ip,uint32_t * new_start_ip)134 skComputeCIDR(
135 uint32_t start_ip,
136 uint32_t end_ip,
137 uint32_t *new_start_ip)
138 {
139 skipaddr_t start_addr;
140 skipaddr_t end_addr;
141 skipaddr_t new_start_addr;
142 int prefix;
143
144 skipaddrSetV4(&start_addr, &start_ip);
145 skipaddrSetV4(&end_addr, &end_ip);
146 if (new_start_ip) {
147 prefix = skCIDRComputePrefix(&start_addr, &end_addr, &new_start_addr);
148 if (-1 != prefix) {
149 *new_start_ip = skipaddrGetV4(&new_start_addr);
150 }
151 } else {
152 prefix = skCIDRComputePrefix(&start_addr, &end_addr, NULL);
153 }
154
155 return prefix;
156 }
157
158
159 /* compute the prefix to hold 'start_addr' through 'end_addr' */
160 int
skCIDRComputePrefix(const skipaddr_t * start_addr,const skipaddr_t * end_addr,skipaddr_t * new_start_addr)161 skCIDRComputePrefix(
162 const skipaddr_t *start_addr,
163 const skipaddr_t *end_addr,
164 skipaddr_t *new_start_addr)
165 {
166 int prefix = -1;
167
168 #if SK_ENABLE_IPV6
169 if (skipaddrIsV6(start_addr) || skipaddrIsV6(end_addr)) {
170 uint8_t start_ip6[16];
171 uint8_t end_ip6[16];
172 uint8_t range_start[16];
173 int i;
174 int tmp1;
175 uint8_t tmp2 = 0;
176
177 tmp1 = skipaddrCompare(start_addr, end_addr);
178 if (tmp1 > 0) {
179 /* bad range, start_addr > end_addr */
180 return -1;
181 }
182
183 /* handle a range that contains a single IP */
184 if (tmp1 == 0) {
185 if (new_start_addr) {
186 skipaddrClear(new_start_addr);
187 }
188 return 128;
189 }
190
191 skipaddrGetAsV6(start_addr, start_ip6);
192
193 /* handle an odd start_addr */
194 if (start_ip6[15] & 0x1) {
195 if (new_start_addr) {
196 skipaddrCopy(new_start_addr, start_addr);
197 skipaddrIncrement(new_start_addr);
198 }
199 return 128;
200 }
201
202 skipaddrGetAsV6(end_addr, end_ip6);
203 memset(range_start, 0, sizeof(range_start));
204
205 /* find the most significant bit where start_addr and end_addr
206 * differ */
207 for (i = 0; i < 16; ++i) {
208 if (start_ip6[i] != end_ip6[i]) {
209 /* copy first i+1 bytes of start_ip6 into range_start */
210 memcpy(range_start, start_ip6, i+1);
211
212 /* find number of IPs in the range */
213 tmp1 = end_ip6[i] - start_ip6[i];
214
215 /* see if we need to add one */
216 if ((i == 15)
217 || ((0 == memcmp(start_ip6 + i + 1, sk_ipv6_zero, (15-i)))
218 && (0 == memcmp(end_ip6 + i + 1, max_ip6, (15-i)))))
219 {
220 ++tmp1;
221 }
222 if (256 == tmp1) {
223 tmp2 = 8;
224 prefix = 8 * i;
225 } else {
226 tmp2 = log_table_256[tmp1];
227 prefix = 8 * (i + 1) - tmp2;
228 range_start[i] &= (0xFF << tmp2);
229 }
230 break;
231 }
232 }
233
234 while (memcmp(range_start, start_ip6, sizeof(range_start)) < 0) {
235 ++prefix;
236 if (tmp2 != 0) {
237 --tmp2;
238 } else {
239 ++i;
240 tmp2 = 7;
241 }
242 range_start[i] = start_ip6[i] & (0xFF << tmp2);
243 }
244
245 if (new_start_addr) {
246 /* compute the start of the next CIDR block, which is the
247 * IP after the block we just finished. In the case of
248 * roll-over, the 'else' clause will be invoked, and we
249 * will return 0. */
250 range_start[i] |= ~(0xFF << tmp2);
251 ++i;
252 memset(range_start + i, 0xFF, (sizeof(range_start) - i));
253 if (0 == memcmp(range_start, end_ip6, sizeof(range_start))) {
254 skipaddrClear(new_start_addr);
255 } else {
256 skipaddrSetV6(new_start_addr, range_start);
257 skipaddrIncrement(new_start_addr);
258 }
259 }
260
261 return prefix;
262
263 } else
264 #endif /* SK_ENABLE_IPV6 */
265 {
266 uint32_t start_ip4 = skipaddrGetV4(start_addr);
267 uint32_t end_ip4 = skipaddrGetV4(end_addr);
268 uint32_t range_start;
269
270 if (end_ip4 < start_ip4) {
271 return -1;
272 }
273
274 /* handle a range that contains a single IP */
275 if (end_ip4 == start_ip4) {
276 if (new_start_addr) {
277 skipaddrClear(new_start_addr);
278 }
279 return 32;
280 }
281 /* handle an odd start_addr */
282 if (start_ip4 & 0x1) {
283 if (new_start_addr) {
284 ++start_ip4;
285 skipaddrSetV4(new_start_addr, &start_ip4);
286 }
287 return 32;
288 }
289
290 /* compute the log-base-2 (position of most significant bit)
291 * of the number of IPs in the range, and subtract that from
292 * 32 to get the widest possible CIDR block */
293 prefix = 32 - skIntegerLog2(UINT64_C(1) + end_ip4 - start_ip4);
294
295 /* tighten the range if we need to, in case the IPs don't fall
296 * into a single CIDR block (e.g., 10.0.0.6--10.0.0.9) */
297 while ((range_start = (start_ip4 & ~(bitmask[prefix]))) < start_ip4) {
298 ++prefix;
299 }
300
301 /* assert that the CIDR block is within the limits */
302 assert(range_start == start_ip4);
303 assert((range_start | (bitmask[prefix])) <= end_ip4);
304
305 if (new_start_addr) {
306 /* compute the start of the next CIDR block, which is the
307 * IP after the block we just finished. In the case of
308 * roll-over, the 'else' clause will be invoked, and we
309 * will return 0. */
310 start_ip4 = 1 + (range_start | (bitmask[prefix]));
311 if (start_ip4 > end_ip4) {
312 skipaddrClear(new_start_addr);
313 } else {
314 skipaddrSetV4(new_start_addr, &start_ip4);
315 }
316 }
317 }
318
319 return prefix;
320 }
321
322
323 int
skCIDR2IPRange(const skipaddr_t * ipaddr,uint32_t cidr,skipaddr_t * min_ip,skipaddr_t * max_ip)324 skCIDR2IPRange(
325 const skipaddr_t *ipaddr,
326 uint32_t cidr,
327 skipaddr_t *min_ip,
328 skipaddr_t *max_ip)
329 {
330 uint32_t ip4;
331
332 #if SK_ENABLE_IPV6
333 if (skipaddrIsV6(ipaddr)) {
334 uint8_t ip6[16];
335 uint32_t i;
336
337 if (cidr >= 128) {
338 if (cidr > 128) {
339 return -1;
340 }
341 /* don't use skipaddrCopy() in case caller supplied
342 * pointers are the same */
343 skipaddrGetV6(ipaddr, ip6);
344 skipaddrSetV6(min_ip, ip6);
345 skipaddrSetV6(max_ip, ip6);
346 return 0;
347 }
348
349 skipaddrGetV6(ipaddr, ip6);
350
351 /* first byte of address where there is any effect */
352 i = cidr >> 3;
353
354 /* handle max: apply mask to this byte, remaining bits all 1 */
355 ip6[i] |= (0xFF >> (cidr & 0x07));
356 memset(&ip6[i+1], 0xFF, (15 - i));
357 skipaddrSetV6(max_ip, ip6);
358
359 /* handle min: apply mask, remaining bits all 0 */
360 ip6[i] &= ~(0xFF >> (cidr & 0x07));
361 memset(&ip6[i+1], 0, (15 - i));
362 skipaddrSetV6(min_ip, ip6);
363
364 return 0;
365 }
366 #endif /* SK_ENABLE_IPV6 */
367
368 if (cidr >= 32) {
369 if (cidr > 32) {
370 return -1;
371 }
372 ip4 = skipaddrGetV4(ipaddr);
373 skipaddrSetV4(min_ip, &ip4);
374 skipaddrSetV4(max_ip, &ip4);
375 return 0;
376 }
377
378 /* handle max IP */
379 ip4 = (UINT32_MAX >> cidr) | skipaddrGetV4(ipaddr);
380 skipaddrSetV4(max_ip, &ip4);
381
382 /* handle min IP */
383 ip4 &= ~(UINT32_MAX >> cidr);
384 skipaddrSetV4(min_ip, &ip4);
385
386 return 0;
387 }
388
389
390 int
skCIDRComputeStart(const skipaddr_t * ipaddr,uint32_t cidr,skipaddr_t * min_ip)391 skCIDRComputeStart(
392 const skipaddr_t *ipaddr,
393 uint32_t cidr,
394 skipaddr_t *min_ip)
395 {
396 uint32_t ip4;
397
398 #if SK_ENABLE_IPV6
399 if (skipaddrIsV6(ipaddr)) {
400 uint8_t ip6[16];
401 uint32_t i;
402
403 if (cidr >= 128) {
404 if (cidr > 128) {
405 return -1;
406 }
407 if (ipaddr != min_ip) {
408 skipaddrCopy(min_ip, ipaddr);
409 }
410 return 0;
411 }
412
413 skipaddrGetV6(ipaddr, ip6);
414
415 /* first byte of address where there is any effect */
416 i = cidr >> 3;
417
418 /* handle min: apply mask to this byte, remaining bits all 0 */
419 ip6[i] &= ~(0xFF >> (cidr & 0x07));
420 memset(&ip6[i+1], 0, (15 - i));
421 skipaddrSetV6(min_ip, ip6);
422
423 return 0;
424 }
425 #endif /* SK_ENABLE_IPV6 */
426
427 if (cidr >= 32) {
428 if (cidr > 32) {
429 return -1;
430 }
431 ip4 = skipaddrGetV4(ipaddr);
432 skipaddrSetV4(min_ip, &ip4);
433 return 0;
434 }
435
436 /* handle min IP */
437 ip4 = ~(UINT32_MAX >> cidr) & skipaddrGetV4(ipaddr);
438 skipaddrSetV4(min_ip, &ip4);
439
440 return 0;
441 }
442
443
444 int
skCIDRComputeEnd(const skipaddr_t * ipaddr,uint32_t cidr,skipaddr_t * max_ip)445 skCIDRComputeEnd(
446 const skipaddr_t *ipaddr,
447 uint32_t cidr,
448 skipaddr_t *max_ip)
449 {
450 uint32_t ip4;
451
452 #if SK_ENABLE_IPV6
453 if (skipaddrIsV6(ipaddr)) {
454 uint8_t ip6[16];
455 uint32_t i;
456
457 if (cidr >= 128) {
458 if (cidr > 128) {
459 return -1;
460 }
461 if (ipaddr != max_ip) {
462 skipaddrCopy(max_ip, ipaddr);
463 }
464 return 0;
465 }
466
467 skipaddrGetV6(ipaddr, ip6);
468
469 /* first byte of address where there is any effect */
470 i = cidr >> 3;
471
472 /* handle max: apply mask to this byte, remaining bits all 1 */
473 ip6[i] |= (0xFF >> (cidr & 0x07));
474 memset(&ip6[i+1], 0xFF, (15 - i));
475 skipaddrSetV6(max_ip, ip6);
476
477 return 0;
478 }
479 #endif /* SK_ENABLE_IPV6 */
480
481 if (cidr >= 32) {
482 if (cidr > 32) {
483 return -1;
484 }
485 ip4 = skipaddrGetV4(ipaddr);
486 skipaddrSetV4(max_ip, &ip4);
487 return 0;
488 }
489
490 /* handle max IP */
491 ip4 = (UINT32_MAX >> cidr) | skipaddrGetV4(ipaddr);
492 skipaddrSetV4(max_ip, &ip4);
493
494 return 0;
495 }
496
497
498 #if SK_ENABLE_IPV6
499 int
skipaddrV6toV4(const skipaddr_t * srcaddr,skipaddr_t * dstaddr)500 skipaddrV6toV4(
501 const skipaddr_t *srcaddr,
502 skipaddr_t *dstaddr)
503 {
504 uint32_t ipv4;
505
506 if (!SK_IPV6_IS_V4INV6(srcaddr->ip_ip.ipu_ipv6)) {
507 return -1;
508 }
509 memcpy(&ipv4, &(srcaddr->ip_ip.ipu_ipv6[12]), 4);
510 ipv4 = ntohl(ipv4);
511 skipaddrSetV4(dstaddr, &ipv4);
512 return 0;
513 }
514
515
516 int
skipaddrGetAsV4(const skipaddr_t * ipaddr,uint32_t * ipv4)517 skipaddrGetAsV4(
518 const skipaddr_t *ipaddr,
519 uint32_t *ipv4)
520 {
521 if (skipaddrIsV6(ipaddr)) {
522 if (!SK_IPV6_IS_V4INV6(ipaddr->ip_ip.ipu_ipv6)) {
523 return -1;
524 }
525 memcpy(ipv4, &(ipaddr->ip_ip.ipu_ipv6[12]), 4);
526 *ipv4 = ntohl(*ipv4);
527 } else {
528 *ipv4 = skipaddrGetV4(ipaddr);
529 }
530 return 0;
531 }
532 #endif /* SK_ENABLE_IPV6 */
533
534
535 static char *
ipaddrString(char * outbuf,const skipaddr_t * ipaddr,uint32_t ip_flags,int * is_ipv6)536 ipaddrString(
537 char *outbuf,
538 const skipaddr_t *ipaddr,
539 uint32_t ip_flags,
540 int *is_ipv6)
541 {
542 uint8_t ipv6[16];
543 uint32_t ipv4;
544
545 #if SK_ENABLE_IPV6
546 if (skipaddrIsV6(ipaddr)) {
547 if ((ip_flags & SKIPADDR_UNMAP_V6)
548 && (0 == skipaddrGetAsV4(ipaddr, &ipv4)))
549 {
550 *is_ipv6 = 0;
551 } else {
552 *is_ipv6 = 1;
553 skipaddrGetV6(ipaddr, ipv6);
554 }
555 } else
556 #endif /* SK_ENABLE_IPV6 */
557 {
558 if (ip_flags & SKIPADDR_MAP_V4) {
559 #ifdef skipaddrGetAsV6
560 skipaddrGetAsV6(ipaddr, ipv6);
561 #else
562 uint32_t tmp;
563 memcpy(ipv6, sk_ipv6_v4inv6, sizeof(sk_ipv6_v4inv6));
564 tmp = htonl(skipaddrGetV4(ipaddr));
565 memcpy(&ipv6[12], &tmp, sizeof(tmp));
566 #endif /* #else of #ifdef skipaddrGetAsV6 */
567 *is_ipv6 = 1;
568 } else {
569 *is_ipv6 = 0;
570 ipv4 = skipaddrGetV4(ipaddr);
571 }
572 }
573
574 ip_flags &= ~(uint32_t)(SKIPADDR_MAP_V4 | SKIPADDR_UNMAP_V6);
575
576 if (*is_ipv6) {
577 /* to represent a 128 bit number, divide the number into 4
578 * 64-bit values where each value represents 10 decimal digits
579 * of the number, with position 0 holding the least
580 * significant bits. */
581 static const uint64_t map_ipv6_to_dec[][3] = {
582 /* 1 << 64 */
583 { UINT64_C(3709551616), UINT64_C(1844674407), 0},
584 /* 1 << 96 */
585 { UINT64_C(3543950336), UINT64_C(1426433759), UINT64_C(792281625)}
586 };
587 /* our 10 decimal digits */
588 static const uint64_t lim = UINT64_C(10000000000);
589 /* the decimal value being calculated */
590 uint64_t decimal[4] = {0, 0, 0, 0};
591 /* when doing our own IPv6 printing, this holds each 16bit
592 * section of the address */
593 uint16_t hexdec[8];
594 /* following two values used when finding the longest run of
595 * 0s in an IPv6 address */
596 unsigned int longest_zero_pos;
597 unsigned int longest_zero_len;
598 uint64_t tmp;
599 char tmpbuf[SKIPADDR_STRLEN];
600 char *pos;
601 unsigned int len;
602 unsigned int i, j;
603 int zero_pad = 0;
604
605 if (0 == memcmp(ipv6, sk_ipv6_zero, sizeof(sk_ipv6_zero))) {
606 switch (ip_flags) {
607 case SKIPADDR_CANONICAL:
608 case SKIPADDR_NO_MIXED:
609 snprintf(outbuf, SKIPADDR_STRLEN, "::");
610 break;
611
612 case SKIPADDR_DECIMAL:
613 case SKIPADDR_HEXADECIMAL:
614 snprintf(outbuf, SKIPADDR_STRLEN, "0");
615 break;
616
617 case SKIPADDR_ZEROPAD | SKIPADDR_CANONICAL:
618 case SKIPADDR_ZEROPAD | SKIPADDR_NO_MIXED:
619 snprintf(outbuf, SKIPADDR_STRLEN,
620 "0000:0000:0000:0000:0000:0000:0000:0000");
621 break;
622
623 case SKIPADDR_ZEROPAD | SKIPADDR_DECIMAL:
624 snprintf(outbuf, SKIPADDR_STRLEN,
625 "000000000000000000000000000000000000000");
626 break;
627
628 case SKIPADDR_ZEROPAD | SKIPADDR_HEXADECIMAL:
629 snprintf(outbuf, SKIPADDR_STRLEN,
630 "00000000000000000000000000000000");
631 break;
632
633 default:
634 skAbortBadCase(ip_flags);
635 }
636 outbuf[SKIPADDR_STRLEN-1] = '\0';
637 return outbuf;
638 }
639
640 switch (ip_flags) {
641 case SKIPADDR_CANONICAL:
642 #ifdef SK_HAVE_INET_NTOP
643 # if SKIPADDR_STRLEN < INET6_ADDRSTRLEN
644 # error "SKIPADDR_STRLEN is not big enough"
645 # endif
646 if (NULL == inet_ntop(AF_INET6, &(ipv6), outbuf,
647 SKIPADDR_STRLEN))
648 {
649 outbuf[0] = '\0';
650 }
651 break;
652 #endif /* SK_HAVE_INET_NTOP */
653
654 case SKIPADDR_NO_MIXED:
655 /* do our own IPV6 printing with no IPv4 representation;
656 * follows Section 4 of RFC5952 */
657 /* compute each hexadectet */
658 hexdec[0] = (ipv6[ 0] << 8) | ipv6[ 1];
659 hexdec[1] = (ipv6[ 2] << 8) | ipv6[ 3];
660 hexdec[2] = (ipv6[ 4] << 8) | ipv6[ 5];
661 hexdec[3] = (ipv6[ 6] << 8) | ipv6[ 7];
662 hexdec[4] = (ipv6[ 8] << 8) | ipv6[ 9];
663 hexdec[5] = (ipv6[10] << 8) | ipv6[11];
664 hexdec[6] = (ipv6[12] << 8) | ipv6[13];
665 hexdec[7] = (ipv6[14] << 8) | ipv6[15];
666 /* find the starting position and length of the longest
667 * run of 0s */
668 longest_zero_pos = 8;
669 longest_zero_len = 0;
670 i = 0;
671 while (i < 8) {
672 if (hexdec[i]) {
673 ++i;
674 } else if (i == 7 || hexdec[i+1]) {
675 /* do not shorten a single 0 */
676 ++i;
677 } else {
678 /* we know i+1 is zero */
679 j = i;
680 for (i += 2; i < 8 && (0 == hexdec[i]); ++i){};/*empty*/
681 if ((i - j) > longest_zero_len) {
682 longest_zero_len = i - j;
683 longest_zero_pos = j;
684 }
685 }
686 }
687 /* print the ip; we build the result in pieces */
688 if (0 == longest_zero_len) {
689 snprintf(outbuf, SKIPADDR_STRLEN, "%x:%x:%x:%x:%x:%x:%x:%x",
690 hexdec[0], hexdec[1], hexdec[2], hexdec[3],
691 hexdec[4], hexdec[5], hexdec[6], hexdec[7]);
692 } else {
693 i = 0;
694 pos = outbuf;
695 len = SKIPADDR_STRLEN;
696 while (i < 8) {
697 if (i == longest_zero_pos) {
698 i += longest_zero_len;
699 if (8 == i) {
700 j = snprintf(pos, len, "::");
701 } else {
702 j = snprintf(pos, len, ":");
703 }
704 } else if (0 == i) {
705 j = snprintf(pos, len, "%x", hexdec[i]);
706 ++i;
707 } else {
708 j = snprintf(pos, len, ":%x", hexdec[i]);
709 ++i;
710 }
711 if (j >= len) {
712 skAbort();
713 }
714 pos += j;
715 len -= j;
716 }
717 }
718 break;
719
720 case SKIPADDR_ZEROPAD | SKIPADDR_CANONICAL:
721 case SKIPADDR_ZEROPAD | SKIPADDR_NO_MIXED:
722 /* Convert integer 0 to string
723 "0000:0000:0000:0000:0000:0000:0000:0000" */
724 snprintf(outbuf, SKIPADDR_STRLEN,
725 ("%02x%02x:%02x%02x:%02x%02x:%02x%02x"
726 ":%02x%02x:%02x%02x:%02x%02x:%02x%02x"),
727 ipv6[ 0], ipv6[ 1], ipv6[ 2], ipv6[ 3],
728 ipv6[ 4], ipv6[ 5], ipv6[ 6], ipv6[ 7],
729 ipv6[ 8], ipv6[ 9], ipv6[10], ipv6[11],
730 ipv6[12], ipv6[13], ipv6[14], ipv6[15]);
731 break;
732
733 case SKIPADDR_ZEROPAD | SKIPADDR_HEXADECIMAL:
734 zero_pad = 1;
735 /* FALLTHROUGH */
736 case SKIPADDR_HEXADECIMAL:
737 /* Fill buffer with a string representation of an integer
738 * in hexadecimal format; this works by printing the value
739 * then stripping leading 0's. */
740 snprintf(tmpbuf, sizeof(tmpbuf),
741 ("%02x%02x%02x%02x%02x%02x%02x%02x"
742 "%02x%02x%02x%02x%02x%02x%02x%02x"),
743 ipv6[ 0], ipv6[ 1], ipv6[ 2], ipv6[ 3],
744 ipv6[ 4], ipv6[ 5], ipv6[ 6], ipv6[ 7],
745 ipv6[ 8], ipv6[ 9], ipv6[10], ipv6[11],
746 ipv6[12], ipv6[13], ipv6[14], ipv6[15]);
747 i = ((zero_pad) ? 0 : strspn(tmpbuf, "0"));
748 /* checked for an IP of 0 above, so 'i' must be on some
749 * non-zero hex-digit */
750 assert('\0' != tmpbuf[i]);
751 strncpy(outbuf, &tmpbuf[i], SKIPADDR_STRLEN);
752 break;
753
754 case SKIPADDR_ZEROPAD | SKIPADDR_DECIMAL:
755 zero_pad = 1;
756 /* FALLTHROUGH */
757 case SKIPADDR_DECIMAL:
758 /* the lower 64 bits of the IPv6 address */
759 tmp = (( (uint64_t)ipv6[ 8] << UINT64_C(56))
760 | ((uint64_t)ipv6[ 9] << UINT64_C(48))
761 | ((uint64_t)ipv6[10] << UINT64_C(40))
762 | ((uint64_t)ipv6[11] << UINT64_C(32))
763 | ((uint64_t)ipv6[12] << UINT64_C(24))
764 | ((uint64_t)ipv6[13] << UINT64_C(16))
765 | ((uint64_t)ipv6[14] << UINT64_C( 8))
766 | ((uint64_t)ipv6[15]));
767 decimal[0] = tmp % lim;
768 decimal[1] = tmp / lim;
769 /* the middle-upper 32 bits, must be multipled by 1<<64 */
770 tmp = (( (uint64_t)ipv6[4] << UINT64_C(24))
771 | ((uint64_t)ipv6[5] << UINT64_C(16))
772 | ((uint64_t)ipv6[6] << UINT64_C( 8))
773 | ((uint64_t)ipv6[7]));
774 if (tmp) {
775 decimal[0] += tmp * map_ipv6_to_dec[0][0];
776 if (decimal[0] >= lim) {
777 decimal[1] += decimal[0] / lim;
778 decimal[0] %= lim;
779 }
780 decimal[1] += tmp * map_ipv6_to_dec[0][1];
781 if (decimal[1] >= lim) {
782 decimal[2] += decimal[1] / lim;
783 decimal[1] %= lim;
784 }
785 }
786 /* the upper 32 bits, must be multipled by 1<<96 */
787 tmp = (( (uint64_t)ipv6[0] << UINT64_C(24))
788 | ((uint64_t)ipv6[1] << UINT64_C(16))
789 | ((uint64_t)ipv6[2] << UINT64_C( 8))
790 | ((uint64_t)ipv6[3]));
791 if (tmp) {
792 decimal[0] += tmp * map_ipv6_to_dec[1][0];
793 if (decimal[0] >= lim) {
794 decimal[1] += decimal[0] / lim;
795 decimal[0] %= lim;
796 }
797 decimal[1] += tmp * map_ipv6_to_dec[1][1];
798 if (decimal[1] >= lim) {
799 decimal[2] += decimal[1] / lim;
800 decimal[1] %= lim;
801 }
802 decimal[2] += tmp * map_ipv6_to_dec[1][2];
803 if (decimal[2] >= lim) {
804 decimal[3] += decimal[2] / lim;
805 decimal[2] %= lim;
806 }
807 }
808 /* print the results */
809 if (zero_pad) {
810 snprintf(outbuf, SKIPADDR_STRLEN,
811 "%09" PRIu64 "%010" PRIu64 "%010" PRIu64
812 "%010" PRIu64,
813 decimal[3], decimal[2], decimal[1], decimal[0]);
814 } else if (decimal[3]) {
815 snprintf(outbuf, SKIPADDR_STRLEN,
816 "%" PRIu64 "%010" PRIu64 "%010" PRIu64 "%010" PRIu64,
817 decimal[3], decimal[2], decimal[1], decimal[0]);
818 } else if (decimal[2]) {
819 snprintf(outbuf, SKIPADDR_STRLEN,
820 "%" PRIu64 "%010" PRIu64 "%010" PRIu64,
821 decimal[2], decimal[1], decimal[0]);
822 } else if (decimal[1]) {
823 snprintf(outbuf, SKIPADDR_STRLEN,
824 "%" PRIu64 "%010" PRIu64,
825 decimal[1], decimal[0]);
826 } else {
827 snprintf(outbuf, SKIPADDR_STRLEN,
828 "%" PRIu64, decimal[0]);
829 }
830 break;
831
832 default:
833 skAbortBadCase(ip_flags);
834 }
835 } else {
836 /* address is IPv4 */
837 switch (ip_flags) {
838 case SKIPADDR_CANONICAL:
839 case SKIPADDR_NO_MIXED:
840 /* Convert integer 0 to string "0.0.0.0" */
841 snprintf(outbuf, SKIPADDR_STRLEN,
842 "%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32,
843 ((ipv4 >> 24) & 0xFF),
844 ((ipv4 >> 16) & 0xFF),
845 ((ipv4 >> 8) & 0xFF),
846 ((ipv4 ) & 0xFF));
847 break;
848
849 case SKIPADDR_DECIMAL:
850 snprintf(outbuf, SKIPADDR_STRLEN, ("%" PRIu32), ipv4);
851 break;
852
853 case SKIPADDR_HEXADECIMAL:
854 snprintf(outbuf, SKIPADDR_STRLEN, ("%" PRIx32), ipv4);
855 break;
856
857 case SKIPADDR_ZEROPAD | SKIPADDR_CANONICAL:
858 case SKIPADDR_ZEROPAD | SKIPADDR_NO_MIXED:
859 snprintf(outbuf, SKIPADDR_STRLEN,
860 "%03" PRIu32 ".%03" PRIu32 ".%03" PRIu32 ".%03" PRIu32,
861 ((ipv4 >> 24) & 0xFF),
862 ((ipv4 >> 16) & 0xFF),
863 ((ipv4 >> 8) & 0xFF),
864 ((ipv4 ) & 0xFF));
865 break;
866
867 case SKIPADDR_ZEROPAD | SKIPADDR_DECIMAL:
868 snprintf(outbuf, SKIPADDR_STRLEN, ("%010" PRIu32), ipv4);
869 break;
870
871 case SKIPADDR_ZEROPAD | SKIPADDR_HEXADECIMAL:
872 snprintf(outbuf, SKIPADDR_STRLEN, ("%08" PRIx32), ipv4);
873 break;
874
875 case SKIPADDR_FORCE_IPV6:
876 case SKIPADDR_MAP_V4:
877 case SKIPADDR_UNMAP_V6:
878 default:
879 skAbortBadCase(ip_flags);
880 }
881 }
882
883 outbuf[SKIPADDR_STRLEN-1] = '\0';
884 return outbuf;
885 }
886
887
888 static int
ipaddrStringMaxlen(unsigned int allow_ipv6,uint32_t ip_flags,int * is_ipv6)889 ipaddrStringMaxlen(
890 unsigned int allow_ipv6,
891 uint32_t ip_flags,
892 int *is_ipv6)
893 {
894 #if !SK_ENABLE_IPV6
895 allow_ipv6 = 0;
896 #endif
897 /* ignore the SKIPADDR_UNMAP_V6 flag since no way to know whether
898 * all IPv6 data falls in the ::ffff:0:0/96 netblock */
899
900 if (allow_ipv6 || (((SKIPADDR_ZEROPAD | SKIPADDR_MAP_V4) & ip_flags)
901 == (SKIPADDR_ZEROPAD | SKIPADDR_MAP_V4)))
902 {
903 /* data is IPv6 or data is IPv4 being mapped to IPv6 and
904 * zero-pad is enabled */
905 *is_ipv6 = 1;
906 switch (ip_flags & (SKIPADDR_ZEROPAD - 1)) {
907 case SKIPADDR_CANONICAL:
908 case SKIPADDR_NO_MIXED:
909 case SKIPADDR_DECIMAL:
910 return 39;
911 case SKIPADDR_HEXADECIMAL:
912 return 32;
913 default:
914 skAbortBadCase(ip_flags);
915 }
916 } else if (ip_flags & SKIPADDR_MAP_V4) {
917 /* IPv4 mapped to v6; max ip is ::ffff:255.255.255.255 */
918 *is_ipv6 = 1;
919 switch (ip_flags & (SKIPADDR_ZEROPAD - 1)) {
920 case SKIPADDR_CANONICAL:
921 return 22;
922 case SKIPADDR_NO_MIXED:
923 return 16;
924 case SKIPADDR_DECIMAL:
925 return 15;
926 case SKIPADDR_HEXADECIMAL:
927 return 12;
928 default:
929 skAbortBadCase(ip_flags);
930 }
931 } else {
932 /* IPv4 */
933 *is_ipv6 = 0;
934 switch (ip_flags & (SKIPADDR_ZEROPAD - 1)) {
935 case SKIPADDR_CANONICAL:
936 case SKIPADDR_NO_MIXED:
937 return 15;
938 case SKIPADDR_DECIMAL:
939 return 10;
940 case SKIPADDR_HEXADECIMAL:
941 return 8;
942 default:
943 skAbortBadCase(ip_flags);
944 }
945 }
946 }
947
948
949 char *
skipaddrString(char * outbuf,const skipaddr_t * ipaddr,uint32_t ip_flags)950 skipaddrString(
951 char *outbuf,
952 const skipaddr_t *ipaddr,
953 uint32_t ip_flags)
954 {
955 int is_ipv6;
956 return ipaddrString(outbuf, ipaddr, ip_flags, &is_ipv6);
957 }
958
959
960 char *
skipaddrCidrString(char * outbuf,const skipaddr_t * ipaddr,uint32_t prefix,uint32_t ip_flags)961 skipaddrCidrString(
962 char *outbuf,
963 const skipaddr_t *ipaddr,
964 uint32_t prefix,
965 uint32_t ip_flags)
966 {
967 int orig_ipv6;
968 int is_ipv6;
969 size_t sz;
970
971 #if SK_ENABLE_IPV6
972 if (skipaddrIsV6(ipaddr)) {
973 if (prefix > 128) {
974 return NULL;
975 }
976 if (prefix < 96 && (ip_flags & SKIPADDR_UNMAP_V6)) {
977 ip_flags &= ~SKIPADDR_UNMAP_V6;
978 }
979 orig_ipv6 = 1;
980 } else
981 #endif /* SK_ENABLE_IPV6 */
982 {
983 if (prefix > 32) {
984 return NULL;
985 }
986 orig_ipv6 = 0;
987 }
988
989 if (ipaddrString(outbuf, ipaddr, ip_flags, &is_ipv6) == NULL) {
990 return NULL;
991 }
992
993 if (is_ipv6 != orig_ipv6) {
994 if (is_ipv6) {
995 assert(!orig_ipv6);
996 assert(prefix <= 32);
997 prefix += 96;
998 } else {
999 assert(!is_ipv6);
1000 assert(orig_ipv6);
1001 assert(prefix >= 96);
1002 prefix -= 96;
1003 }
1004 }
1005
1006 sz = strlen(outbuf);
1007 if (ip_flags & SKIPADDR_ZEROPAD) {
1008 snprintf(outbuf + sz, 5, "/%0*u", (is_ipv6 ? 3 : 2), prefix);
1009 } else {
1010 snprintf(outbuf + sz, 5, "/%u", prefix);
1011 }
1012 return outbuf;
1013 }
1014
1015
1016 int
skipaddrStringMaxlen(unsigned int allow_ipv6,uint32_t ip_flags)1017 skipaddrStringMaxlen(
1018 unsigned int allow_ipv6,
1019 uint32_t ip_flags)
1020 {
1021 int is_ipv6;
1022 return ipaddrStringMaxlen(allow_ipv6, ip_flags, &is_ipv6);
1023 }
1024
1025
1026 int
skipaddrCidrStringMaxlen(unsigned int allow_ipv6,uint32_t ip_flags)1027 skipaddrCidrStringMaxlen(
1028 unsigned int allow_ipv6,
1029 uint32_t ip_flags)
1030 {
1031 int is_ipv6;
1032 int len = ipaddrStringMaxlen(allow_ipv6, ip_flags, &is_ipv6);
1033 return len + 3 + is_ipv6;
1034 }
1035
1036
1037 static struct policies_st {
1038 sk_ipv6policy_t policy;
1039 const char *name;
1040 const char *description;
1041 } policies[] = {
1042 {SK_IPV6POLICY_IGNORE, "ignore",
1043 "Completely ignore IPv6 flows"},
1044 {SK_IPV6POLICY_ASV4, "asv4",
1045 "Convert IPv6 flows to IPv4 if possible, else ignore"},
1046 {SK_IPV6POLICY_MIX, "mix",
1047 "Process a mixture of IPv4 and IPv6 flows"},
1048 {SK_IPV6POLICY_FORCE, "force",
1049 "Force IPv4 flows to be converted to IPv6"},
1050 {SK_IPV6POLICY_ONLY, "only",
1051 "Only process flows that were marked as IPv6"}
1052 };
1053
1054
1055 /* Parse an IPv6 policy. Return 0 if it is valid, -1 otherwise. */
1056 int
skIPv6PolicyParse(sk_ipv6policy_t * ipv6_policy,const char * policy_name,const char * option_name)1057 skIPv6PolicyParse(
1058 sk_ipv6policy_t *ipv6_policy,
1059 const char *policy_name,
1060 const char *option_name)
1061 {
1062 size_t len = strlen(policy_name);
1063 size_t i;
1064
1065 for (i = 0; i < sizeof(policies)/sizeof(struct policies_st); ++i) {
1066 if (len < strlen(policies[i].name)) {
1067 if (0 == strncmp(policies[i].name, policy_name, len)) {
1068 *ipv6_policy = policies[i].policy;
1069 return 0;
1070 }
1071 } else if (0 == strcmp(policies[i].name, policy_name)) {
1072 *ipv6_policy = policies[i].policy;
1073 return 0;
1074 }
1075 }
1076
1077 if (option_name) {
1078 skAppPrintErr("Invalid %s '%s'", option_name, policy_name);
1079 }
1080 return -1;
1081 }
1082
1083
1084 /* store the default policy from the application */
1085 static sk_ipv6policy_t ipv6_default;
1086
1087 /* support for the option */
1088 #define OPT_IPV6_POLICY 0
1089
1090 static struct option ipv6_policy_options[] = {
1091 {"ipv6-policy", REQUIRED_ARG, 0, OPT_IPV6_POLICY},
1092 {0,0,0,0} /* sentinel */
1093 };
1094
1095 /* handler for the option */
1096 static int
ipv6PolicyHandler(clientData cData,int opt_index,char * opt_arg)1097 ipv6PolicyHandler(
1098 clientData cData,
1099 int opt_index,
1100 char *opt_arg)
1101 {
1102 sk_ipv6policy_t *ipv6_policy = (sk_ipv6policy_t*)cData;
1103
1104 switch (opt_index) {
1105 case OPT_IPV6_POLICY:
1106 if (skIPv6PolicyParse(ipv6_policy, opt_arg,
1107 ipv6_policy_options[opt_index].name))
1108 {
1109 return 1;
1110 }
1111 break;
1112
1113 default:
1114 skAbortBadCase(opt_index);
1115 }
1116
1117 return 0;
1118 }
1119
1120
1121 int
skIPv6PolicyOptionsRegister(sk_ipv6policy_t * ipv6_policy)1122 skIPv6PolicyOptionsRegister(
1123 sk_ipv6policy_t *ipv6_policy)
1124 {
1125 sk_ipv6policy_t tmp_policy;
1126 char *env;
1127
1128 assert(ipv6_policy);
1129
1130 /* store the default policy wanted by the application */
1131 ipv6_default = *ipv6_policy;
1132
1133 /* get the default from the environment */
1134 env = getenv(SILK_IPV6_POLICY_ENVAR);
1135 if (env) {
1136 if (skIPv6PolicyParse(&tmp_policy, env, SILK_IPV6_POLICY_ENVAR) == 0) {
1137 *ipv6_policy = tmp_policy;
1138 }
1139 }
1140
1141 #if !SK_ENABLE_IPV6
1142 /* Force an IPv4-only SiLK to ignore any IPv6 flows */
1143 ipv6_default = SK_IPV6POLICY_IGNORE;
1144 *ipv6_policy = ipv6_default;
1145
1146 /* Register the option for compatibility with an IPv6-enabled
1147 * silk, but pass 'ipv6_default' as the clientData, so the user's
1148 * value does not modify the value the application uses. */
1149 return skOptionsRegister(ipv6_policy_options, &ipv6PolicyHandler,
1150 (clientData)&ipv6_default);
1151 #else
1152 /* add the option */
1153 return skOptionsRegister(ipv6_policy_options, &ipv6PolicyHandler,
1154 (clientData)ipv6_policy);
1155 #endif /* SK_ENABLE_IPV6 */
1156 }
1157
1158
1159 void
skIPv6PolicyUsage(FILE * fh)1160 skIPv6PolicyUsage(
1161 FILE *fh)
1162 {
1163 size_t i;
1164
1165 fprintf(fh, "--%s %s. ",
1166 ipv6_policy_options[OPT_IPV6_POLICY].name,
1167 SK_OPTION_HAS_ARG(ipv6_policy_options[OPT_IPV6_POLICY]));
1168 #if !SK_ENABLE_IPV6
1169 fprintf(fh, ("No IPv6 support available; IPv6 flows are always ignored\n"
1170 "\tregardless of the value passed to this switch."
1171 " Legal values:\n"));
1172 #else
1173 fprintf(fh, "Set policy for handling IPv4 and IPv6 flows.");
1174 for (i = 0; i < sizeof(policies)/sizeof(struct policies_st); ++i) {
1175 if (ipv6_default != policies[i].policy) {
1176 continue;
1177 }
1178 fprintf(fh, "\n\tDef. $" SILK_IPV6_POLICY_ENVAR " or %s. ",
1179 policies[i].name);
1180 break;
1181 }
1182 fprintf(fh, "Choices:\n");
1183 #endif
1184 for (i = 0; i < sizeof(policies)/sizeof(struct policies_st); ++i) {
1185 fprintf(fh, "\t%-6s - %s\n",
1186 policies[i].name, policies[i].description);
1187 }
1188 }
1189
1190
1191 #if SK_ENABLE_IPV6
1192 int
skipaddrCompare(const skipaddr_t * addr1,const skipaddr_t * addr2)1193 skipaddrCompare(
1194 const skipaddr_t *addr1,
1195 const skipaddr_t *addr2)
1196 {
1197 skipaddr_t tmp;
1198
1199 if (addr1->ip_is_v6) {
1200 if (addr2->ip_is_v6) {
1201 return memcmp(addr1->ip_ip.ipu_ipv6, addr2->ip_ip.ipu_ipv6, 16);
1202 }
1203 skipaddrV4toV6(addr2, &tmp);
1204 return memcmp(addr1->ip_ip.ipu_ipv6, tmp.ip_ip.ipu_ipv6, 16);
1205 }
1206 if (addr2->ip_is_v6) {
1207 skipaddrV4toV6(addr1, &tmp);
1208 return memcmp(tmp.ip_ip.ipu_ipv6, addr2->ip_ip.ipu_ipv6, 16);
1209 }
1210 /* both addresses are IPv4 */
1211 if (addr1->ip_ip.ipu_ipv4 < addr2->ip_ip.ipu_ipv4) {
1212 return -1;
1213 }
1214 if (addr1->ip_ip.ipu_ipv4 > addr2->ip_ip.ipu_ipv4) {
1215 return 1;
1216 }
1217 return 0;
1218 }
1219
1220
1221 /* apply the bit-mask in 'mask_ip' to 'ipaddr' */
1222 void
skipaddrMask(skipaddr_t * ipaddr,const skipaddr_t * mask_ip)1223 skipaddrMask(
1224 skipaddr_t *ipaddr,
1225 const skipaddr_t *mask_ip)
1226 {
1227 skipaddr_t tmp;
1228 uint32_t mask_v4;
1229
1230 if (ipaddr->ip_is_v6) {
1231 if (mask_ip->ip_is_v6) {
1232 /* both addresses are IPv6 */
1233 skIPUnionApplyMaskV6(&ipaddr->ip_ip, mask_ip->ip_ip.ipu_ipv6);
1234 return;
1235 }
1236 /* convert mask to IPv6. This result will be strange */
1237 skipaddrV4toV6(mask_ip, &tmp);
1238 skIPUnionApplyMaskV6(&ipaddr->ip_ip, tmp.ip_ip.ipu_ipv6);
1239 return;
1240 }
1241 if (skipaddrGetAsV4(mask_ip, &mask_v4) == -1) {
1242 /* 'ipaddr' is IPv4 and 'mask_ip' is IPv6. convert 'ipaddr' to
1243 * v6; the result is going to be strange */
1244 skipaddrV4toV6(ipaddr, ipaddr);
1245 skIPUnionApplyMaskV6(&ipaddr->ip_ip, mask_ip->ip_ip.ipu_ipv6);
1246 return;
1247 }
1248 /* both addresses are IPv4 */
1249 skIPUnionApplyMaskV4(&ipaddr->ip_ip, mask_v4);
1250 }
1251
1252 #endif /* SK_ENABLE_IPV6 */
1253
1254
1255 /* ************* IP WILDCARDS ******************* */
1256
1257
1258 void
skIPWildcardClear(skIPWildcard_t * ipwild)1259 skIPWildcardClear(
1260 skIPWildcard_t *ipwild)
1261 {
1262 assert(ipwild);
1263 memset(ipwild, 0, sizeof(skIPWildcard_t));
1264 memset(ipwild->m_min, 0xFF, sizeof(ipwild->m_min));
1265 }
1266
1267
1268
1269 #if SK_ENABLE_IPV6
1270 int
skIPWildcardCheckIp(const skIPWildcard_t * ipwild,const skipaddr_t * ipaddr)1271 skIPWildcardCheckIp(
1272 const skIPWildcard_t *ipwild,
1273 const skipaddr_t *ipaddr)
1274 {
1275 uint32_t ip4;
1276
1277 assert(ipwild);
1278 assert(ipaddr);
1279
1280 if (skIPWildcardIsV6(ipwild)) {
1281 uint8_t ip6[16];
1282 skipaddrGetAsV6(ipaddr, ip6);
1283 return (_IPWILD_BLOCK_IS_SET(ipwild, 0, ((ip6[ 0] << 8) | ip6[ 1])) &&
1284 _IPWILD_BLOCK_IS_SET(ipwild, 1, ((ip6[ 2] << 8) | ip6[ 3])) &&
1285 _IPWILD_BLOCK_IS_SET(ipwild, 2, ((ip6[ 4] << 8) | ip6[ 5])) &&
1286 _IPWILD_BLOCK_IS_SET(ipwild, 3, ((ip6[ 6] << 8) | ip6[ 7])) &&
1287 _IPWILD_BLOCK_IS_SET(ipwild, 4, ((ip6[ 8] << 8) | ip6[ 9])) &&
1288 _IPWILD_BLOCK_IS_SET(ipwild, 5, ((ip6[10] << 8) | ip6[11])) &&
1289 _IPWILD_BLOCK_IS_SET(ipwild, 6, ((ip6[12] << 8) | ip6[13])) &&
1290 _IPWILD_BLOCK_IS_SET(ipwild, 7, ((ip6[14] << 8) | ip6[15])));
1291 }
1292
1293 if (skipaddrGetAsV4(ipaddr, &ip4)) {
1294 return 0;
1295 }
1296
1297 return (_IPWILD_BLOCK_IS_SET((ipwild), 0, 0xFF & (ip4 >> 24)) &&
1298 _IPWILD_BLOCK_IS_SET((ipwild), 1, 0xFF & (ip4 >> 16)) &&
1299 _IPWILD_BLOCK_IS_SET((ipwild), 2, 0xFF & (ip4 >> 8)) &&
1300 _IPWILD_BLOCK_IS_SET((ipwild), 3, 0xFF & (ip4)));
1301 }
1302
1303
1304 /* Bind iterator to an ipwildcard, forcing IPv6 addresses */
1305 int
skIPWildcardIteratorBindV6(skIPWildcardIterator_t * out_iter,const skIPWildcard_t * ipwild)1306 skIPWildcardIteratorBindV6(
1307 skIPWildcardIterator_t *out_iter,
1308 const skIPWildcard_t *ipwild)
1309 {
1310 if (skIPWildcardIteratorBind(out_iter, ipwild)) {
1311 return -1;
1312 }
1313 out_iter->force_ipv6 = 1;
1314 out_iter->force_ipv4 = 0;
1315 return 0;
1316 }
1317
1318
1319 /* Bind iterator to an ipwildcard, forcing IPv4 addresses */
1320 int
skIPWildcardIteratorBindV4(skIPWildcardIterator_t * out_iter,const skIPWildcard_t * ipwild)1321 skIPWildcardIteratorBindV4(
1322 skIPWildcardIterator_t *out_iter,
1323 const skIPWildcard_t *ipwild)
1324 {
1325 assert(out_iter);
1326 if (NULL == ipwild) {
1327 return -1;
1328 }
1329
1330 out_iter->ipwild = ipwild;
1331 out_iter->force_ipv6 = 0;
1332 /* only set force_ipv4 when wildcard is IPv6 */
1333 out_iter->force_ipv4 = skIPWildcardIsV6(ipwild);
1334 skIPWildcardIteratorReset(out_iter);
1335
1336 return 0;
1337 }
1338 #endif /* SK_ENABLE_IPV6 */
1339
1340
1341 /* Bind iterator to an ipwildcard */
1342 int
skIPWildcardIteratorBind(skIPWildcardIterator_t * out_iter,const skIPWildcard_t * ipwild)1343 skIPWildcardIteratorBind(
1344 skIPWildcardIterator_t *out_iter,
1345 const skIPWildcard_t *ipwild)
1346 {
1347 assert(out_iter);
1348 if (ipwild == NULL) {
1349 return -1;
1350 }
1351
1352 out_iter->ipwild = ipwild;
1353 out_iter->force_ipv6 = 0;
1354 out_iter->force_ipv4 = 0;
1355 skIPWildcardIteratorReset(out_iter);
1356
1357 return 0;
1358 }
1359
1360
1361 /* helper function for skIPWildcardIteratorNext() and
1362 * skIPWildcardIteratorNextCidr() */
1363 static skIteratorStatus_t
ipwildcardIterNext(skIPWildcardIterator_t * iter,skipaddr_t * ipaddr,uint32_t * prefix,int want_cidr)1364 ipwildcardIterNext(
1365 skIPWildcardIterator_t *iter,
1366 skipaddr_t *ipaddr,
1367 uint32_t *prefix,
1368 int want_cidr)
1369 {
1370 uint32_t cidr_adjust;
1371 uint32_t tmp;
1372 unsigned int check_ints;
1373 unsigned int idx;
1374 unsigned int i;
1375 unsigned int j;
1376
1377 assert(iter);
1378 assert(ipaddr);
1379 assert(prefix);
1380
1381 /* check the stopping condition */
1382 if (iter->no_more_entries) {
1383 return SK_ITERATOR_NO_MORE_ENTRIES;
1384 }
1385
1386 /* the iterator is already set to the single IP to return or to
1387 * the first IP of the CIDR block to return; get that first IP,
1388 * and set prefix assuming a single IP */
1389 #if SK_ENABLE_IPV6
1390 if (skIPWildcardIsV6(iter->ipwild)) {
1391 if (iter->force_ipv4) {
1392 uint32_t ip4 = (iter->i_block[6] << 16) | iter->i_block[7];
1393 skipaddrSetV4(ipaddr, &ip4);
1394 *prefix = 32;
1395 } else {
1396 uint8_t ip6[16];
1397
1398 ip6[ 0] = (uint8_t)(iter->i_block[0] >> 8);
1399 ip6[ 1] = (uint8_t)(iter->i_block[0] & 0xFF);
1400 ip6[ 2] = (uint8_t)(iter->i_block[1] >> 8);
1401 ip6[ 3] = (uint8_t)(iter->i_block[1] & 0xFF);
1402 ip6[ 4] = (uint8_t)(iter->i_block[2] >> 8);
1403 ip6[ 5] = (uint8_t)(iter->i_block[2] & 0xFF);
1404 ip6[ 6] = (uint8_t)(iter->i_block[3] >> 8);
1405 ip6[ 7] = (uint8_t)(iter->i_block[3] & 0xFF);
1406 ip6[ 8] = (uint8_t)(iter->i_block[4] >> 8);
1407 ip6[ 9] = (uint8_t)(iter->i_block[4] & 0xFF);
1408 ip6[10] = (uint8_t)(iter->i_block[5] >> 8);
1409 ip6[11] = (uint8_t)(iter->i_block[5] & 0xFF);
1410 ip6[12] = (uint8_t)(iter->i_block[6] >> 8);
1411 ip6[13] = (uint8_t)(iter->i_block[6] & 0xFF);
1412 ip6[14] = (uint8_t)(iter->i_block[7] >> 8);
1413 ip6[15] = (uint8_t)(iter->i_block[7] & 0xFF);
1414 skipaddrSetV6(ipaddr, ip6);
1415 *prefix = 128;
1416 }
1417 } else if (iter->force_ipv6) {
1418 uint32_t ip4 = ((iter->i_block[0] << 24) |
1419 (iter->i_block[1] << 16) |
1420 (iter->i_block[2] << 8) |
1421 (iter->i_block[3]));
1422 skipaddrSetV6FromUint32(ipaddr, &ip4);
1423 *prefix = 128;
1424 } else
1425 #endif
1426 {
1427 uint32_t ip4 = ((iter->i_block[0] << 24) |
1428 (iter->i_block[1] << 16) |
1429 (iter->i_block[2] << 8) |
1430 (iter->i_block[3]));
1431 skipaddrSetV4(ipaddr, &ip4);
1432 *prefix = 32;
1433 }
1434
1435 /* skip the for() loop if not looking for a CIDR block */
1436 if (!want_cidr) {
1437 goto NEXT_IP;
1438 }
1439
1440 /* determine the end of this CIDR block by counting the number of
1441 * consecutive high bits in the bitmap */
1442 i = iter->ipwild->num_blocks;
1443 while (i > 0) {
1444 --i;
1445 assert(i < (SK_ENABLE_IPV6 ? 8 : 4));
1446 /* 'idx' is array position of the uint32_t we are currently
1447 * looking at in the bitmap for this octet/hexadectet */
1448 idx = _BMAP_INDEX(iter->i_block[i]);
1449 assert(idx < (SK_ENABLE_IPV6 ? (65536/32) : (256/32)));
1450 /* this is the CIDR block adjustment to make due to this
1451 * octet/hexadectet only */
1452 cidr_adjust = 0;
1453 /* switch based on the number of additional bits we can
1454 * consider in the current uint32_t */
1455 switch (iter->i_block[i] & 0x1F) {
1456 case 0:
1457 /* can consider all */
1458 if (iter->ipwild->m_blocks[i][idx] == 0xFFFFFFFF) {
1459 /* all bits in this uint32_t are high. Check for a
1460 * longer run of high bits by checking the value in
1461 * adjacent uint32_t's. 'check_ints' is the number of
1462 * values to check. this calculation is based on the
1463 * number of trailing 0's in the number of available
1464 * uint32_t's. */
1465 tmp = ((iter->i_block[i] >> 5)
1466 | (1 << (2 * iter->ipwild->num_blocks - 5)));
1467 if (tmp & 0x1) {
1468 check_ints = 0;
1469 } else {
1470 check_ints = (1 << 1);
1471 if ((tmp & 0xff) == 0) {
1472 tmp >>= 8;
1473 check_ints <<= 8;
1474 }
1475 if ((tmp & 0xf) == 0) {
1476 tmp >>= 4;
1477 check_ints <<= 4;
1478 }
1479 if ((tmp & 0x3) == 0) {
1480 tmp >>= 2;
1481 check_ints <<= 2;
1482 }
1483 check_ints >>= (tmp & 0x1);
1484 }
1485 /* move to next uint32_t; start counting from 1 since
1486 * we already checked one uint32_t. */
1487 ++idx;
1488 for (j = 1; j < check_ints; ++j, ++idx) {
1489 assert(idx < (SK_ENABLE_IPV6 ? (65536/32) : (256/32)));
1490 if (iter->ipwild->m_blocks[i][idx] != 0xFFFFFFFF) {
1491 break;
1492 }
1493 }
1494 /* cidr_adjust is at least 5 plus an amount determined
1495 * by the most significant bit in 'j' */
1496 cidr_adjust = 5 + skIntegerLog2(j);
1497 break;
1498 }
1499 /* FALLTHROUGH */
1500
1501 case 16:
1502 /* we can consider at least 16 bits in this uint32_t */
1503 if (((iter->ipwild->m_blocks[i][idx]
1504 >> (iter->i_block[i] & 0x1F)) & 0xFFFF) == 0xFFFF)
1505 {
1506 cidr_adjust = 4;
1507 break;
1508 }
1509 /* FALLTHROUGH */
1510
1511 case 8: case 24:
1512 /* we can consider at least 8 bits in this uint32_t */
1513 if (((iter->ipwild->m_blocks[i][idx]
1514 >> (iter->i_block[i] & 0x1F)) & 0xFF) == 0xFF)
1515 {
1516 cidr_adjust = 3;
1517 break;
1518 }
1519 /* FALLTHROUGH */
1520
1521 case 4: case 12: case 20: case 28:
1522 if (((iter->ipwild->m_blocks[i][idx]
1523 >> (iter->i_block[i] & 0x1F)) & 0xF) == 0xF)
1524 {
1525 cidr_adjust = 2;
1526 break;
1527 }
1528 /* FALLTHROUGH */
1529
1530 case 2: case 6: case 10: case 14:
1531 case 18: case 22: case 26: case 30:
1532 if (((iter->ipwild->m_blocks[i][idx]
1533 >> (iter->i_block[i] & 0x1F)) & 0x3) == 0x3)
1534 {
1535 cidr_adjust = 1;
1536 break;
1537 }
1538 /* FALLTHROUGH */
1539
1540 default:
1541 break;
1542 }
1543
1544 /* adjust the prefix value based on this octet/hexadectet */
1545 *prefix -= cidr_adjust;
1546 iter->i_block[i] += (1 << cidr_adjust) - 1;
1547 assert(iter->i_block[i] <= iter->ipwild->m_max[i]);
1548
1549 /* do the consecutive bits run into the next
1550 * octet/hexadectet? */
1551 if (cidr_adjust < 2u * iter->ipwild->num_blocks) {
1552 /* no. we've found the largest block */
1553 break;
1554 }
1555 }
1556
1557 NEXT_IP:
1558 /* found the CIDR block to return this time. move the iterator to
1559 * the start of the next IP or CIDR block for the next query */
1560 i = iter->ipwild->num_blocks;
1561 while (i > 0) {
1562 --i;
1563 /* is the i'th octet/hexadectet at its maximum? */
1564 if (iter->i_block[i] >= iter->ipwild->m_max[i]) {
1565 /* yes; reset the counter for this octet/hexadectet and
1566 * try the next most significant octet/hexadectet */
1567 iter->i_block[i] = iter->ipwild->m_min[i];
1568
1569 if (iter->force_ipv4 && i <= 6) {
1570 break;
1571 }
1572 continue;
1573 }
1574 /* else it is not at the max, and we can increment this
1575 * octet/hexadectet. find the next high bit */
1576
1577 /* assert that our stopping condition is valid */
1578 assert(_IPWILD_BLOCK_IS_SET(iter->ipwild, i, iter->ipwild->m_max[i]));
1579 ++iter->i_block[i];
1580 if (_IPWILD_BLOCK_IS_SET(iter->ipwild, i, iter->i_block[i])) {
1581 /* found it */
1582 return SK_ITERATOR_OK;
1583 }
1584
1585 /* jump over multiple 0 bits. get current uint32_t */
1586 tmp = iter->ipwild->m_blocks[i][_BMAP_INDEX(iter->i_block[i])];
1587 if (iter->i_block[i] & 0x1F) {
1588 /* this uint32_t contains the CIDR block that is being
1589 * returned; need to shift off bits we have already
1590 * handled */
1591 tmp >>= (iter->i_block[i] & 0x1F);
1592 if (0 == tmp) {
1593 /* no more high bits in this uint32_t */
1594 iter->i_block[i] += 32 - (iter->i_block[i] & 0x1F);
1595 tmp = iter->ipwild->m_blocks[i][_BMAP_INDEX(iter->i_block[i])];
1596 }
1597 }
1598 while (0 == tmp) {
1599 /* skip over uint32_t's that are 0 */
1600 iter->i_block[i] += 32;
1601 tmp = iter->ipwild->m_blocks[i][_BMAP_INDEX(iter->i_block[i])];
1602 }
1603
1604 /* this uint32_t contains a high bit */
1605 if (0 == (tmp & 0x1)) {
1606 ++iter->i_block[i];
1607 if ((tmp & 0xFFFF) == 0) {
1608 tmp >>= 16;
1609 iter->i_block[i] += 16;
1610 }
1611 if ((tmp & 0xFF) == 0) {
1612 tmp >>= 8;
1613 iter->i_block[i] += 8;
1614 }
1615 if ((tmp & 0xF) == 0) {
1616 tmp >>= 4;
1617 iter->i_block[i] += 4;
1618 }
1619 if ((tmp & 0x3) == 0) {
1620 tmp >>= 2;
1621 iter->i_block[i] += 2;
1622 }
1623 iter->i_block[i] -= (tmp & 0x1);
1624 }
1625 assert(_IPWILD_BLOCK_IS_SET(iter->ipwild,i,iter->i_block[i]));
1626 return SK_ITERATOR_OK;
1627 }
1628
1629 /* we're done. make the next call to Next() fail */
1630 iter->no_more_entries = 1;
1631
1632 return SK_ITERATOR_OK;
1633 }
1634
1635
1636 /* Get next entry in tree */
1637 skIteratorStatus_t
skIPWildcardIteratorNext(skIPWildcardIterator_t * iter,skipaddr_t * ipaddr)1638 skIPWildcardIteratorNext(
1639 skIPWildcardIterator_t *iter,
1640 skipaddr_t *ipaddr)
1641 {
1642 uint32_t prefix;
1643
1644 return ipwildcardIterNext(iter, ipaddr, &prefix, 0);
1645 }
1646
1647
1648 /* get the next CIDR block in the wildcard */
1649 skIteratorStatus_t
skIPWildcardIteratorNextCidr(skIPWildcardIterator_t * iter,skipaddr_t * ipaddr,uint32_t * prefix)1650 skIPWildcardIteratorNextCidr(
1651 skIPWildcardIterator_t *iter,
1652 skipaddr_t *ipaddr,
1653 uint32_t *prefix)
1654 {
1655 return ipwildcardIterNext(iter, ipaddr, prefix, 1);
1656 }
1657
1658
1659 /* Reset iterator */
1660 void
skIPWildcardIteratorReset(skIPWildcardIterator_t * iter)1661 skIPWildcardIteratorReset(
1662 skIPWildcardIterator_t *iter)
1663 {
1664 int i;
1665
1666 assert(iter);
1667
1668 #if SK_ENABLE_IPV6
1669 if (iter->force_ipv4) {
1670 /* must ensure that wildcard contains 0:0:0:0:0:ffff:x:x */
1671 assert(skIPWildcardIsV6(iter->ipwild));
1672 for (i = 0; i < 5; ++i) {
1673 if (!_IPWILD_BLOCK_IS_SET(iter->ipwild, i, 0)) {
1674 iter->no_more_entries = 1;
1675 return;
1676 }
1677 assert(0 == iter->ipwild->m_min[i]);
1678 iter->i_block[i] = iter->ipwild->m_min[i];
1679 }
1680 if (!_IPWILD_BLOCK_IS_SET(iter->ipwild, 5, 0xFFFF)) {
1681 iter->no_more_entries = 1;
1682 return;
1683 }
1684 assert(UINT16_MAX == iter->ipwild->m_max[5]);
1685 iter->i_block[5] = iter->ipwild->m_max[5];
1686
1687 iter->i_block[6] = iter->ipwild->m_min[6];
1688 iter->i_block[7] = iter->ipwild->m_min[7];
1689
1690 iter->no_more_entries = 0;
1691 return;
1692 }
1693 #endif /* SK_ENABLE_IPV6 */
1694
1695 iter->no_more_entries = 0;
1696 for (i = 0; i < iter->ipwild->num_blocks; ++i) {
1697 iter->i_block[i] = iter->ipwild->m_min[i];
1698 }
1699 }
1700
1701
1702 /* ******************************************************************** */
1703 /* skcidr_t */
1704 /* ******************************************************************** */
1705
1706
1707 #if SK_ENABLE_IPV6
1708 /* check whether 'ipaddr' is in 'cidr' */
1709 int
skcidrCheckIP(const skcidr_t * cidr,const skipaddr_t * ipaddr)1710 skcidrCheckIP(
1711 const skcidr_t *cidr,
1712 const skipaddr_t *ipaddr)
1713 {
1714 uint8_t ipv6[16];
1715 uint32_t ipv4;
1716
1717 if (skcidrIsV6(cidr)) {
1718 skipaddrGetAsV6(ipaddr, ipv6);
1719
1720 return (0 == memcmp(cidr->v6.ip, ipv6, cidr->v6.byte_length)
1721 && ((0 == cidr->v6.mask)
1722 || ((cidr->v6.mask & ipv6[cidr->v6.byte_length])
1723 == cidr->v6.ip[cidr->v6.byte_length])));
1724 }
1725 if (0 == skipaddrGetAsV4(ipaddr, &ipv4)) {
1726 return ((ipv4 & cidr->v4.mask) == cidr->v4.ip);
1727 }
1728 return 0;
1729 }
1730 #endif /* SK_ENABLE_IPV6 */
1731
1732 /* Fill 'ipaddr' with the IP address in 'cidr' */
1733 void
skcidrGetIPAddr(const skcidr_t * cidr,skipaddr_t * ipaddr)1734 skcidrGetIPAddr(
1735 const skcidr_t *cidr,
1736 skipaddr_t *ipaddr)
1737 {
1738 #if SK_ENABLE_IPV6
1739 if (skcidrIsV6(cidr)) {
1740 skipaddrSetV6(ipaddr, cidr->v6.ip);
1741 return;
1742 }
1743 #endif
1744 skipaddrSetV4(ipaddr, &(cidr->v4.ip));
1745 }
1746
1747
1748 /* Fill 'cidr' using the 'ipaddr' and 'cidr_len' */
1749 int
skcidrSetFromIPAddr(skcidr_t * cidr,const skipaddr_t * ipaddr,uint32_t cidr_len)1750 skcidrSetFromIPAddr(
1751 skcidr_t *cidr,
1752 const skipaddr_t *ipaddr,
1753 uint32_t cidr_len)
1754 {
1755 #if SK_ENABLE_IPV6
1756 if (skipaddrIsV6(ipaddr)) {
1757 uint8_t tmp_ip[16];
1758 skipaddrGetV6(ipaddr, tmp_ip);
1759 return skcidrSetV6(cidr, tmp_ip, cidr_len);
1760 }
1761 #endif
1762 return skcidrSetV4(cidr, skipaddrGetV4(ipaddr), cidr_len);
1763 }
1764
1765
1766 /* Fill 'cidr' using the 'ipv4' and 'cidr_len' */
1767 int
skcidrSetV4(skcidr_t * cidr,uint32_t ipv4,uint32_t cidr_len)1768 skcidrSetV4(
1769 skcidr_t *cidr,
1770 uint32_t ipv4,
1771 uint32_t cidr_len)
1772 {
1773 if (cidr_len > 32) {
1774 return -1;
1775 }
1776
1777 skcidrClear(cidr);
1778 cidr->v4.cidr_length = cidr_len;
1779 cidr->v4.mask = ((cidr_len == 32)
1780 ? UINT32_MAX
1781 : ~(UINT32_MAX >> cidr_len));
1782 cidr->v4.ip = ipv4 & cidr->v4.mask;
1783 return 0;
1784 }
1785
1786
1787 #if SK_ENABLE_IPV6
1788 /* Fill 'cidr' using the 'ipv6' and 'cidr_len' */
1789 int
skcidrSetV6(skcidr_t * cidr,const uint8_t * ipv6,uint32_t cidr_len)1790 skcidrSetV6(
1791 skcidr_t *cidr,
1792 const uint8_t *ipv6,
1793 uint32_t cidr_len)
1794 {
1795 if (cidr_len > 128) {
1796 return -1;
1797 }
1798
1799 skcidrClear(cidr);
1800 cidr->v6.is_ipv6 = 1;
1801 cidr->v6.cidr_length = cidr_len;
1802 cidr->v6.byte_length = cidr_len >> 3;
1803 cidr->v6.mask = 0xFF & ~(0xFF >> (cidr_len & 0x7));
1804 memcpy(cidr->v6.ip, ipv6, cidr->v6.byte_length);
1805 if (cidr->v6.mask) {
1806 cidr->v6.ip[cidr->v6.byte_length]
1807 = ipv6[cidr->v6.byte_length] & cidr->v6.mask;
1808 }
1809 return 0;
1810 }
1811 #endif /* SK_ENABLE_IPV6 */
1812
1813
1814 /* ******************************************************************** */
1815 /* sockaddr */
1816 /* ******************************************************************** */
1817
1818
1819 /* Fill 'dest' of length 'len' with the address in 'src' */
1820 int
skipaddrToSockaddr(struct sockaddr * dest,size_t len,const skipaddr_t * src)1821 skipaddrToSockaddr(
1822 struct sockaddr *dest,
1823 size_t len,
1824 const skipaddr_t *src)
1825 {
1826 assert(src);
1827 assert(dest);
1828
1829 #if SK_ENABLE_IPV6
1830 if (skipaddrIsV6(src)) {
1831 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)dest;
1832 if (len < sizeof(*v6)) {
1833 return -1;
1834 }
1835 memset(v6, 0, sizeof(*v6));
1836 v6->sin6_family = AF_INET6;
1837 skipaddrGetV6(src, v6->sin6_addr.s6_addr);
1838 } else
1839 #endif /* SK_ENABLE_IPV6 */
1840 {
1841 struct sockaddr_in *v4 = (struct sockaddr_in *)dest;
1842 if (len < sizeof(*v4)) {
1843 return -1;
1844 }
1845 memset(v4, 0, sizeof(*v4));
1846 v4->sin_family = AF_INET;
1847 v4->sin_addr.s_addr = htonl(skipaddrGetV4(src));
1848 }
1849
1850 return 0;
1851 }
1852
1853 /* Fill 'dest' with address in 'src' */
1854 int
skipaddrFromSockaddr(skipaddr_t * dest,const struct sockaddr * src)1855 skipaddrFromSockaddr(
1856 skipaddr_t *dest,
1857 const struct sockaddr *src)
1858 {
1859 assert(dest);
1860 assert(src);
1861
1862 switch (src->sa_family) {
1863 case AF_INET:
1864 {
1865 in_addr_t addr;
1866 const struct sockaddr_in *v4 = (const struct sockaddr_in *)src;
1867 addr = ntohl(v4->sin_addr.s_addr);
1868 skipaddrSetV4(dest, &addr);
1869 }
1870 break;
1871 #if SK_ENABLE_IPV6
1872 case AF_INET6:
1873 {
1874 const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)src;
1875 skipaddrSetV6(dest, v6->sin6_addr.s6_addr);
1876 }
1877 break;
1878 #endif
1879 default:
1880 return -1;
1881 }
1882
1883 return 0;
1884 }
1885
1886
1887 int
skSockaddrCompare(const sk_sockaddr_t * a,const sk_sockaddr_t * b,unsigned int flags)1888 skSockaddrCompare(
1889 const sk_sockaddr_t *a,
1890 const sk_sockaddr_t *b,
1891 unsigned int flags)
1892 {
1893 uint16_t pa, pb;
1894 sk_sockaddr_t temp;
1895
1896 if (a == b) {
1897 return 0;
1898 }
1899 if (a == NULL) {
1900 return -1;
1901 }
1902 if (b == NULL) {
1903 return 1;
1904 }
1905 if (!(flags & SK_SOCKADDRCOMP_NOPORT)) {
1906 switch (a->sa.sa_family) {
1907 case AF_INET:
1908 pa = a->v4.sin_port;
1909 break;
1910 case AF_INET6:
1911 pa = a->v6.sin6_port;
1912 break;
1913 case AF_UNIX:
1914 pa = 0;
1915 break;
1916 default:
1917 skAbortBadCase(a->sa.sa_family);
1918 }
1919 switch (b->sa.sa_family) {
1920 case AF_INET:
1921 pb = b->v4.sin_port;
1922 break;
1923 case AF_INET6:
1924 pb = b->v6.sin6_port;
1925 break;
1926 case AF_UNIX:
1927 pb = 0;
1928 break;
1929 default:
1930 skAbortBadCase(b->sa.sa_family);
1931 }
1932 if (pa < pb) {
1933 return -1;
1934 }
1935 if (pa > pb) {
1936 return 1;
1937 }
1938 }
1939 if (!(flags & SK_SOCKADDRCOMP_NOT_V4_AS_V6)) {
1940 /* If necessary, convert V4 addresses to V6. */
1941 if (a->sa.sa_family == AF_INET6 && b->sa.sa_family == AF_INET) {
1942 temp.sa.sa_family = AF_INET6;
1943 memcpy(temp.v6.sin6_addr.s6_addr,
1944 sk_ipv6_v4inv6, SK_IPV6_V4INV6_LEN);
1945 memcpy(temp.v6.sin6_addr.s6_addr + SK_IPV6_V4INV6_LEN,
1946 &b->v4.sin_addr.s_addr, 4);
1947 b = &temp;
1948 } else if (a->sa.sa_family == AF_INET && b->sa.sa_family == AF_INET6) {
1949 temp.sa.sa_family = AF_INET6;
1950 memcpy(temp.v6.sin6_addr.s6_addr,
1951 sk_ipv6_v4inv6, SK_IPV6_V4INV6_LEN);
1952 memcpy(temp.v6.sin6_addr.s6_addr + SK_IPV6_V4INV6_LEN,
1953 &a->v4.sin_addr.s_addr, 4);
1954 a = &temp;
1955 }
1956 }
1957 if (a->sa.sa_family < b->sa.sa_family) {
1958 return -1;
1959 }
1960 if (a->sa.sa_family > b->sa.sa_family) {
1961 return 1;
1962 }
1963 if (flags & SK_SOCKADDRCOMP_NOADDR) {
1964 return 0;
1965 }
1966 switch (a->sa.sa_family) {
1967 case AF_INET:
1968 return memcmp(&a->v4.sin_addr.s_addr, &b->v4.sin_addr.s_addr,
1969 sizeof(a->v4.sin_addr.s_addr));
1970 case AF_INET6:
1971 return memcmp(a->v6.sin6_addr.s6_addr, b->v6.sin6_addr.s6_addr,
1972 sizeof(a->v6.sin6_addr.s6_addr));
1973 case AF_UNIX:
1974 return strncmp(a->un.sun_path, b->un.sun_path,
1975 sizeof(a->un.sun_path));
1976 default:
1977 skAbortBadCase(a->sa.sa_family);
1978 }
1979 }
1980
1981 ssize_t
skSockaddrString(char * buffer,size_t size,const sk_sockaddr_t * addr)1982 skSockaddrString(
1983 char *buffer,
1984 size_t size,
1985 const sk_sockaddr_t *addr)
1986 {
1987 /* Must be large enough to hold UNIX domain socket path. */
1988 char sabuf[PATH_MAX];
1989 skipaddr_t ipaddr;
1990 uint16_t port;
1991 ssize_t rv;
1992
1993 switch (addr->sa.sa_family) {
1994 case AF_INET6:
1995 if (0 == memcmp(addr->v6.sin6_addr.s6_addr, in6addr_any.s6_addr,
1996 sizeof(addr->v6.sin6_addr.s6_addr)))
1997 {
1998 sabuf[0] = '*';
1999 sabuf[1] = '\0';
2000 } else {
2001 #if SK_ENABLE_IPV6
2002 skipaddrFromSockaddr(&ipaddr, &addr->sa);
2003 skipaddrString(sabuf, &ipaddr, SKIPADDR_CANONICAL);
2004 #elif defined(SK_HAVE_INET_NTOP)
2005 if (NULL == inet_ntop(AF_INET6, &addr->v6.sin6_addr,
2006 sabuf, sizeof(sabuf)))
2007 {
2008 strcpy(sabuf, "<unknown-ipv6>");
2009 }
2010 #else /* !SK_ENABLE_IPV6 && !defined(SK_HAVE_INET_NTOP) */
2011 strcpy(sabuf, "<unknown-ipv6>");
2012 #endif /* SK_ENABLE_IPV6 */
2013 }
2014 port = ntohs(addr->v6.sin6_port);
2015 if (port) {
2016 rv = snprintf(buffer, size, ("[%s]:%" PRIu16), sabuf, port);
2017 } else {
2018 rv = snprintf(buffer, size, "%s", sabuf);
2019 }
2020 break;
2021 case AF_INET:
2022 if (addr->v4.sin_addr.s_addr == INADDR_ANY) {
2023 sabuf[0] = '*';
2024 sabuf[1] = '\0';
2025 } else {
2026 skipaddrFromSockaddr(&ipaddr, &addr->sa);
2027 skipaddrString(sabuf, &ipaddr, SKIPADDR_CANONICAL);
2028 }
2029 port = ntohs(addr->v4.sin_port);
2030 if (port) {
2031 rv = snprintf(buffer, size, ("%s:%" PRIu16), sabuf, port);
2032 } else {
2033 rv = snprintf(buffer, size, "%s", sabuf);
2034 }
2035 break;
2036 case AF_UNIX:
2037 rv = snprintf(buffer, size, "%s", addr->un.sun_path);
2038 break;
2039 default:
2040 skAbortBadCase(addr->sa.sa_family);
2041 }
2042
2043 return rv;
2044 }
2045
2046 int
skSockaddrArrayContains(const sk_sockaddr_array_t * array,const sk_sockaddr_t * addr,unsigned int flags)2047 skSockaddrArrayContains(
2048 const sk_sockaddr_array_t *array,
2049 const sk_sockaddr_t *addr,
2050 unsigned int flags)
2051 {
2052 uint32_t i;
2053
2054 if (array == NULL || addr == NULL) {
2055 return 0;
2056 }
2057 for (i = 0; i < skSockaddrArrayGetSize(array); i++) {
2058 if (skSockaddrCompare(skSockaddrArrayGet(array, i),
2059 addr, flags) == 0)
2060 {
2061 return 1;
2062 }
2063 }
2064
2065 return 0;
2066 }
2067
2068 int
skSockaddrArrayEqual(const sk_sockaddr_array_t * a,const sk_sockaddr_array_t * b,unsigned int flags)2069 skSockaddrArrayEqual(
2070 const sk_sockaddr_array_t *a,
2071 const sk_sockaddr_array_t *b,
2072 unsigned int flags)
2073 {
2074 uint32_t i;
2075
2076 if (a == NULL) {
2077 return b == NULL;
2078 }
2079 if (b == NULL) {
2080 return 0;
2081 }
2082 if (skSockaddrArrayGetSize(a) != skSockaddrArrayGetSize(b)) {
2083 return 0;
2084 }
2085 for (i = 0; i < skSockaddrArrayGetSize(a); i++) {
2086 if (!skSockaddrArrayContains(b, skSockaddrArrayGet(a, i), flags)) {
2087 return 0;
2088 }
2089 }
2090 return 1;
2091 }
2092
2093 int
skSockaddrArrayMatches(const sk_sockaddr_array_t * a,const sk_sockaddr_array_t * b,unsigned int flags)2094 skSockaddrArrayMatches(
2095 const sk_sockaddr_array_t *a,
2096 const sk_sockaddr_array_t *b,
2097 unsigned int flags)
2098 {
2099 uint32_t i, j;
2100
2101 if (a == NULL) {
2102 return b == NULL;
2103 }
2104 if (b == NULL) {
2105 return 0;
2106 }
2107 for (i = 0; i < skSockaddrArrayGetSize(a); ++i) {
2108 for (j = 0; j < skSockaddrArrayGetSize(b); ++j) {
2109 if (skSockaddrCompare(skSockaddrArrayGet(a, i),
2110 skSockaddrArrayGet(b, j),
2111 flags) == 0)
2112 {
2113 return 1;
2114 }
2115 }
2116 }
2117 return 0;
2118 }
2119
2120
2121 /* Deprecated */
2122 size_t
skSockaddrLen(const sk_sockaddr_t * s)2123 skSockaddrLen(
2124 const sk_sockaddr_t *s)
2125 {
2126 return skSockaddrGetLen(s);
2127 }
2128
2129 /* Deprecated */
2130 int
skSockaddrPort(const sk_sockaddr_t * s)2131 skSockaddrPort(
2132 const sk_sockaddr_t *s)
2133 {
2134 return skSockaddrGetPort(s);
2135 }
2136
2137 /* Deprecated */
2138 const char *
skSockaddrArrayNameSafe(const sk_sockaddr_array_t * s)2139 skSockaddrArrayNameSafe(
2140 const sk_sockaddr_array_t *s)
2141 {
2142 return skSockaddrArrayGetHostname(s);
2143 }
2144
2145 /* Deprecated */
2146 const char *
skSockaddrArrayName(const sk_sockaddr_array_t * s)2147 skSockaddrArrayName(
2148 const sk_sockaddr_array_t *s)
2149 {
2150 return s->name;
2151 }
2152
2153 /* Deprecated */
2154 uint32_t
skSockaddrArraySize(const sk_sockaddr_array_t * s)2155 skSockaddrArraySize(
2156 const sk_sockaddr_array_t *s)
2157 {
2158 return skSockaddrArrayGetSize(s);
2159 }
2160
2161
2162 /*
2163 ** Local Variables:
2164 ** mode:c
2165 ** indent-tabs-mode:nil
2166 ** c-basic-offset:4
2167 ** End:
2168 */
2169