1 /* 2 * Copyright (C) 2012 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * $Id: alist_new.c,v 1.5.2.2 2012/07/22 08:04:24 darren_r Exp $ 7 */ 8 9 #include "ipf.h" 10 #include <ctype.h> 11 12 alist_t * 13 alist_new(int family, char *host) 14 { 15 int a, b, c, d, bits; 16 char *slash; 17 alist_t *al; 18 u_int mask; 19 20 if (family == AF_UNSPEC) { 21 if (strchr(host, ':') != NULL) 22 family = AF_INET6; 23 else 24 family = AF_INET; 25 } 26 if (family != AF_INET && family != AF_INET6) 27 return (NULL); 28 29 al = calloc(1, sizeof(*al)); 30 if (al == NULL) { 31 fprintf(stderr, "alist_new out of memory\n"); 32 return (NULL); 33 } 34 35 while (ISSPACE(*host)) 36 host++; 37 38 if (*host == '!') { 39 al->al_not = 1; 40 host++; 41 while (ISSPACE(*host)) 42 host++; 43 } 44 45 bits = -1; 46 slash = strchr(host, '/'); 47 if (slash != NULL) { 48 *slash = '\0'; 49 bits = atoi(slash + 1); 50 } 51 52 if (family == AF_INET) { 53 if (bits > 32) 54 goto bad; 55 56 a = b = c = d = -1; 57 sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d); 58 59 if (bits > 0 && bits < 33) { 60 mask = 0xffffffff << (32 - bits); 61 } else if (b == -1) { 62 mask = 0xff000000; 63 b = c = d = 0; 64 } else if (c == -1) { 65 mask = 0xffff0000; 66 c = d = 0; 67 } else if (d == -1) { 68 mask = 0xffffff00; 69 d = 0; 70 } else { 71 mask = 0xffffffff; 72 } 73 al->al_mask = htonl(mask); 74 } else { 75 if (bits > 128) 76 goto bad; 77 fill6bits(bits, al->al_i6mask.i6); 78 } 79 80 if (gethost(family, host, &al->al_i6addr) == -1) { 81 if (slash != NULL) 82 *slash = '/'; 83 fprintf(stderr, "Cannot parse hostname\n"); 84 goto bad; 85 } 86 al->al_family = family; 87 if (slash != NULL) 88 *slash = '/'; 89 return (al); 90 bad: 91 free(al); 92 return (NULL); 93 } 94