chiark / gitweb /
Makefiles: Use Final.sd.mk to implementing RECHECK_RM
[secnet.git] / ipaddr.c
index d8661dafcd4535560d3b83988096ad293ac4a763..d12af55329eca6bf66a7dc50004d34683271df69 100644 (file)
--- a/ipaddr.c
+++ b/ipaddr.c
@@ -1,10 +1,31 @@
 /* The 'ipset' data structure and related algorithms in this file were
    inspired by the 'ipaddr.py' library from Cendio Systems AB. */
+/*
+ * This file is part of secnet.
+ * See README for full list of copyright holders.
+ *
+ * secnet is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * secnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with secnet; if not, see
+ * https://www.gnu.org/licenses/gpl.html.
+ */
 
 #include "secnet.h"
+#include <limits.h>
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 #include "ipaddr.h"
+#include "util.h"
 
 #define DEFAULT_ALLOC 2
 #define EXTEND_ALLOC_BY 4
 struct subnet_list *subnet_list_new(void)
 {
     struct subnet_list *r;
-    r=safe_malloc(sizeof(*r),"subnet_list_new:list");
+    NEW(r);
     r->entries=0;
     r->alloc=DEFAULT_ALLOC;
-    r->list=safe_malloc(sizeof(*r->list)*r->alloc,"subnet_list_new:data");
+    NEW_ARY(r->list,r->alloc);
     return r;
 }
 
@@ -25,26 +46,23 @@ void subnet_list_free(struct subnet_list *a)
     free(a);
 }
 
-static void subnet_list_set_len(struct subnet_list *a, uint32_t l)
+static void subnet_list_set_len(struct subnet_list *a, int32_t l)
 {
-    struct subnet *nd;
-    uint32_t na;
+    int32_t na;
 
     if (l>a->alloc) {
+       assert(a->alloc < INT_MAX-EXTEND_ALLOC_BY);
        na=a->alloc+EXTEND_ALLOC_BY;
-       nd=realloc(a->list,sizeof(*nd)*na);
-       if (!nd) {
-           fatal_perror("subnet_list_set_len: realloc");
-       }
+       REALLOC_ARY(a->list,na);
        a->alloc=na;
-       a->list=nd;
     }
     a->entries=l;
 }
 
-void subnet_list_append(struct subnet_list *a, uint32_t prefix, uint32_t len)
+void subnet_list_append(struct subnet_list *a, uint32_t prefix, int len)
 {
     struct subnet *sn;
+    assert(a->entries < INT_MAX);
     subnet_list_set_len(a,a->entries+1);
     sn=&a->list[a->entries-1];
     sn->prefix=prefix;
@@ -55,10 +73,10 @@ void subnet_list_append(struct subnet_list *a, uint32_t prefix, uint32_t len)
 struct ipset *ipset_new(void)
 {
     struct ipset *r;
-    r=safe_malloc(sizeof(*r),"ipset_new:set");
+    NEW(r);
     r->l=0;
     r->a=DEFAULT_ALLOC;
-    r->d=safe_malloc(sizeof(*r->d)*r->a,"ipset_new:data");
+    NEW_ARY(r->d,r->a);
     return r;
 }
 
@@ -71,7 +89,7 @@ void ipset_free(struct ipset *a)
 #ifdef DEBUG
 static void ipset_dump(struct ipset *a, string_t name)
 {
-    uint32_t i;
+    int32_t i;
 
     printf("%s: ",name);
     for (i=0; i<a->l; i++) {
@@ -95,7 +113,7 @@ struct ipset *ipset_from_subnet(struct subnet s)
 struct ipset *ipset_from_subnet_list(struct subnet_list *l)
 {
     struct ipset *r, *a, *b;
-    uint32_t i;
+    int32_t i;
 
     r=ipset_new();
     for (i=0; i<l->entries; i++) {
@@ -108,19 +126,15 @@ struct ipset *ipset_from_subnet_list(struct subnet_list *l)
     return r;
 }
 
-static void ipset_set_len(struct ipset *a, uint32_t l)
+static void ipset_set_len(struct ipset *a, int32_t l)
 {
-    struct iprange *nd;
-    uint32_t na;
+    int32_t na;
 
     if (l>a->a) {
+       assert(a->a < INT_MAX-EXTEND_ALLOC_BY);
        na=a->a+EXTEND_ALLOC_BY;
-       nd=realloc(a->d,sizeof(*nd)*na);
-       if (!nd) {
-           fatal_perror("ipset_set_len: realloc");
-       }
+       REALLOC_ARY(a->d,na);
        a->a=na;
-       a->d=nd;
     }
     a->l=l;
 }
@@ -131,12 +145,11 @@ static void ipset_append_range(struct ipset *a, struct iprange r)
     a->d[a->l-1]=r;
 }
 
-#define max(a,b) (a>b?a:b)
 struct ipset *ipset_union(struct ipset *a, struct ipset *b)
 {
     struct ipset *c;
     struct iprange r;
-    uint32_t ia,ib;
+    int32_t ia,ib;
 
     c=ipset_new();
     ia=0; ib=0;
@@ -156,7 +169,7 @@ struct ipset *ipset_union(struct ipset *a, struct ipset *b)
            ipset_append_range(c,r);
        else if (r.a <= c->d[c->l-1].b+1)
            /* Extends (or is consumed by) the last range */
-           c->d[c->l-1].b=max(c->d[c->l-1].b, r.b);
+           c->d[c->l-1].b=MAX(c->d[c->l-1].b, r.b);
        else
            ipset_append_range(c,r);
     }
@@ -167,7 +180,7 @@ struct ipset *ipset_intersection(struct ipset *a, struct ipset *b)
 {
     struct ipset *r;
     struct iprange ra, rb;
-    uint32_t ia,ib;
+    int32_t ia,ib;
 
     r=ipset_new();
     ia=0; ib=0;
@@ -215,7 +228,8 @@ struct ipset *ipset_complement(struct ipset *a)
     struct ipset *r;
     struct iprange n;
     int64_t pre;
-    uint32_t i,lo,hi;
+    int32_t i;
+    uint32_t lo,hi;
 
     r=ipset_new();
     pre=-1;
@@ -254,7 +268,7 @@ bool_t ipset_is_empty(struct ipset *a)
 
 bool_t ipset_contains_addr(struct ipset *a, uint32_t addr)
 {
-    uint32_t i;
+    int32_t i;
     struct iprange r;
 
     for (i=0; i<a->l; i++) {
@@ -285,8 +299,8 @@ struct subnet_list *ipset_to_subnet_list(struct ipset *is)
 {
     struct subnet_list *r;
     int64_t a,b,lobit,himask,lomask;
-    int32_t bits;
-    uint32_t i;
+    int bits;
+    int32_t i;
 
     r=subnet_list_new();
     for (i=0; i<is->l; i++) {
@@ -317,13 +331,21 @@ struct subnet_list *ipset_to_subnet_list(struct ipset *is)
     return r;
 }
 
+#define IPADDR_BUFLEN 20
+
+static char *ipaddr_getbuf(void)
+{
+    SBUF_DEFINE(16, IPADDR_BUFLEN);
+    return SBUF;
+}
+
 /* The string buffer must be at least 16 bytes long */
 string_t ipaddr_to_string(uint32_t addr)
 {
     uint8_t a,b,c,d;
     string_t s;
 
-    s=safe_malloc(16,"ipaddr_to_string");
+    s=ipaddr_getbuf();
     a=addr>>24;
     b=addr>>16;
     c=addr>>8;
@@ -338,7 +360,7 @@ string_t subnet_to_string(struct subnet sn)
     uint8_t a,b,c,d;
     string_t s;
 
-    s=safe_malloc(19,"subnet_to_string");
+    s=ipaddr_getbuf();
     a=addr>>24;
     b=addr>>16;
     c=addr>>8;
@@ -352,7 +374,7 @@ static struct subnet string_item_to_subnet(item_t *i, cstring_t desc,
 {
     struct subnet s;
     uint32_t a, b, c, d, n;
-    uint32_t match;
+    int match;
     cstring_t in;
 
     *invert=False;
@@ -398,10 +420,10 @@ static struct subnet string_item_to_subnet(item_t *i, cstring_t desc,
     return s;
 }
 
-uint32_t string_item_to_ipaddr(item_t *i, cstring_t desc)
+uint32_t string_item_to_ipaddr(const item_t *i, cstring_t desc)
 {
     uint32_t a, b, c, d;
-    uint32_t match;
+    int match;
 
     /* i is not guaranteed to be a string */
     if (i->type!=t_string) {