X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fipaccess.c;h=51d9eb586fe8e1859394b19ea02f78ec2d4b7193;hb=396571ed89ec4260ba3fd1b7ce2b38b07bd90ab7;hp=8a4841695fd8cce56187748fbd6120ea6aae4826;hpb=04294f573be8073e305f70621e6e74e2440f7f24;p=libucw.git diff --git a/lib/ipaccess.c b/lib/ipaccess.c index 8a484169..51d9eb58 100644 --- a/lib/ipaccess.c +++ b/lib/ipaccess.c @@ -1,15 +1,24 @@ /* - * Sherlock Library -- IP address access lists + * UCW Library -- IP address access lists * * (c) 1997--2001 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. */ #include "lib/lib.h" +#include "lib/lists.h" #include "lib/conf.h" #include "lib/chartype.h" #include "lib/ipaccess.h" #include +#include + +struct ipaccess_list { + list l; +}; struct ipaccess_entry { node n; @@ -17,10 +26,14 @@ struct ipaccess_entry { u32 addr, mask; }; -void -ipaccess_init(ipaccess_list *l) +struct ipaccess_list * +ipaccess_init(void) { - init_list(l); + /* Cannot use cfg_malloc() here as the pool can be uninitialized now */ + struct ipaccess_list *l = xmalloc(sizeof(*l)); + + init_list(&l->l); + return l; } static byte * @@ -47,31 +60,37 @@ parse_ip(byte *x, u32 *a) } byte * -ipaccess_parse(ipaccess_list *l, byte *c, int is_allow) +ipaccess_parse(struct ipaccess_list *l, byte *c, int is_allow) { - byte *p = strchr(c, '/'); - byte *q; + char *p = strchr(c, '/'); + char *q; struct ipaccess_entry *a = cfg_malloc(sizeof(struct ipaccess_entry)); + unsigned long pxlen; a->allow = is_allow; + a->mask = ~0U; if (p) { *p++ = 0; - if (q = parse_ip(p, &a->mask)) + pxlen = strtoul(p, &q, 10); + if ((!q || !*q) && pxlen <= 32) + { + if (pxlen != 32) + a->mask = ~(~0U >> (uns) pxlen); + } + else if (q = parse_ip(p, &a->mask)) return q; } - else - a->mask = ~0; - add_tail(l, &a->n); + add_tail(&l->l, &a->n); return parse_ip(c, &a->addr); } int -ipaccess_check(ipaccess_list *l, u32 ip) +ipaccess_check(struct ipaccess_list *l, u32 ip) { struct ipaccess_entry *a; - DO_FOR_ALL(a, *l) + DO_FOR_ALL(a, l->l) if (! ((ip ^ a->addr) & a->mask)) return a->allow; return 0;