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