1*f52ace7aSdarrenr /* $NetBSD: alist_new.c,v 1.2 2012/07/22 14:27:36 darrenr Exp $ */
226945a25Schristos
326945a25Schristos /*
4c50c2f6fSdarrenr * Copyright (C) 2012 by Darren Reed.
526945a25Schristos *
626945a25Schristos * See the IPFILTER.LICENCE file for details on licencing.
726945a25Schristos *
8*f52ace7aSdarrenr * Id: alist_new.c,v 1.1.1.2 2012/07/22 13:44:38 darrenr Exp $
926945a25Schristos */
1026945a25Schristos
1126945a25Schristos #include "ipf.h"
1226945a25Schristos #include <ctype.h>
1326945a25Schristos
1426945a25Schristos alist_t *
alist_new(int family,char * host)1526945a25Schristos alist_new(int family, char *host)
1626945a25Schristos {
1726945a25Schristos int a, b, c, d, bits;
1826945a25Schristos char *slash;
1926945a25Schristos alist_t *al;
2026945a25Schristos u_int mask;
2126945a25Schristos
2226945a25Schristos if (family == AF_UNSPEC) {
2326945a25Schristos if (strchr(host, ':') != NULL)
2426945a25Schristos family = AF_INET6;
2526945a25Schristos else
2626945a25Schristos family = AF_INET;
2726945a25Schristos }
2826945a25Schristos if (family != AF_INET && family != AF_INET6)
2926945a25Schristos return NULL;
3026945a25Schristos
3126945a25Schristos al = calloc(1, sizeof(*al));
3226945a25Schristos if (al == NULL) {
3326945a25Schristos fprintf(stderr, "alist_new out of memory\n");
3426945a25Schristos return NULL;
3526945a25Schristos }
3626945a25Schristos
3726945a25Schristos while (ISSPACE(*host))
3826945a25Schristos host++;
3926945a25Schristos
4026945a25Schristos if (*host == '!') {
4126945a25Schristos al->al_not = 1;
4226945a25Schristos host++;
4326945a25Schristos while (ISSPACE(*host))
4426945a25Schristos host++;
4526945a25Schristos }
4626945a25Schristos
4726945a25Schristos bits = -1;
4826945a25Schristos slash = strchr(host, '/');
4926945a25Schristos if (slash != NULL) {
5026945a25Schristos *slash = '\0';
5126945a25Schristos bits = atoi(slash + 1);
5226945a25Schristos }
5326945a25Schristos
5426945a25Schristos if (family == AF_INET) {
5526945a25Schristos if (bits > 32)
5626945a25Schristos goto bad;
5726945a25Schristos
5826945a25Schristos a = b = c = d = -1;
5926945a25Schristos sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d);
6026945a25Schristos
6126945a25Schristos if (bits > 0 && bits < 33) {
6226945a25Schristos mask = 0xffffffff << (32 - bits);
6326945a25Schristos } else if (b == -1) {
6426945a25Schristos mask = 0xff000000;
6526945a25Schristos b = c = d = 0;
6626945a25Schristos } else if (c == -1) {
6726945a25Schristos mask = 0xffff0000;
6826945a25Schristos c = d = 0;
6926945a25Schristos } else if (d == -1) {
7026945a25Schristos mask = 0xffffff00;
7126945a25Schristos d = 0;
7226945a25Schristos } else {
7326945a25Schristos mask = 0xffffffff;
7426945a25Schristos }
7526945a25Schristos al->al_mask = htonl(mask);
7626945a25Schristos } else {
7726945a25Schristos if (bits > 128)
7826945a25Schristos goto bad;
7926945a25Schristos fill6bits(bits, al->al_i6mask.i6);
8026945a25Schristos }
8126945a25Schristos
8226945a25Schristos if (gethost(family, host, &al->al_i6addr) == -1) {
8326945a25Schristos if (slash != NULL)
8426945a25Schristos *slash = '/';
8526945a25Schristos fprintf(stderr, "Cannot parse hostname\n");
8626945a25Schristos goto bad;
8726945a25Schristos }
8826945a25Schristos al->al_family = family;
8926945a25Schristos if (slash != NULL)
9026945a25Schristos *slash = '/';
9126945a25Schristos return al;
9226945a25Schristos bad:
9326945a25Schristos free(al);
9426945a25Schristos return NULL;
9526945a25Schristos }
96