diff options
Diffstat (limited to 'lib/alist_new.c')
-rw-r--r-- | lib/alist_new.c | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/lib/alist_new.c b/lib/alist_new.c index 50a4275e7d540..73bc03073990f 100644 --- a/lib/alist_new.c +++ b/lib/alist_new.c @@ -1,20 +1,30 @@ /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: alist_new.c,v 1.1.2.3 2007/06/06 08:05:33 darrenr Exp $ + * $Id: alist_new.c,v 1.5.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" +#include <ctype.h> -alist_t * -alist_new(int v, char *host) +alist_t * +alist_new(int family, char *host) { int a, b, c, d, bits; - char *slash; - alist_t *al; - u_int mask; + char *slash; + alist_t *al; + u_int mask; + + if (family == AF_UNSPEC) { + if (strchr(host, ':') != NULL) + family = AF_INET6; + else + family = AF_INET; + } + if (family != AF_INET && family != AF_INET6) + return NULL; al = calloc(1, sizeof(*al)); if (al == NULL) { @@ -22,45 +32,62 @@ alist_new(int v, char *host) return NULL; } - bits = -1; + while (ISSPACE(*host)) + host++; + + if (*host == '!') { + al->al_not = 1; + host++; + while (ISSPACE(*host)) + host++; + } + + bits = -1; slash = strchr(host, '/'); if (slash != NULL) { *slash = '\0'; bits = atoi(slash + 1); } - a = b = c = d = -1; - sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d); + if (family == AF_INET) { + if (bits > 32) + goto bad; - if (bits > 0 && bits < 33) { - mask = 0xffffffff << (32 - bits); - } else if (b == -1) { - mask = 0xff000000; - b = c = d = 0; - } else if (c == -1) { - mask = 0xffff0000; - c = d = 0; - } else if (d == -1) { - mask = 0xffffff00; - d = 0; - } else { - mask = 0xffffffff; - } + a = b = c = d = -1; + sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d); - if (*host == '!') { - al->al_not = 1; - host++; + if (bits > 0 && bits < 33) { + mask = 0xffffffff << (32 - bits); + } else if (b == -1) { + mask = 0xff000000; + b = c = d = 0; + } else if (c == -1) { + mask = 0xffff0000; + c = d = 0; + } else if (d == -1) { + mask = 0xffffff00; + d = 0; + } else { + mask = 0xffffffff; + } + al->al_mask = htonl(mask); + } else { + if (bits > 128) + goto bad; + fill6bits(bits, al->al_i6mask.i6); } - if (gethost(host, &al->al_addr) == -1) { + if (gethost(family, host, &al->al_i6addr) == -1) { if (slash != NULL) *slash = '/'; fprintf(stderr, "Cannot parse hostname\n"); - free(al); - return NULL; + goto bad; } - al->al_mask = htonl(mask); + al->al_family = family; if (slash != NULL) *slash = '/'; return al; +bad: + free(al); + return NULL; } |