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