xref: /freebsd/sbin/ipf/common/genmask.c (revision 2ac057dd33e85e3e4ca1095f80bdc00974a1132c)
141edb306SCy Schubert /*
241edb306SCy Schubert  * Copyright (C) 2012 by Darren Reed.
341edb306SCy Schubert  *
441edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
541edb306SCy Schubert  *
641edb306SCy Schubert  * $Id$
741edb306SCy Schubert  */
841edb306SCy Schubert 
941edb306SCy Schubert #include "ipf.h"
1041edb306SCy Schubert 
1141edb306SCy Schubert 
12*2ac057ddSJohn Baldwin int
genmask(int family,char * msk,i6addr_t * mskp)13*2ac057ddSJohn Baldwin genmask(int family, char *msk, i6addr_t *mskp)
1441edb306SCy Schubert {
1541edb306SCy Schubert 	char *endptr = 0L;
1641edb306SCy Schubert 	u_32_t addr;
1741edb306SCy Schubert 	int bits;
1841edb306SCy Schubert 
1941edb306SCy Schubert 	if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) {
2041edb306SCy Schubert 		/* possibly of the form xxx.xxx.xxx.xxx
2141edb306SCy Schubert 		 * or 0xYYYYYYYY */
2241edb306SCy Schubert 		switch (family)
2341edb306SCy Schubert 		{
2441edb306SCy Schubert #ifdef USE_INET6
2541edb306SCy Schubert 		case AF_INET6 :
2641edb306SCy Schubert 			if (inet_pton(AF_INET6, msk, &mskp->in4) != 1)
272582ae57SCy Schubert 				return (-1);
2841edb306SCy Schubert 			break;
2941edb306SCy Schubert #endif
3041edb306SCy Schubert 		case AF_INET :
3141edb306SCy Schubert 			if (inet_aton(msk, &mskp->in4) == 0)
322582ae57SCy Schubert 				return (-1);
3341edb306SCy Schubert 			break;
3441edb306SCy Schubert 		default :
352582ae57SCy Schubert 			return (-1);
3641edb306SCy Schubert 			/*NOTREACHED*/
3741edb306SCy Schubert 		}
3841edb306SCy Schubert 	} else {
3941edb306SCy Schubert 		/*
4041edb306SCy Schubert 		 * set x most significant bits
4141edb306SCy Schubert 		 */
4241edb306SCy Schubert 		bits = (int)strtol(msk, &endptr, 0);
4341edb306SCy Schubert 
4441edb306SCy Schubert 		switch (family)
4541edb306SCy Schubert 		{
4641edb306SCy Schubert 		case AF_INET6 :
4741edb306SCy Schubert 			if ((*endptr != '\0') || (bits < 0) || (bits > 128))
482582ae57SCy Schubert 				return (-1);
4941edb306SCy Schubert 			fill6bits(bits, mskp->i6);
5041edb306SCy Schubert 			break;
5141edb306SCy Schubert 		case AF_INET :
5241edb306SCy Schubert 			if (*endptr != '\0' || bits > 32 || bits < 0)
532582ae57SCy Schubert 				return (-1);
5441edb306SCy Schubert 			if (bits == 0)
5541edb306SCy Schubert 				addr = 0;
5641edb306SCy Schubert 			else
5741edb306SCy Schubert 				addr = htonl(0xffffffff << (32 - bits));
5841edb306SCy Schubert 			mskp->in4.s_addr = addr;
5941edb306SCy Schubert 			break;
6041edb306SCy Schubert 		default :
612582ae57SCy Schubert 			return (-1);
6241edb306SCy Schubert 			/*NOTREACHED*/
6341edb306SCy Schubert 		}
6441edb306SCy Schubert 	}
652582ae57SCy Schubert 	return (0);
6641edb306SCy Schubert }
67