X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=secnet.git;a=blobdiff_plain;f=ipaddr.c;h=4b5b48aa43d0cf3b6f889ebd049cced818638557;hp=7dd0476cdd86faf92b260a1a701e5565137a8a4f;hb=b3877445fa32f46d70057212cb38347ae1bf4955;hpb=fe5e9cc422cd72526ccfceffbc7e5af8ac83b407 diff --git a/ipaddr.c b/ipaddr.c index 7dd0476..4b5b48a 100644 --- a/ipaddr.c +++ b/ipaddr.c @@ -2,8 +2,12 @@ inspired by the 'ipaddr.py' library from Cendio Systems AB. */ #include "secnet.h" +#include +#include #include +#include #include "ipaddr.h" +#include "util.h" #define DEFAULT_ALLOC 2 #define EXTEND_ALLOC_BY 4 @@ -11,10 +15,10 @@ 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; } @@ -24,26 +28,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; @@ -54,10 +55,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; } @@ -70,7 +71,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; il; i++) { @@ -94,7 +95,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; ientries; i++) { @@ -107,19 +108,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; } @@ -130,12 +127,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; @@ -155,7 +151,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); } @@ -166,7 +162,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; @@ -214,7 +210,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; @@ -253,7 +250,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; il; i++) { @@ -284,8 +281,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; il; i++) { @@ -316,13 +313,27 @@ struct subnet_list *ipset_to_subnet_list(struct ipset *is) return r; } +#define IPADDR_NBUFS_SHIFT 4 +#define IPADDR_NBUFS (1 << IPADDR_NBUFS_SHIFT) +#define IPADDR_BUFLEN 20 + +static char *ipaddr_getbuf(void) +{ + static int ipaddr_bufnum; + static char ipaddr_bufs[IPADDR_NBUFS][IPADDR_BUFLEN]; + + ipaddr_bufnum++; + ipaddr_bufnum &= IPADDR_NBUFS-1; + return ipaddr_bufs[ipaddr_bufnum]; +} + /* 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; @@ -337,7 +348,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; @@ -351,7 +362,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; @@ -397,10 +408,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) {