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