From: Martin Mares Date: Tue, 25 Apr 2006 22:03:13 +0000 (+0200) Subject: ipaccess filters now use CF_USER for (addr,mask) pairs, operations X-Git-Tag: holmes-import~645^2~11^2~37 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=3c052bd949b11a549173fe65cef90a5851e10ac1;p=libucw.git ipaccess filters now use CF_USER for (addr,mask) pairs, operations on lists now work fine. --- diff --git a/lib/ipaccess.c b/lib/ipaccess.c index f1637c85..f9cda623 100644 --- a/lib/ipaccess.c +++ b/lib/ipaccess.c @@ -14,43 +14,55 @@ #include +struct addrmask { + u32 addr; + u32 mask; +}; + struct ipaccess_entry { cnode n; int allow; - u32 addr, mask; + struct addrmask addr; }; -static byte * -ipaccess_cf_ip(uns n UNUSED, byte **pars, struct ipaccess_entry *a) +static byte *addrmask_parser(byte *c, void *ptr) { - byte *c = pars[0]; - CF_JOURNAL_VAR(a->addr); - CF_JOURNAL_VAR(a->mask); + /* + * This is tricky: addrmasks will be compared by memcmp(), so we must ensure + * that even the padding between structure members is zeroed out. + */ + struct addrmask *am = ptr; + bzero(am, sizeof(*am)); byte *p = strchr(c, '/'); if (p) *p++ = 0; - byte *err = cf_parse_ip(c, &a->addr); + byte *err = cf_parse_ip(c, &am->addr); if (err) return err; if (p) { uns len; if (!cf_parse_int(p, &len) && len <= 32) - a->mask = ~(len == 32 ? 0 : ~0U >> len); - else if (cf_parse_ip(p, &a->mask)) + am->mask = ~(len == 32 ? 0 : ~0U >> len); + else if (cf_parse_ip(p, &am->mask)) return "Invalid prefix length or netmask"; } else - a->mask = ~0U; + am->mask = ~0U; return NULL; } +static struct cf_user_type addrmask_type = { + .size = sizeof(struct addrmask), + .parser = addrmask_parser +}; + struct cf_section ipaccess_cf = { CF_TYPE(struct ipaccess_entry), CF_ITEMS { CF_LOOKUP("Mode", PTR_TO(struct ipaccess_entry, allow), ((char*[]) { "deny", "allow" })), - CF_PARSER("IP", NULL, ipaccess_cf_ip, 1), + CF_USER("IP", PTR_TO(struct ipaccess_entry, addr), &addrmask_type), CF_END } }; @@ -59,7 +71,7 @@ int ipaccess_check(clist *l, u32 ip) { CLIST_FOR_EACH(struct ipaccess_entry *, a, *l) - if (! ((ip ^ a->addr) & a->mask)) + if (! ((ip ^ a->addr.addr) & a->addr.mask)) return a->allow; return 0; }