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