]> mj.ucw.cz Git - libucw.git/blob - lib/ipaccess.c
Fixed operator priorities in cf_parse_ip().
[libucw.git] / lib / ipaccess.c
1 /*
2  *      UCW Library -- IP address access lists
3  *
4  *      (c) 1997--2006 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/clists.h"
12 #include "lib/conf2.h"
13 #include "lib/ipaccess.h"
14
15 #undef ipaccess_check                   /* FIXME */
16
17 #include <string.h>
18
19 struct ipaccess_entry {
20   cnode n;
21   uns allow;
22   u32 addr, mask;
23 };
24
25 static byte *
26 ipaccess_cf_ip(uns n UNUSED, byte **pars, struct ipaccess_entry *a)
27 {
28   byte *c = pars[0];
29   CF_JOURNAL_VAR(a->addr);
30   CF_JOURNAL_VAR(a->mask);
31
32   byte *p = strchr(c, '/');
33   if (p)
34     *p++ = 0;
35   byte *err = cf_parse_ip(c, &a->addr);
36   if (err)
37     return err;
38   if (p)
39     {
40       uns len;
41       if (!cf_parse_int(p, &len) && len <= 32)
42         a->mask = ~(len == 32 ? 0 : ~0U >> len);
43       else if (cf_parse_ip(p, &a->mask))
44         return "Invalid prefix length or netmask";
45     }
46   else
47     a->mask = ~0U;
48   return NULL;
49 }
50
51 static byte *
52 ipaccess_cf_mode(uns n UNUSED, byte **pars, struct ipaccess_entry *a)
53 {
54   CF_JOURNAL_VAR(a->allow);
55   if (!strcasecmp(pars[0], "allow"))
56     a->allow = 1;
57   else if (!strcasecmp(pars[0], "deny"))
58     a->allow = 0;
59   else
60     return "Either `allow' or `deny' expected";
61   return NULL;
62 }
63
64 struct cf_section ipaccess_cf = {
65   CF_TYPE(struct ipaccess_entry),
66   CF_ITEMS {
67     CF_PARSER("Mode", NULL, ipaccess_cf_mode, 1),
68     CF_PARSER("IP", NULL, ipaccess_cf_ip, 1),
69     CF_END
70   }
71 };
72
73 int
74 ipaccess_check(clist *l, u32 ip)
75 {
76   CLIST_FOR_EACH(struct ipaccess_entry *, a, *l)
77     if (! ((ip ^ a->addr) & a->mask))
78       return a->allow;
79   return 0;
80 }
81
82 #ifdef TEST
83
84 #include <stdio.h>
85
86 static clist t;
87
88 static struct cf_section test_cf = {
89   CF_ITEMS {
90     CF_LIST("A", &t, &ipaccess_cf),
91     CF_END
92   }
93 };
94
95 int main(int argc, char **argv)
96 {
97   cf_declare_section("T", &test_cf, 0);
98   if (cf_get_opt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1)
99     die("Invalid arguments");
100
101   byte buf[256];
102   while (fgets(buf, sizeof(buf), stdin))
103     {
104       byte *c = strchr(buf, '\n');
105       if (c)
106         *c = 0;
107       u32 ip;
108       if (cf_parse_ip(buf, &ip))
109         puts("Invalid IP address");
110       else if (ipaccess_check(&t, ip))
111         puts("Allowed");
112       else
113         puts("Denied");
114     }
115   return 0;
116 }
117
118 #endif