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 */
|