LCOV - code coverage report
Current view: top level - src - ipacl.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 3 119 2.5 %
Date: 2022-05-01 01:22:11 Functions: 1 11 9.1 %

          Line data    Source code
       1             : #include "ipacl.h"
       2             : 
       3             : #ifdef USE_IPACL
       4             : #include <limits.h>
       5             : #include <errno.h>
       6             : #include <string.h>
       7             : #include <ctype.h>
       8             : #include <stdlib.h>
       9             : 
      10             : #define E(a, b, c, d) \
      11             :         {.ip6 = { \
      12             :                 cpu_to_be32(a), cpu_to_be32(b), \
      13             :                 cpu_to_be32(c), cpu_to_be32(d), \
      14             :         }}
      15             : 
      16             : /* This table works for both IPv4 and IPv6;
      17             :  * just use prefixlen_netmask_map[prefixlength].ip.
      18             :  */
      19             : static const union ipacl_inet_addr ipacl_netmask_map[]=
      20             : {
      21             :         E(0x00000000, 0x00000000, 0x00000000, 0x00000000),
      22             :         E(0x80000000, 0x00000000, 0x00000000, 0x00000000),
      23             :         E(0xC0000000, 0x00000000, 0x00000000, 0x00000000),
      24             :         E(0xE0000000, 0x00000000, 0x00000000, 0x00000000),
      25             :         E(0xF0000000, 0x00000000, 0x00000000, 0x00000000),
      26             :         E(0xF8000000, 0x00000000, 0x00000000, 0x00000000),
      27             :         E(0xFC000000, 0x00000000, 0x00000000, 0x00000000),
      28             :         E(0xFE000000, 0x00000000, 0x00000000, 0x00000000),
      29             :         E(0xFF000000, 0x00000000, 0x00000000, 0x00000000),
      30             :         E(0xFF800000, 0x00000000, 0x00000000, 0x00000000),
      31             :         E(0xFFC00000, 0x00000000, 0x00000000, 0x00000000),
      32             :         E(0xFFE00000, 0x00000000, 0x00000000, 0x00000000),
      33             :         E(0xFFF00000, 0x00000000, 0x00000000, 0x00000000),
      34             :         E(0xFFF80000, 0x00000000, 0x00000000, 0x00000000),
      35             :         E(0xFFFC0000, 0x00000000, 0x00000000, 0x00000000),
      36             :         E(0xFFFE0000, 0x00000000, 0x00000000, 0x00000000),
      37             :         E(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000),
      38             :         E(0xFFFF8000, 0x00000000, 0x00000000, 0x00000000),
      39             :         E(0xFFFFC000, 0x00000000, 0x00000000, 0x00000000),
      40             :         E(0xFFFFE000, 0x00000000, 0x00000000, 0x00000000),
      41             :         E(0xFFFFF000, 0x00000000, 0x00000000, 0x00000000),
      42             :         E(0xFFFFF800, 0x00000000, 0x00000000, 0x00000000),
      43             :         E(0xFFFFFC00, 0x00000000, 0x00000000, 0x00000000),
      44             :         E(0xFFFFFE00, 0x00000000, 0x00000000, 0x00000000),
      45             :         E(0xFFFFFF00, 0x00000000, 0x00000000, 0x00000000),
      46             :         E(0xFFFFFF80, 0x00000000, 0x00000000, 0x00000000),
      47             :         E(0xFFFFFFC0, 0x00000000, 0x00000000, 0x00000000),
      48             :         E(0xFFFFFFE0, 0x00000000, 0x00000000, 0x00000000),
      49             :         E(0xFFFFFFF0, 0x00000000, 0x00000000, 0x00000000),
      50             :         E(0xFFFFFFF8, 0x00000000, 0x00000000, 0x00000000),
      51             :         E(0xFFFFFFFC, 0x00000000, 0x00000000, 0x00000000),
      52             :         E(0xFFFFFFFE, 0x00000000, 0x00000000, 0x00000000),
      53             :         E(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000),
      54             :         E(0xFFFFFFFF, 0x80000000, 0x00000000, 0x00000000),
      55             :         E(0xFFFFFFFF, 0xC0000000, 0x00000000, 0x00000000),
      56             :         E(0xFFFFFFFF, 0xE0000000, 0x00000000, 0x00000000),
      57             :         E(0xFFFFFFFF, 0xF0000000, 0x00000000, 0x00000000),
      58             :         E(0xFFFFFFFF, 0xF8000000, 0x00000000, 0x00000000),
      59             :         E(0xFFFFFFFF, 0xFC000000, 0x00000000, 0x00000000),
      60             :         E(0xFFFFFFFF, 0xFE000000, 0x00000000, 0x00000000),
      61             :         E(0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000),
      62             :         E(0xFFFFFFFF, 0xFF800000, 0x00000000, 0x00000000),
      63             :         E(0xFFFFFFFF, 0xFFC00000, 0x00000000, 0x00000000),
      64             :         E(0xFFFFFFFF, 0xFFE00000, 0x00000000, 0x00000000),
      65             :         E(0xFFFFFFFF, 0xFFF00000, 0x00000000, 0x00000000),
      66             :         E(0xFFFFFFFF, 0xFFF80000, 0x00000000, 0x00000000),
      67             :         E(0xFFFFFFFF, 0xFFFC0000, 0x00000000, 0x00000000),
      68             :         E(0xFFFFFFFF, 0xFFFE0000, 0x00000000, 0x00000000),
      69             :         E(0xFFFFFFFF, 0xFFFF0000, 0x00000000, 0x00000000),
      70             :         E(0xFFFFFFFF, 0xFFFF8000, 0x00000000, 0x00000000),
      71             :         E(0xFFFFFFFF, 0xFFFFC000, 0x00000000, 0x00000000),
      72             :         E(0xFFFFFFFF, 0xFFFFE000, 0x00000000, 0x00000000),
      73             :         E(0xFFFFFFFF, 0xFFFFF000, 0x00000000, 0x00000000),
      74             :         E(0xFFFFFFFF, 0xFFFFF800, 0x00000000, 0x00000000),
      75             :         E(0xFFFFFFFF, 0xFFFFFC00, 0x00000000, 0x00000000),
      76             :         E(0xFFFFFFFF, 0xFFFFFE00, 0x00000000, 0x00000000),
      77             :         E(0xFFFFFFFF, 0xFFFFFF00, 0x00000000, 0x00000000),
      78             :         E(0xFFFFFFFF, 0xFFFFFF80, 0x00000000, 0x00000000),
      79             :         E(0xFFFFFFFF, 0xFFFFFFC0, 0x00000000, 0x00000000),
      80             :         E(0xFFFFFFFF, 0xFFFFFFE0, 0x00000000, 0x00000000),
      81             :         E(0xFFFFFFFF, 0xFFFFFFF0, 0x00000000, 0x00000000),
      82             :         E(0xFFFFFFFF, 0xFFFFFFF8, 0x00000000, 0x00000000),
      83             :         E(0xFFFFFFFF, 0xFFFFFFFC, 0x00000000, 0x00000000),
      84             :         E(0xFFFFFFFF, 0xFFFFFFFE, 0x00000000, 0x00000000),
      85             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000),
      86             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x00000000),
      87             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000, 0x00000000),
      88             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000, 0x00000000),
      89             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000, 0x00000000),
      90             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000, 0x00000000),
      91             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000, 0x00000000),
      92             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000, 0x00000000),
      93             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000),
      94             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000, 0x00000000),
      95             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000, 0x00000000),
      96             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000, 0x00000000),
      97             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000, 0x00000000),
      98             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000, 0x00000000),
      99             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000, 0x00000000),
     100             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000, 0x00000000),
     101             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0x00000000),
     102             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000, 0x00000000),
     103             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000, 0x00000000),
     104             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000, 0x00000000),
     105             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000, 0x00000000),
     106             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800, 0x00000000),
     107             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00, 0x00000000),
     108             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00, 0x00000000),
     109             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0x00000000),
     110             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80, 0x00000000),
     111             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0, 0x00000000),
     112             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0, 0x00000000),
     113             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0, 0x00000000),
     114             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8, 0x00000000),
     115             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC, 0x00000000),
     116             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000000),
     117             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000),
     118             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000),
     119             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000),
     120             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000),
     121             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000),
     122             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000),
     123             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000),
     124             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000),
     125             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000),
     126             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000),
     127             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000),
     128             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000),
     129             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000),
     130             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000),
     131             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000),
     132             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000),
     133             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000),
     134             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000),
     135             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000),
     136             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000),
     137             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000),
     138             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800),
     139             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00),
     140             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00),
     141             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00),
     142             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80),
     143             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0),
     144             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0),
     145             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0),
     146             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8),
     147             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC),
     148             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE),
     149             :         E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
     150             : };
     151             : #undef E
     152             : 
     153             : __always_inline
     154             : static __be32 ipacl_netmask(__u8 pfxlen)
     155             : {
     156           0 :         return ipacl_netmask_map[pfxlen].ip;
     157             : }
     158             : 
     159             : __always_inline
     160             : static const __be32 *ipacl_netmask6(__u8 pfxlen)
     161             : {
     162           0 :         return &ipacl_netmask_map[pfxlen].ip6[0];
     163             : }
     164             : 
     165             : __always_inline
     166             : static void ip6_netmask(union ipacl_inet_addr *ip, __u8 prefix)
     167             : {
     168           0 :         ip->ip6[0]&=ipacl_netmask6(prefix)[0];
     169           0 :         ip->ip6[1]&=ipacl_netmask6(prefix)[1];
     170           0 :         ip->ip6[2]&=ipacl_netmask6(prefix)[2];
     171           0 :         ip->ip6[3]&=ipacl_netmask6(prefix)[3];
     172             : }
     173             : 
     174             : __always_inline
     175             : static void ipacl_net4_data_netmask(struct ipacl_net4_elem *elem, __u8 cidr)
     176             : {
     177           0 :         elem->ip&=ipacl_netmask(cidr);
     178           0 :         elem->cidr=cidr;
     179             : }
     180             : 
     181             : __always_inline
     182             : static void ipacl_net6_data_netmask(struct ipacl_net6_elem *elem, __u8 cidr)
     183             : {
     184           0 :         ip6_netmask(&elem->ip, cidr);
     185           0 :         elem->cidr=cidr;
     186             : }
     187             : 
     188             : __always_inline
     189             : static bool ipv_prefix_equal(const __be32 addr1,
     190             :         const __be32 addr2, unsigned int prefixlen)
     191             : {
     192           0 :         return !((addr1 ^ addr2) & ipacl_netmask(prefixlen));
     193             : }
     194             : 
     195             : __always_inline
     196             : static bool __ipv6_prefix_equal64_half(const __be64 *a1,
     197             :         const __be64 *a2, unsigned int len)
     198             : {
     199           0 :         return !(len && ((*a1 ^ *a2) & htobe64((~0UL) << (64-len))));
     200             : }
     201             : 
     202             : __always_inline
     203             : static bool ipv6_prefix_equal(const struct in6_addr *addr1,
     204             :         const struct in6_addr *addr2, unsigned int prefixlen)
     205             : {
     206           0 :         const __be64 *a1 = (const __be64 *)addr1;
     207           0 :         const __be64 *a2 = (const __be64 *)addr2;
     208             : 
     209           0 :         if(prefixlen >= 64)
     210             :         {
     211           0 :                 if(a1[0] ^ a2[0])
     212             :                         return false;
     213             : 
     214           0 :                 return __ipv6_prefix_equal64_half(a1+1, a2+1, prefixlen-64);
     215             :         }
     216           0 :         return __ipv6_prefix_equal64_half(a1, a2, prefixlen);
     217             : }
     218             : 
     219             : __always_inline
     220             : static bool ipacl_net4_do_match(struct ipacl_net4_elem *elem,
     221             :         const struct sockaddr_in *in)
     222             : {
     223           0 :         return ipv_prefix_equal(in->sin_addr.s_addr, elem->ip, elem->cidr);
     224             : }
     225             : 
     226             : __always_inline
     227             : static bool ipacl_net6_do_match(struct ipacl_net6_elem *elem, const struct sockaddr_in6 *in6)
     228             : {
     229           0 :         return ipv6_prefix_equal(&in6->sin6_addr, &elem->ip.in6, elem->cidr);
     230             : }
     231             : 
     232           0 : static ipacl_entity_t *ipacl_create(hipacl_t *acl, struct sockaddr_storage *ss, __u8 cidr)
     233             : {
     234           0 :         ipacl_entity_t *elem=malloc_w(sizeof(ipacl_entity_t), __func__);
     235             : 
     236           0 :         if (!elem)
     237             :                 return NULL;
     238             : 
     239           0 :         elem->ss_family=ss->ss_family;
     240             : 
     241           0 :         switch(ss->ss_family)
     242             :         {
     243             :                 case AF_INET:
     244           0 :                         memcpy(&elem->in, &((struct sockaddr_in *)ss)->sin_addr, sizeof(struct in_addr));
     245           0 :                         ipacl_net4_data_netmask(&elem->in, cidr);
     246             :                         break;
     247             :                 case AF_INET6:
     248           0 :                         memcpy(&elem->in6, &(((struct sockaddr_in6 *)ss))->sin6_addr, sizeof(struct in6_addr));
     249           0 :                         ipacl_net6_data_netmask(&elem->in6, cidr);
     250             :                         break;
     251             :         }
     252             : 
     253           0 :         SLIST_INSERT_HEAD(acl, elem, node);
     254           0 :         return elem;
     255             : }
     256             : 
     257           0 : static bool parse_prefix(const char *str, long *prefix)
     258             : {
     259             :         char *endptr;
     260             :         long val;
     261             : 
     262           0 :         errno=0; /* To distinguish success/failure after call */
     263             : 
     264           0 :         val=strtol(str, &endptr, 10);
     265             : 
     266           0 :         if((errno==ERANGE && (val==LONG_MAX || val==LONG_MIN))
     267           0 :           || (errno!=0 && val==0)
     268           0 :           || endptr==str) // No digits were found
     269             :                 return false;
     270             : 
     271           0 :         if(prefix)
     272           0 :                 *prefix = val;
     273             :         return true;
     274             : }
     275             : 
     276             : static bool check_prefix(long *prefix, sa_family_t ss_family)
     277             : {
     278           0 :         switch(ss_family)
     279             :         {
     280             :                 case AF_INET:
     281           0 :                         *prefix=(*prefix == -1) ? 32 : *prefix;
     282           0 :                         return (*prefix>=0 && *prefix<=32);
     283             :                 case AF_INET6:
     284           0 :                         *prefix=(*prefix == -1) ? 128 : *prefix;
     285           0 :                         return (*prefix>=0 && *prefix<=128);
     286             :                 default:
     287             :                         return false;
     288             :         }
     289             : }
     290             : 
     291           0 : const char *ipacl_strerror(ipacl_res_t res)
     292             : {
     293           0 :         switch(res)
     294             :         {
     295             :                 case IPACL_OK:                  return "success";
     296           0 :                 case IPACL_INVALID_PREFIX:      return "invalid prefix";
     297           0 :                 case IPACL_UNPARSABLE_PREFIX:   return "unparsable prefix";
     298           0 :                 case IPACL_UNPARSABLE_ADDR:     return "unparsable address";
     299           0 :                 case IPACL_NOMEM:               return "no memory";
     300           0 :                 default:                        return "unknown";
     301             :         }
     302             : }
     303             : 
     304           0 : static char *trim(char *str)
     305             : {
     306             :         char *end;
     307             : 
     308           0 :         if(!str)
     309             :                 return NULL;
     310             : 
     311           0 :         while(isspace(*str)) str++;
     312             : 
     313           0 :         if(*str==0)
     314             :                 return str;
     315             : 
     316           0 :         end=str+strlen(str)-1;
     317           0 :         while(end>str && isspace(*end)) end--;
     318             : 
     319           0 :         *(end+1)=0;
     320           0 :         return str;
     321             : }
     322             : 
     323           0 : ipacl_res_t ipacl_emplace(hipacl_t *hacl, const char *ipacl_str)
     324           0 : {
     325           0 :         struct sockaddr_storage ss={};
     326             :         size_t acl_str_length;
     327             : 
     328           0 :         if(!hacl || !ipacl_str
     329           0 :           || !(acl_str_length=strlen(ipacl_str)))
     330             :                 return IPACL_OK;
     331             : 
     332             : #pragma GCC diagnostic push
     333             : #pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
     334             : 
     335           0 :         char __acl_str[++acl_str_length], *p;
     336             : 
     337             : #pragma GCC diagnostic pop
     338             : 
     339           0 :         memcpy(__acl_str, ipacl_str, acl_str_length);
     340             : 
     341           0 :         if((p = strrchr(__acl_str, '/')))
     342           0 :                 *(p++)=0;
     343             : 
     344           0 :         if(inet_pton(AF_INET, __acl_str, &(((struct sockaddr_in *)&ss)->sin_addr))==1)
     345           0 :                 ss.ss_family = AF_INET;
     346           0 :         else if(inet_pton(AF_INET6, __acl_str, &((struct sockaddr_in6 *)&ss)->sin6_addr)==1)
     347           0 :                 ss.ss_family = AF_INET6;
     348             :         else
     349             :                 return IPACL_UNPARSABLE_ADDR;
     350             : 
     351           0 :         long prefix=-1;
     352             : 
     353           0 :         if(p && !parse_prefix(p, &prefix))
     354             :                 return IPACL_UNPARSABLE_PREFIX;
     355             : 
     356           0 :         if(!check_prefix(&prefix, ss.ss_family))
     357             :                 return IPACL_INVALID_PREFIX;
     358             : 
     359           0 :         if(ipacl_create(hacl, &ss, prefix)==NULL)
     360             :                 return IPACL_NOMEM;
     361             : 
     362           0 :         return IPACL_OK;
     363             : }
     364             : 
     365             : /**  Parse ipacl_str and add elements to dst acl */
     366           0 : ipacl_res_t ipacl_append(hipacl_t *hacl, const char *ipacl_str, int *size)
     367           0 : {
     368             :         size_t ipacl_str_length;
     369           0 :         ipacl_res_t rc=IPACL_OK;
     370             :         char *token;
     371           0 :         int _size=0;
     372             : 
     373           0 :         if(!hacl || !ipacl_str
     374           0 :           || !(ipacl_str_length=strlen(ipacl_str)))
     375             :                 return IPACL_OK;
     376             : 
     377             : #pragma GCC diagnostic push
     378             : #pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
     379             : 
     380           0 :         char *context=NULL,
     381           0 :                 __ipacl_str[++ipacl_str_length];
     382             : 
     383             : #pragma GCC diagnostic pop
     384             : 
     385           0 :         memcpy(__ipacl_str, ipacl_str, ipacl_str_length);
     386             : 
     387           0 :         for(token=strtok_r(__ipacl_str," ,;", &context);
     388             :                 token;
     389           0 :                 token=strtok_r(NULL," ,;", &context), ++_size)
     390             :         {
     391           0 :                 if((rc=ipacl_emplace(hacl, trim(token)))!=IPACL_OK)
     392             :                         break;
     393             :         }
     394             : 
     395           0 :         if(size)
     396           0 :                 *size = _size;
     397             :         return rc;
     398             : }
     399             : 
     400         260 : void ipacl_free(hipacl_t *hacl)
     401             : {
     402         260 :         if(!hacl)
     403             :                 return;
     404             : 
     405         260 :         while(!SLIST_EMPTY(hacl))
     406             :         {
     407           0 :                 ipacl_entity_t *e=SLIST_FIRST(hacl);
     408           0 :                 SLIST_REMOVE_HEAD(hacl, node);
     409           0 :                 free_v((void **)&e);
     410             :         }
     411             : }
     412             : 
     413           0 : bool ipacl_test_saddr_storage(const hipacl_t *hacl, const struct sockaddr_storage *ss)
     414             : {
     415           0 :         if(!ss || !hacl)
     416             :                 return false;
     417             : 
     418             :         ipacl_entity_t *e;
     419             : 
     420           0 :         SLIST_FOREACH(e, hacl, node)
     421             :         {
     422           0 :                 if (e->ss_family!=ss->ss_family)
     423           0 :                         continue;
     424             : 
     425           0 :                 bool match=e->ss_family==AF_INET
     426           0 :                         ? ipacl_net4_do_match(&e->in, (const struct sockaddr_in *)ss)
     427           0 :                         : ipacl_net6_do_match(&e->in6, (const struct sockaddr_in6 *)ss);
     428           0 :                 if(match)
     429             :                         return true;
     430             :         }
     431             :         return false;
     432             : }
     433             : 
     434           0 : bool ipacl_test_saddr(const hipacl_t *hacl, const struct sockaddr *saddr)
     435             : {
     436           0 :         return ipacl_test_saddr_storage(hacl, (const struct sockaddr_storage*)saddr);
     437             : }
     438             : 
     439           0 : bool ipacl_test_ip(const hipacl_t *hacl, const char *ip)
     440             : {
     441             :         struct sockaddr_storage ss;
     442             : 
     443           0 :         if(inet_pton(AF_INET, ip, &(((struct sockaddr_in *)&ss)->sin_addr)) == 1)
     444           0 :                 ss.ss_family=AF_INET;
     445           0 :         else if(inet_pton(AF_INET6, ip, &(((struct sockaddr_in6 *)&ss)->sin6_addr)) == 1)
     446           0 :                 ss.ss_family=AF_INET6;
     447             :         else
     448           0 :                 ss.ss_family=AF_UNSPEC;
     449             : 
     450           0 :         return ss.ss_family!=AF_UNSPEC
     451           0 :                 ? ipacl_test_saddr(hacl, (struct sockaddr *)&ss)
     452           0 :                 : false;
     453             : }
     454             : 
     455           0 : bool ipacl_is_empty(const hipacl_t *hacl)
     456             : {
     457           0 :         return SLIST_EMPTY(hacl);
     458             : }
     459             : 
     460             : #endif /* USE_IPACL */

Generated by: LCOV version 1.13