1*13885a66Sdarrenr /* $NetBSD: genmask.c,v 1.2 2012/07/22 14:27:36 darrenr Exp $ */
2bc4097aaSchristos
3bc4097aaSchristos /*
4c9d5dc6cSdarrenr * Copyright (C) 2012 by Darren Reed.
5bc4097aaSchristos *
6bc4097aaSchristos * See the IPFILTER.LICENCE file for details on licencing.
7bc4097aaSchristos *
8*13885a66Sdarrenr * Id: genmask.c,v 1.1.1.2 2012/07/22 13:44:38 darrenr Exp $
9bc4097aaSchristos */
10bc4097aaSchristos
11bc4097aaSchristos #include "ipf.h"
12bc4097aaSchristos
13bc4097aaSchristos
genmask(family,msk,mskp)14bc4097aaSchristos int genmask(family, msk, mskp)
15bc4097aaSchristos int family;
16bc4097aaSchristos char *msk;
17bc4097aaSchristos i6addr_t *mskp;
18bc4097aaSchristos {
19bc4097aaSchristos char *endptr = 0L;
20bc4097aaSchristos u_32_t addr;
21bc4097aaSchristos int bits;
22bc4097aaSchristos
23bc4097aaSchristos if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) {
24bc4097aaSchristos /* possibly of the form xxx.xxx.xxx.xxx
25bc4097aaSchristos * or 0xYYYYYYYY */
26bc4097aaSchristos switch (family)
27bc4097aaSchristos {
28bc4097aaSchristos #ifdef USE_INET6
29bc4097aaSchristos case AF_INET6 :
30bc4097aaSchristos if (inet_pton(AF_INET6, msk, &mskp->in4) != 1)
31bc4097aaSchristos return -1;
32bc4097aaSchristos break;
33bc4097aaSchristos #endif
34bc4097aaSchristos case AF_INET :
35bc4097aaSchristos if (inet_aton(msk, &mskp->in4) == 0)
36bc4097aaSchristos return -1;
37bc4097aaSchristos break;
38bc4097aaSchristos default :
39bc4097aaSchristos return -1;
40bc4097aaSchristos /*NOTREACHED*/
41bc4097aaSchristos }
42bc4097aaSchristos } else {
43bc4097aaSchristos /*
44bc4097aaSchristos * set x most significant bits
45bc4097aaSchristos */
46bc4097aaSchristos bits = (int)strtol(msk, &endptr, 0);
47bc4097aaSchristos
48bc4097aaSchristos switch (family)
49bc4097aaSchristos {
50bc4097aaSchristos case AF_INET6 :
51bc4097aaSchristos if ((*endptr != '\0') || (bits < 0) || (bits > 128))
52bc4097aaSchristos return -1;
53bc4097aaSchristos fill6bits(bits, mskp->i6);
54bc4097aaSchristos break;
55bc4097aaSchristos case AF_INET :
56bc4097aaSchristos if (*endptr != '\0' || bits > 32 || bits < 0)
57bc4097aaSchristos return -1;
58bc4097aaSchristos if (bits == 0)
59bc4097aaSchristos addr = 0;
60bc4097aaSchristos else
61bc4097aaSchristos addr = htonl(0xffffffff << (32 - bits));
62bc4097aaSchristos mskp->in4.s_addr = addr;
63bc4097aaSchristos break;
64bc4097aaSchristos default :
65bc4097aaSchristos return -1;
66bc4097aaSchristos /*NOTREACHED*/
67bc4097aaSchristos }
68bc4097aaSchristos }
69bc4097aaSchristos return 0;
70bc4097aaSchristos }
71