]> mj.ucw.cz Git - libucw.git/commitdiff
A preliminary version of the new ipaccess module.
authorMartin Mares <mj@ucw.cz>
Tue, 25 Apr 2006 12:08:34 +0000 (14:08 +0200)
committerMartin Mares <mj@ucw.cz>
Tue, 25 Apr 2006 12:08:34 +0000 (14:08 +0200)
lib/Makefile
lib/ipaccess.c
lib/ipaccess.h

index 216da3c1f17fe09edac5854e193d9e7f9f16742b..8cbf1c989cd732250749bba2726aa03d15d711c2 100644 (file)
@@ -78,6 +78,7 @@ $(o)/lib/redblack-test: $(o)/lib/redblack-test.o $(LIBUCW)
 $(o)/lib/binheap-test: $(o)/lib/binheap-test.o $(LIBUCW)
 $(o)/lib/lizard-test: $(o)/lib/lizard-test.o $(LIBUCW)
 $(o)/lib/kmp-test: $(o)/lib/kmp-test.o $(LIBUCW) $(LIBCHARSET)
+$(o)/lib/ipaccess-test: $(o)/lib/ipaccess-test.o $(LIBUCW)
 
 TESTS+=$(addprefix $(o)/lib/,regex.test unicode-utf8.test hash-test.test mempool.test stkstring.test slists.test kmp-test.test)
 $(o)/lib/regex.test: $(o)/lib/regex-t
index 319a99ec4997bea964dfce1222f30429a637fc23..2116f71d9b6193815a947c6653b1a8440601e437 100644 (file)
 /*
  *     UCW Library -- IP address access lists
  *
- *     (c) 1997--2001 Martin Mares <mj@ucw.cz>
+ *     (c) 1997--2006 Martin Mares <mj@ucw.cz>
  *
  *     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/clists.h"
 #include "lib/conf2.h"
-#include "lib/chartype.h"
 #include "lib/ipaccess.h"
 
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
+#undef ipaccess_check                  /* FIXME */
 
-struct ipaccess_list {
-  list l;
-};
+#include <string.h>
 
 struct ipaccess_entry {
-  node n;
+  cnode n;
   uns allow;
   u32 addr, mask;
 };
 
-struct ipaccess_list *
-ipaccess_init(void)
-{
-  /* 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;
-}
-
-// FIXME: replace by cf_parse_ip()
 static byte *
-parse_ip(byte **p, u32 *varp)
+ipaccess_cf_ip(uns n UNUSED, byte **pars, struct ipaccess_entry *a)
 {
-  while (Cspace(**p))
-    (*p)++;
-  if (!**p)
-    return "Missing IP address";
-  uns x = 0;
-  if (**p == '0' && *(*p + 1) | 32 == 'X')
+  byte *c = pars[0];
+  CF_JOURNAL_VAR(a->addr);
+  CF_JOURNAL_VAR(a->mask);
+
+  byte *p = strchr(c, '/');
+  if (p)
+    *p++ = 0;
+  byte *err = cf_parse_ip(c, &a->addr);
+  if (err)
+    return err;
+  if (p)
     {
-      errno = 0;
-      x = strtoul(*p + 2, (char **)p, 16);
-      if (errno == ERANGE || x > 0xffffffff)
-        goto error;
+      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))
+       return "Invalid prefix length or netmask";
     }
   else
-    for (uns i = 0; i < 4; i++)
-      {
-        if (i)
-          {
-            while (Cspace(**p))
-              (*p)++;
-            if (*(*p)++ != '.')
-              goto error;
-          }
-        while (Cspace(**p))
-          (*p)++;
-        errno = 0;
-        uns y = strtoul(*p, (char **)p, 10);
-        if (errno == ERANGE || y > 255)
-          goto error;
-        x = (x << 8) + y;
-      }
-  *varp = x;
+    a->mask = ~0U;
   return NULL;
-error:
-  return "Invalid IP address";
 }
 
-byte *
-ipaccess_parse(struct ipaccess_list *l, byte *c, int is_allow)
+static byte *
+ipaccess_cf_mode(uns n UNUSED, byte **pars, struct ipaccess_entry *a)
 {
-  byte *p = strchr(c, '/');
-  char *q;
-  struct ipaccess_entry *a = cf_malloc(sizeof(struct ipaccess_entry));
-  unsigned long pxlen;
-
-  a->allow = is_allow;
-  a->mask = ~0U;
-  if (p)
-    {
-      *p++ = 0;
-      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;
-    }
-  add_tail(&l->l, &a->n);
-  return parse_ip(&c, &a->addr);
+  CF_JOURNAL_VAR(a->allow);
+  if (!strcasecmp(pars[0], "allow"))
+    a->allow = 1;
+  else if (!strcasecmp(pars[0], "deny"))
+    a->allow = 0;
+  else
+    return "Either `allow' or `deny' expected";
+  return NULL;
 }
 
+struct cf_section ipaccess_cf = {
+  CF_TYPE(struct ipaccess_entry),
+  CF_ITEMS {
+    CF_PARSER("Mode", NULL, ipaccess_cf_mode, 1),
+    CF_PARSER("IP", NULL, ipaccess_cf_ip, 1),
+    CF_END
+  }
+};
+
 int
-ipaccess_check(struct ipaccess_list *l, u32 ip)
+ipaccess_check(clist *l, u32 ip)
 {
-  struct ipaccess_entry *a;
-
-  DO_FOR_ALL(a, l->l)
+  CLIST_FOR_EACH(struct ipaccess_entry *, a, *l)
     if (! ((ip ^ a->addr) & a->mask))
       return a->allow;
   return 0;
 }
+
+#ifdef TEST
+
+#include <stdio.h>
+
+static clist t;
+
+static struct cf_section test_cf = {
+  CF_ITEMS {
+    CF_LIST("A", &t, &ipaccess_cf),
+    CF_END
+  }
+};
+
+int main(int argc, char **argv)
+{
+  cf_declare_section("T", &test_cf, 0);
+  if (cf_get_opt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1)
+    die("Invalid arguments");
+
+  byte buf[256];
+  while (fgets(buf, sizeof(buf), stdin))
+    {
+      byte *c = strchr(buf, '\n');
+      if (c)
+       *c = 0;
+      u32 ip;
+      if (cf_parse_ip(buf, &ip))
+       puts("Invalid IP address");
+      else if (ipaccess_check(&t, ip))
+       puts("Allowed");
+      else
+       puts("Denied");
+    }
+  return 0;
+}
+
+#endif
index aedb15877db744578b698ef0e55e8276ee4fc62d..8e003bdc28e59cdc6e900f5c0acfe4b980a84544 100644 (file)
@@ -1,14 +1,24 @@
 /*
  *     UCW Library -- IP address access lists
  *
- *     (c) 1997--2001 Martin Mares <mj@ucw.cz>
+ *     (c) 1997--2006 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
  */
 
-struct ipaccess_list;
+#ifndef _UCW_IPACCESS_H
+#define _UCW_IPACCESS_H
 
-struct ipaccess_list *ipaccess_init(void);
-byte *ipaccess_parse(struct ipaccess_list *l, byte *c, int is_allow);
-int ipaccess_check(struct ipaccess_list *l, u32 ip);
+#include "lib/clists.h"
+
+extern struct cf_section ipaccess_cf;
+int ipaccess_check(clist *l, u32 ip);
+
+/* FIXME: Hacks to make older modules compile */
+struct ipaccess_list { };
+#define ipaccess_init() NULL
+#define ipaccess_parse(x,y,z) NULL
+#define ipaccess_check(x,y) 0
+
+#endif