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