1 /*
2 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 ** Copyright (C) 1998-2013 Sourcefire, Inc.
4 ** Adam Keeton
5 ** Kevin Liu <kliu@sourcefire.com>
6 *
7 ** $ID: $
8 **
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License Version 2 as
11 ** published by the Free Software Foundation. You may not use, modify or
12 ** distribute this program under any other version of the GNU General
13 ** Public License.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 /*
26 * Adam Keeton
27 * sf_ip.h
28 * 11/17/06
29 */
30
31 #ifndef SF_IP_H
32 #define SF_IP_H
33
34 #ifndef WIN32
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #endif
40
41 #ifdef WIN32
42 #include <ws2tcpip.h>
43 #endif
44
45 #include "snort_debug.h" /* for inline definition */
46
47 /* define SFIP_ROBUST to check pointers passed into the sfip libs.
48 * Robustification should not be enabled if the client code is trustworthy.
49 * Namely, if pointers are checked once in the client, or are pointers to
50 * data allocated on the stack, there's no need to check them again here.
51 * The intention is to prevent the same stack-allocated variable from being
52 * checked a dozen different times. */
53 #define SFIP_ROBUST
54
55 #ifdef SFIP_ROBUST
56
57 #define ARG_CHECK1(a, z) if(!a) return z;
58 #define ARG_CHECK2(a, b, z) if(!a || !b) return z;
59 #define ARG_CHECK3(a, b, c, z) if(!a || !b || !c) return z;
60
61 #elif defined(DEBUG)
62
63 #define ARG_CHECK1(a, z) assert(a);
64 #define ARG_CHECK2(a, b, z) assert(a); assert(b);
65 #define ARG_CHECK3(a, b, c, z) assert(a); assert(b); assert(c);
66
67 #else
68
69 #define ARG_CHECK1(a, z)
70 #define ARG_CHECK2(a, b, z)
71 #define ARG_CHECK3(a, b, c, z)
72
73 #endif
74
75 #ifndef WIN32
76 #if !defined(s6_addr8)
77 #define s6_addr8 __u6_addr.__u6_addr8
78 #endif
79 #if !defined(s6_addr16)
80 #define s6_addr16 __u6_addr.__u6_addr16
81 #endif
82 #if !defined(s6_addr32)
83 #define s6_addr32 __u6_addr.__u6_addr32
84 #endif
85
86 #ifdef _WIN32
87 #pragma pack(push,1)
88 #endif
89
90 struct _sfaddr
91 {
92 struct in6_addr ip;
93 uint16_t family;
94 # define ia8 ip.s6_addr
95 # define ia16 ip.s6_addr16
96 # define ia32 ip.s6_addr32
97 #ifdef _WIN32
98 };
99 #pragma pack(pop)
100 #else
101 } __attribute__((__packed__));
102 #endif
103 typedef struct _sfaddr sfaddr_t;
104
105 #ifdef _WIN32
106 #pragma pack(push,1)
107 #endif
108
109 struct _ip {
110 sfaddr_t addr;
111 uint16_t bits;
112 # define ip8 addr.ip.s6_addr
113 # define ip16 addr.ip.s6_addr16
114 # define ip32 addr.ip.s6_addr32
115 # define ip_family addr.family
116 #ifdef _WIN32
117 };
118 #pragma pack(pop)
119 #else
120 } __attribute__((__packed__));
121 #endif
122
123 typedef struct _ip sfcidr_t;
124 #else // WIN32 Build
125 #if !defined(s6_addr8)
126 #define s6_addr8 u.u6_addr8
127 #endif
128 #if !defined(s6_addr16)
129 #define s6_addr16 u.u6_addr16
130 #endif
131 #if !defined(s6_addr32)
132 #define s6_addr32 u.u6_addr32
133 #endif
134
135 struct sf_in6_addr {
136 union {
137 uint8_t u6_addr8[16];
138 uint16_t u6_addr16[8];
139 uint32_t u6_addr32[4];
140 } in6_u;
141 };
142
143 #pragma pack(push,1)
144 struct _sfaddr {
145 struct in6_addr ip;
146 uint16_t family;
147 # define ia8 ip.s6_addr
148 # define ia16 ip.s6_addr16
149 # define ia32 ip.s6_addr32
150 };
151 typedef struct _sfaddr sfaddr_t;
152
153 struct _ip {
154 sfaddr_t addr;
155 uint16_t bits;
156 # define ip8 addr.ip.s6_addr
157 # define ip16 addr.ip.s6_addr16
158 # define ip32 addr.ip.s6_addr32
159 # define ip_family addr.family
160 };
161 typedef struct _ip sfcidr_t;
162 #pragma pack(pop)
163
164 #endif // WIN32
165
166 typedef enum _return_values {
167 SFIP_SUCCESS=0,
168 SFIP_FAILURE,
169 SFIP_LESSER,
170 SFIP_GREATER,
171 SFIP_EQUAL,
172 SFIP_ARG_ERR,
173 SFIP_CIDR_ERR,
174 SFIP_INET_PARSE_ERR,
175 SFIP_INVALID_MASK,
176 SFIP_ALLOC_ERR,
177 SFIP_CONTAINS,
178 SFIP_NOT_CONTAINS,
179 SFIP_DUPLICATE, /* Tried to add a duplicate variable name to table */
180 SFIP_LOOKUP_FAILURE, /* Failed to lookup a variable from the table */
181 SFIP_UNMATCHED_BRACKET, /* IP lists that are missing a closing bracket */
182 SFIP_NOT_ANY, /* For !any */
183 SFIP_CONFLICT, /* For IP conflicts in IP lists */
184 SFIP_INVALID_VAR /* variable definition is invalid */
185 } SFIP_RET;
186
187
188 /* IP allocations and setting ******************************************/
189
190 /* Parses "src" and stores results in "dst" */
191 /* If the conversion is invalid, returns SFIP_FAILURE */
192 SFIP_RET sfaddr_pton(const char *src, sfaddr_t *dst);
193 SFIP_RET sfip_pton(const char *src, sfcidr_t *dst);
194
195 /* Allocate IP address from a character array describing the IP */
196 sfcidr_t *sfip_alloc(const char *ip, SFIP_RET *status);
197
198 /* Frees an sfcidr_t */
199 void sfip_free(sfcidr_t *ip);
200
201 /* Allocate IP address from a character array describing the IP */
202 sfaddr_t *sfaddr_alloc(const char *ip, SFIP_RET *status);
203
204 /* Frees an sfaddr_t */
205 void sfaddr_free(sfaddr_t *ip);
206
207 /* Allocate IP address from an array of integers. The array better be
208 * long enough for the given family! */
209 sfaddr_t *sfip_alloc_raw(void *ip, int family, SFIP_RET *status);
210
211 /* Sets existing IP, "dst", to a raw source IP (4 or 16 bytes,
212 * according to family) */
213 SFIP_RET sfip_set_raw(sfaddr_t *dst, const void *src, int src_family);
214
215 /* Sets existing IP, "dst", to be source IP, "src" */
216 #define sfip_set_ip(dst, src) *(dst) = *(src)
217
218 /* Obfuscates an IP */
219 void sfip_obfuscate(sfcidr_t *ob, sfaddr_t *ip);
220
221 /* Member-access *******************************************************/
222
223 #define sfip_get_ip4_value(x) ((x)->ip32[3])
224 #define sfaddr_get_ip4_value(x) ((x)->ia32[3])
225
226 #define sfip_get_ip4_ptr(x) (&(x)->ip32[3])
227 #define sfip_get_ip6_ptr(x) ((x)->ip32)
228 #define sfip_get_ptr(x) (((x)->ip_family == AF_INET) ? &(x)->ip32[3] : (x)->ip32)
229
230 #define sfaddr_get_ip4_ptr(x) (&(x)->ia32[3])
231 #define sfaddr_get_ip6_ptr(x) ((x)->ia32)
232 #define sfaddr_get_ptr(x) (((x)->family == AF_INET) ? &(x)->ia32[3] : (x)->ia32)
233
234 /* Returns the family of "ip", either AF_INET or AF_INET6 */
235 /* XXX This is a performance critical function,
236 * need to determine if it's safe to not check these pointers */
237 /* ARG_CHECK1(ip, 0); */
238 #define sfaddr_family(x) ((x)->family)
239 #define sfip_family(x) ((x)->ip_family)
240
241 /* Returns the number of bits used for masking "ip" */
sfip_bits(const sfcidr_t * ip)242 static inline unsigned char sfip_bits(const sfcidr_t *ip) {
243 ARG_CHECK1(ip, 0);
244 return (unsigned char)ip->bits;
245 }
246
sfip_set_bits(sfcidr_t * p,int bits)247 static inline void sfip_set_bits(sfcidr_t *p, int bits) {
248
249 if(!p)
250 return;
251
252 if(bits < 0 || bits > 128) return;
253
254 p->bits = bits;
255 }
256
257 /* Returns the raw IP address as an in6_addr */
258 /*inline struct in6_addr sfip_to_raw(sfcidr_t *); */
259
260
261
262 /* IP Comparisons ******************************************************/
263
264 /* Check if ip is contained within the network specified by net */
265 /* Returns SFIP_EQUAL if so */
266 SFIP_RET sfip_contains(const sfcidr_t *net, const sfaddr_t *ip);
267
268 /* Returns 1 if the IP is non-zero. 0 otherwise */
269 /* XXX This is a performance critical function, \
270 * need to determine if it's safe to not check these pointers */\
sfraw_is_set(const struct in6_addr * addr)271 static inline int sfraw_is_set(const struct in6_addr *addr) {
272 /* ARG_CHECK1(ip, -1); */
273 return (addr->s6_addr32[3] || addr->s6_addr32[0] || addr->s6_addr32[1] || addr->s6_addr16[4] ||
274 (addr->s6_addr16[5] && addr->s6_addr16[5] != 0xFFFF)) ? 1 : 0;
275 }
276
sfaddr_is_set(const sfaddr_t * addr)277 static inline int sfaddr_is_set(const sfaddr_t *addr) {
278 /* ARG_CHECK1(ip, -1); */
279 return ((addr->family == AF_INET && addr->ia32[3]) ||
280 (addr->family == AF_INET6 &&
281 (addr->ia32[0] || addr->ia32[1] || addr->ia32[3] || addr->ia16[4] ||
282 (addr->ia16[5] && addr->ia16[5] != 0xFFFF)))) ? 1 : 0;
283 }
284
sfip_is_set(const sfcidr_t * ip)285 static inline int sfip_is_set(const sfcidr_t *ip) {
286 /* ARG_CHECK1(ip, -1); */
287 return (sfaddr_is_set(&ip->addr) ||
288 ((ip->ip_family == AF_INET || ip->ip_family == AF_INET6) &&
289 ip->bits != 128)) ? 1 : 0;
290 }
291
292 /* Return 1 if the IP is a loopback IP */
293 int sfip_is_loopback(const sfaddr_t *ip);
294
295 /* Returns 1 if the IPv6 address appears mapped. 0 otherwise. */
sfip_ismapped(const sfaddr_t * ip)296 static inline int sfip_ismapped(const sfaddr_t *ip) {
297 ARG_CHECK1(ip, 0);
298
299 return (ip->ia32[0] || ip->ia32[1] || ip->ia16[4] || (ip->ia16[5] != 0xffff && ip->ia16[5])) ? 0 : 1;
300 }
301
302 /* Support function for sfip_compare */
_ip4_cmp(u_int32_t ip1,u_int32_t ip2)303 static inline SFIP_RET _ip4_cmp(u_int32_t ip1, u_int32_t ip2) {
304 u_int32_t hip1 = htonl(ip1);
305 u_int32_t hip2 = htonl(ip2);
306 if(hip1 < hip2) return SFIP_LESSER;
307 if(hip1 > hip2) return SFIP_GREATER;
308 return SFIP_EQUAL;
309 }
310
311 /* Support function for sfip_compare */
_ip6_cmp(const sfaddr_t * ip1,const sfaddr_t * ip2)312 static inline SFIP_RET _ip6_cmp(const sfaddr_t *ip1, const sfaddr_t *ip2) {
313 SFIP_RET ret;
314 const struct in6_addr p1 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip1);
315 const struct in6_addr p2 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip2);
316
317 /* XXX
318 * Argument are assumed trusted!
319 * This function is presently only called by sfip_compare
320 * on validated pointers.
321 * XXX */
322
323 if( (ret = _ip4_cmp(p1.s6_addr32[0], p2.s6_addr32[0])) != SFIP_EQUAL) return ret;
324 if( (ret = _ip4_cmp(p1.s6_addr32[1], p2.s6_addr32[1])) != SFIP_EQUAL) return ret;
325 if( (ret = _ip4_cmp(p1.s6_addr32[2], p2.s6_addr32[2])) != SFIP_EQUAL) return ret;
326 if( (ret = _ip4_cmp(p1.s6_addr32[3], p2.s6_addr32[3])) != SFIP_EQUAL) return ret;
327
328 return ret;
329 }
330
331 /* Compares two IPs
332 * Returns SFIP_LESSER, SFIP_EQUAL, SFIP_GREATER, if ip1 is less than, equal to,
333 * or greater than ip2 In the case of mismatched families, the IPv4 address
334 * is converted to an IPv6 representation. */
335 /* XXX-IPv6 Should add version of sfip_compare that just tests equality */
sfip_compare(const sfaddr_t * ip1,const sfaddr_t * ip2)336 static inline SFIP_RET sfip_compare(const sfaddr_t *ip1, const sfaddr_t *ip2) {
337 int f1,f2;
338
339 ARG_CHECK2(ip1, ip2, SFIP_ARG_ERR);
340
341 /* This is being done because at some points in the existing Snort code,
342 * an unset IP is considered to match anything. Thus, if either IP is not
343 * set here, it's considered equal. */
344 if(!sfaddr_is_set(ip1) || !sfaddr_is_set(ip2)) return SFIP_EQUAL;
345
346 f1 = sfaddr_family(ip1);
347 f2 = sfaddr_family(ip2);
348
349 if(f1 == AF_INET && f2 == AF_INET) {
350 return _ip4_cmp(sfaddr_get_ip4_value(ip1), sfaddr_get_ip4_value(ip2));
351 }
352 return _ip6_cmp(ip1, ip2);
353 }
354
355 /* Compares two CIDRs
356 * Returns SFIP_LESSER, SFIP_EQUAL, SFIP_GREATER, if ip1 is less than, equal to,
357 * or greater than ip2 In the case of mismatched families, the IPv4 address
358 * is converted to an IPv6 representation. */
sfip_cidr_compare(const sfcidr_t * ip1,const sfcidr_t * ip2)359 static inline SFIP_RET sfip_cidr_compare(const sfcidr_t* ip1, const sfcidr_t *ip2) {
360 SFIP_RET ret = sfip_compare(&ip1->addr, &ip2->addr);
361 if(SFIP_EQUAL == ret)
362 {
363 if(ip1->bits < ip2->bits) return SFIP_LESSER;
364 if(ip1->bits > ip2->bits) return SFIP_GREATER;
365 }
366 return ret;
367 }
368
369 /* Compares two IPs
370 * Returns SFIP_LESSER, SFIP_EQUAL, SFIP_GREATER, if ip1 is less than, equal to,
371 * or greater than ip2 In the case of mismatched families, the IPv4 address
372 * is converted to an IPv6 representation. */
373 /* XXX-IPv6 Should add version of sfip_compare that just tests equality */
sfip_compare_unset(const sfaddr_t * ip1,const sfaddr_t * ip2)374 static inline SFIP_RET sfip_compare_unset(const sfaddr_t *ip1, const sfaddr_t *ip2) {
375 int f1,f2;
376
377 ARG_CHECK2(ip1, ip2, SFIP_ARG_ERR);
378
379 /* This is to handle the special case when one of the values being
380 * unset is considered to match nothing. This is the opposite of
381 * sfip_compare(), defined above. Thus, if either IP is not
382 * set here, it's considered not equal. */
383 if(!sfaddr_is_set(ip1) || !sfaddr_is_set(ip2)) return SFIP_FAILURE;
384
385 f1 = sfaddr_family(ip1);
386 f2 = sfaddr_family(ip2);
387
388 if(f1 == AF_INET && f2 == AF_INET) {
389 return _ip4_cmp(sfaddr_get_ip4_value(ip1), sfaddr_get_ip4_value(ip2));
390 }
391 return _ip6_cmp(ip1, ip2);
392 }
393
sfip_fast_lt4(const sfaddr_t * ip1,const sfaddr_t * ip2)394 static inline int sfip_fast_lt4(const sfaddr_t *ip1, const sfaddr_t *ip2) {
395 return sfaddr_get_ip4_value(ip1) < sfaddr_get_ip4_value(ip2);
396 }
sfip_fast_gt4(const sfaddr_t * ip1,const sfaddr_t * ip2)397 static inline int sfip_fast_gt4(const sfaddr_t *ip1, const sfaddr_t *ip2) {
398 return sfaddr_get_ip4_value(ip1) > sfaddr_get_ip4_value(ip2);
399 }
sfip_fast_eq4(const sfaddr_t * ip1,const sfaddr_t * ip2)400 static inline int sfip_fast_eq4(const sfaddr_t *ip1, const sfaddr_t *ip2) {
401 return sfaddr_get_ip4_value(ip1) == sfaddr_get_ip4_value(ip2);
402 }
403
sfip_fast_lt6(const sfaddr_t * ip1,const sfaddr_t * ip2)404 static inline int sfip_fast_lt6(const sfaddr_t *ip1, const sfaddr_t *ip2) {
405 const struct in6_addr p1 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip1);
406 const struct in6_addr p2 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip2);
407
408 if(p1.s6_addr32[0] < p2.s6_addr32[0]) return 1;
409 else if(p1.s6_addr32[0] > p2.s6_addr32[0]) return 0;
410
411 if(p1.s6_addr32[1] < p2.s6_addr32[1]) return 1;
412 else if(p1.s6_addr32[1] > p2.s6_addr32[1]) return 0;
413
414 if(p1.s6_addr32[2] < p2.s6_addr32[2]) return 1;
415 else if(p1.s6_addr32[2] > p2.s6_addr32[2]) return 0;
416
417 if(p1.s6_addr32[3] < p2.s6_addr32[3]) return 1;
418 else if(p1.s6_addr32[3] > p2.s6_addr32[3]) return 0;
419
420 return 0;
421 }
422
sfip_fast_gt6(const sfaddr_t * ip1,const sfaddr_t * ip2)423 static inline int sfip_fast_gt6(const sfaddr_t *ip1, const sfaddr_t *ip2) {
424 const struct in6_addr p1 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip1);
425 const struct in6_addr p2 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip2);
426
427 if(p1.s6_addr32[0] > p2.s6_addr32[0]) return 1;
428 else if(p1.s6_addr32[0] < p2.s6_addr32[0]) return 0;
429
430 if(p1.s6_addr32[1] > p2.s6_addr32[1]) return 1;
431 else if(p1.s6_addr32[1] < p2.s6_addr32[1]) return 0;
432
433 if(p1.s6_addr32[2] > p2.s6_addr32[2]) return 1;
434 else if(p1.s6_addr32[2] < p2.s6_addr32[2]) return 0;
435
436 if(p1.s6_addr32[3] > p2.s6_addr32[3]) return 1;
437 else if(p1.s6_addr32[3] < p2.s6_addr32[3]) return 0;
438
439 return 0;
440 }
441
sfip_fast_eq6(const sfaddr_t * ip1,const sfaddr_t * ip2)442 static inline int sfip_fast_eq6(const sfaddr_t *ip1, const sfaddr_t *ip2) {
443 const struct in6_addr p1 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip1);
444 const struct in6_addr p2 = *(struct in6_addr *)sfaddr_get_ip6_ptr(ip2);
445
446 if(p1.s6_addr32[0] != p2.s6_addr32[0]) return 0;
447 if(p1.s6_addr32[1] != p2.s6_addr32[1]) return 0;
448 if(p1.s6_addr32[2] != p2.s6_addr32[2]) return 0;
449 if(p1.s6_addr32[3] != p2.s6_addr32[3]) return 0;
450
451 return 1;
452 }
453
454 /* Checks if ip2 is equal to ip1 or contained within the CIDR ip1 */
sfip_fast_cont4(const sfcidr_t * ip1,const sfaddr_t * ip2)455 static inline int sfip_fast_cont4(const sfcidr_t *ip1, const sfaddr_t *ip2) {
456 uint32_t shift = 128 - sfip_bits(ip1);
457 uint32_t ip = ntohl(sfaddr_get_ip4_value(ip2));
458 uint32_t ip3 = ntohl(sfip_get_ip4_value(ip1));
459
460 ip >>= shift;
461 ip <<= shift;
462
463 if(ip3 == 0)
464 return 1;
465
466 return (ip3 == ip);
467 }
468
469 /* Checks if ip2 is equal to ip1 or contained within the CIDR ip1 */
sfip_fast_cont6(const sfcidr_t * ip1,const sfaddr_t * ip2)470 static inline int sfip_fast_cont6(const sfcidr_t *ip1, const sfaddr_t *ip2) {
471 uint32_t ip;
472 int i, bits = sfip_bits(ip1);
473 int words = bits / 32;
474 bits = 32 - (bits % 32);
475
476 for ( i = 0; i < words; i++ ) {
477 if ( ip1->ip32[i] != ip2->ia32[i] )
478 return 0;
479 }
480
481 if ( bits == 32 ) return 1;
482
483 ip = ntohl(ip2->ia32[i]);
484
485 ip >>= bits;
486 ip <<= bits;
487
488 return ntohl(ip1->ip32[i]) == ip;
489 }
490
491 /* Compares two IPs
492 * Returns 1 for equal and 0 for not equal
493 */
sfip_fast_equals_raw(const sfaddr_t * ip1,const sfaddr_t * ip2)494 static inline int sfip_fast_equals_raw(const sfaddr_t *ip1, const sfaddr_t *ip2)
495 {
496 int f1,f2;
497
498 ARG_CHECK2(ip1, ip2, 0);
499
500 f1 = sfaddr_family(ip1);
501 f2 = sfaddr_family(ip2);
502
503 if(f1 == AF_INET)
504 {
505 if(f2 != AF_INET)
506 return 0;
507 if (sfip_fast_eq4(ip1, ip2))
508 return 1;
509 }
510 else if(f1 == AF_INET6)
511 {
512 if(f2 != AF_INET6)
513 return 0;
514 if (sfip_fast_eq6(ip1, ip2))
515 return 1;
516 }
517 return 0;
518 }
519
520 /********************************************************************
521 * Function: sfip_is_private()
522 *
523 * Checks if the address is local
524 *
525 * Arguments:
526 * sfcidr_t * - IP address to check
527 *
528 * Returns:
529 * 1 if the IP is in local network
530 * 0 otherwise
531 *
532 ********************************************************************/
sfip_is_private(const sfaddr_t * ip)533 static inline int sfip_is_private(const sfaddr_t *ip)
534 {
535 ARG_CHECK1(ip, 0);
536
537 /* Check the first 80 bits in an IPv6 address, and */
538 /* verify they're zero. If not, it's not a loopback */
539 if(ip->ia32[0] || ip->ia32[1] || ip->ia16[4]) return 0;
540
541 if ( ip->ia16[5] == 0xffff ) {
542 /* ::ffff: IPv4 mapped over IPv6 */
543 /*
544 * 10.0.0.0 - 10.255.255.255 (10/8 prefix)
545 * 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
546 * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
547 * */
548 return ( (ip->ia8[12] == 10)
549 ||((ip->ia8[12] == 172) && ((ip->ia8[13] & 0xf0 ) == 16))
550 ||((ip->ia8[12] == 192) && (ip->ia8[13] == 168)) );
551 }
552
553 /* Check if the 3rd 32-bit int is zero */
554 if ( !ip->ia16[5] ) {
555 /* ::ipv4 compatible ipv6 */
556 /* ::1 is the IPv6 loopback */
557 return ( (ip->ia8[12] == 10)
558 ||((ip->ia8[12] == 172) && ((ip->ia8[13] & 0xf0 ) == 16))
559 ||((ip->ia8[12] == 192) && (ip->ia8[13] == 168))
560 || (ip->ia32[3] == htonl(0x1)) );
561 }
562
563 return 0;
564 }
565
sfaddr_copy_to_raw(struct in6_addr * dst,const sfaddr_t * src)566 static inline void sfaddr_copy_to_raw(struct in6_addr *dst, const sfaddr_t *src)
567 {
568 dst->s6_addr32[0] = src->ia32[0];
569 dst->s6_addr32[1] = src->ia32[1];
570 dst->s6_addr32[2] = src->ia32[2];
571 dst->s6_addr32[3] = src->ia32[3];
572 }
573
574 #define sfip_equals(x,y) (sfip_compare(&x, &y) == SFIP_EQUAL)
575 #define sfip_not_equals !sfip_equals
576 #define sfip_clear(x) memset(x, 0, 16)
577
578 /* Printing ************************************************************/
579
580 /* Uses a static buffer to return a string representation of the IP */
581 char *sfip_to_str(const sfaddr_t *ip);
582 #define sfip_ntoa(x) sfip_to_str(x)
583 void sfip_raw_ntop(int family, const void *ip_raw, char *buf, int bufsize);
584 void sfip_ntop(const sfaddr_t *ip, char *buf, int bufsize);
585
586 /* Conversions *********************************************************/
587
588 SFIP_RET sfip_convert_ip_text_to_binary( const int, const char *src, void *dst );
589
590 #endif /* SF_IP_H */
591
592