1170263Sdarrenr/* 2255332Scy * Copyright (C) 2012 by Darren Reed. 3170263Sdarrenr * 4170263Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 5170263Sdarrenr * 6255332Scy * $Id: alist_new.c,v 1.5.2.2 2012/07/22 08:04:24 darren_r Exp $ 7170263Sdarrenr */ 8170263Sdarrenr 9170263Sdarrenr#include "ipf.h" 10255332Scy#include <ctype.h> 11170263Sdarrenr 12255332Scyalist_t * 13255332Scyalist_new(int family, char *host) 14170263Sdarrenr{ 15170263Sdarrenr int a, b, c, d, bits; 16255332Scy char *slash; 17255332Scy alist_t *al; 18255332Scy u_int mask; 19170263Sdarrenr 20255332Scy if (family == AF_UNSPEC) { 21255332Scy if (strchr(host, ':') != NULL) 22255332Scy family = AF_INET6; 23255332Scy else 24255332Scy family = AF_INET; 25255332Scy } 26255332Scy if (family != AF_INET && family != AF_INET6) 27255332Scy return NULL; 28255332Scy 29170263Sdarrenr al = calloc(1, sizeof(*al)); 30170263Sdarrenr if (al == NULL) { 31170263Sdarrenr fprintf(stderr, "alist_new out of memory\n"); 32170263Sdarrenr return NULL; 33170263Sdarrenr } 34170263Sdarrenr 35255332Scy while (ISSPACE(*host)) 36255332Scy host++; 37255332Scy 38255332Scy if (*host == '!') { 39255332Scy al->al_not = 1; 40255332Scy host++; 41255332Scy while (ISSPACE(*host)) 42255332Scy host++; 43255332Scy } 44255332Scy 45255332Scy bits = -1; 46170263Sdarrenr slash = strchr(host, '/'); 47170263Sdarrenr if (slash != NULL) { 48170263Sdarrenr *slash = '\0'; 49170263Sdarrenr bits = atoi(slash + 1); 50170263Sdarrenr } 51170263Sdarrenr 52255332Scy if (family == AF_INET) { 53255332Scy if (bits > 32) 54255332Scy goto bad; 55170263Sdarrenr 56255332Scy a = b = c = d = -1; 57255332Scy sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d); 58255332Scy 59255332Scy if (bits > 0 && bits < 33) { 60255332Scy mask = 0xffffffff << (32 - bits); 61255332Scy } else if (b == -1) { 62255332Scy mask = 0xff000000; 63255332Scy b = c = d = 0; 64255332Scy } else if (c == -1) { 65255332Scy mask = 0xffff0000; 66255332Scy c = d = 0; 67255332Scy } else if (d == -1) { 68255332Scy mask = 0xffffff00; 69255332Scy d = 0; 70255332Scy } else { 71255332Scy mask = 0xffffffff; 72255332Scy } 73255332Scy al->al_mask = htonl(mask); 74170263Sdarrenr } else { 75255332Scy if (bits > 128) 76255332Scy goto bad; 77255332Scy fill6bits(bits, al->al_i6mask.i6); 78170263Sdarrenr } 79170263Sdarrenr 80255332Scy if (gethost(family, host, &al->al_i6addr) == -1) { 81172771Sdarrenr if (slash != NULL) 82172771Sdarrenr *slash = '/'; 83170263Sdarrenr fprintf(stderr, "Cannot parse hostname\n"); 84255332Scy goto bad; 85170263Sdarrenr } 86255332Scy al->al_family = family; 87172771Sdarrenr if (slash != NULL) 88172771Sdarrenr *slash = '/'; 89170263Sdarrenr return al; 90255332Scybad: 91255332Scy free(al); 92255332Scy return NULL; 93170263Sdarrenr} 94