static struct in_addr *parse_ipmask(const char *mask) { static struct in_addr maskaddr; struct in_addr *addrp; unsigned int bits; if (mask == NULL) { /* no mask at all defaults to 32 bits */ maskaddr.s_addr = 0xFFFFFFFF; return &maskaddr; } if ((addrp = xtables_numeric_to_ipmask(mask)) != NULL) /* dotted_to_addr already returns a network byte order addr */ return addrp; if (!xtables_strtoui(mask, NULL, &bits, 0, 32)) xt_params->exit_err(PARAMETER_PROBLEM, "invalid mask `%s' specified", mask); if (bits != 0) { maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); return &maskaddr; } maskaddr.s_addr = 0U; return &maskaddr; }
/* Parses network address */ static void parse_to(char *arg, struct nf_nat_range *range) { char *slash; const struct in_addr *ip; u_int32_t netmask; unsigned int bits; range->flags |= IP_NAT_RANGE_MAP_IPS; slash = strchr(arg, '/'); if (slash) *slash = '\0'; ip = xtables_numeric_to_ipaddr(arg); if (!ip) xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n", arg); range->min_ip = ip->s_addr; if (slash) { if (strchr(slash+1, '.')) { ip = xtables_numeric_to_ipmask(slash+1); if (!ip) xtables_error(PARAMETER_PROBLEM, "Bad netmask \"%s\"\n", slash+1); netmask = ip->s_addr; } else { if (!xtables_strtoui(slash+1, NULL, &bits, 0, 32)) xtables_error(PARAMETER_PROBLEM, "Bad netmask \"%s\"\n", slash+1); netmask = bits2netmask(bits); } /* Don't allow /0 (/1 is probably insane, too) */ if (netmask == 0) xtables_error(PARAMETER_PROBLEM, "Netmask needed\n"); } else netmask = ~0; if (range->min_ip & ~netmask) { if (slash) *slash = '/'; xtables_error(PARAMETER_PROBLEM, "Bad network address \"%s\"\n", arg); } range->max_ip = range->min_ip | ~netmask; }