xref: /netbsd-src/external/bsd/ipf/dist/lib/genmask.c (revision 13885a665959c62f13a82b3caedf986eaa17aa31)
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