2 * UCW Library -- IP address access lists
4 * (c) 1997--2007 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
11 #include "lib/clists.h"
13 #include "lib/getopt.h"
14 #include "lib/fastbuf.h"
15 #include "lib/ipaccess.h"
19 struct ipaccess_entry {
22 struct ip_addrmask addr;
26 addrmask_parser(char *c, void *ptr)
29 * This is tricky: addrmasks will be compared by memcmp(), so we must ensure
30 * that even the padding between structure members is zeroed out.
32 struct ip_addrmask *am = ptr;
33 bzero(am, sizeof(*am));
35 char *p = strchr(c, '/');
38 char *err = cf_parse_ip(c, &am->addr);
44 if (!cf_parse_int(p, &len) && len <= 32)
45 am->mask = ~(len == 32 ? 0 : ~0U >> len);
46 else if (cf_parse_ip(p, &am->mask))
47 return "Invalid prefix length or netmask";
55 addrmask_dumper(struct fastbuf *fb, void *ptr)
57 struct ip_addrmask *am = ptr;
58 bprintf(fb, "%08x/%08x ", am->addr, am->mask);
61 struct cf_user_type ip_addrmask_type = {
62 .size = sizeof(struct ip_addrmask),
63 .name = "ip_addrmask",
64 .parser = addrmask_parser,
65 .dumper = addrmask_dumper
68 struct cf_section ipaccess_cf = {
69 CF_TYPE(struct ipaccess_entry),
71 CF_LOOKUP("Mode", PTR_TO(struct ipaccess_entry, allow), ((char*[]) { "deny", "allow", NULL })),
72 CF_USER("IP", PTR_TO(struct ipaccess_entry, addr), &ip_addrmask_type),
77 int ip_addrmask_match(struct ip_addrmask *am, u32 ip)
79 return !((ip ^ am->addr) & am->mask);
83 ipaccess_check(clist *l, u32 ip)
85 CLIST_FOR_EACH(struct ipaccess_entry *, a, *l)
86 if (ip_addrmask_match(&a->addr, ip))
97 static struct cf_section test_cf = {
99 CF_LIST("A", &t, &ipaccess_cf),
104 int main(int argc, char **argv)
106 cf_declare_section("T", &test_cf, 0);
107 if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1)
108 die("Invalid arguments");
111 while (fgets(buf, sizeof(buf), stdin))
113 char *c = strchr(buf, '\n');
117 if (cf_parse_ip(buf, &ip))
118 puts("Invalid IP address");
119 else if (ipaccess_check(&t, ip))