/* Parses ports */
static void
parse_ports(const char *arg, struct nf_nat_multi_range *mr)
{
	char *end;
	unsigned int port, maxport;

	mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;

	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX))
		xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);

	switch (*end) {
	case '\0':
		mr->range[0].min.tcp.port
			= mr->range[0].max.tcp.port
			= htons(port);
		return;
	case '-':
		if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX))
			break;

		if (maxport < port)
			break;

		mr->range[0].min.tcp.port = htons(port);
		mr->range[0].max.tcp.port = htons(maxport);
		return;
	default:
		break;
	}
	xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
}
Beispiel #2
0
static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
                         const void *entry, struct xt_entry_match **match)
{
	struct xt_mark_mtinfo1 *info = (void *)(*match)->data;
	unsigned int mark, mask = UINT32_MAX;
	char *end;

	switch (c) {
	case '1': /* --mark */
		xtables_param_act(XTF_ONLY_ONCE, "mark", "--mark", *flags & F_MARK);
		if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
		if (*end == '/')
			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
				xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
		if (*end != '\0')
			xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);

		if (invert)
			info->invert = true;
		info->mark = mark;
		info->mask = mask;
		*flags    |= F_MARK;
		return true;
	}
	return false;
}
/* Parses ports */
static void
parse_ports(const char *arg, struct nf_nat_range *range)
{
	char *end = "";
	unsigned int port, maxport;

	range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;

	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) &&
	    (port = xtables_service_to_port(arg, NULL)) == (unsigned)-1)
		xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);

	switch (*end) {
	case '\0':
		range->min_proto.tcp.port
			= range->max_proto.tcp.port
			= htons(port);
		return;
	case '-':
		if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) &&
		    (maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1)
			break;

		if (maxport < port)
			break;

		range->min_proto.tcp.port = htons(port);
		range->max_proto.tcp.port = htons(maxport);
		return;
	default:
		break;
	}
	xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
}
Beispiel #4
0
static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
                         const void *entry, struct xt_entry_target **target)
{
	struct xt_mark_tginfo2 *info = (void *)(*target)->data;
	unsigned int value, mask = UINT32_MAX;
	char *end;

	switch (c) {
	case 'X': /* --set-xmark */
	case '=': /* --set-mark */
		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
		xtables_param_act(XTF_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert);
		if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
		if (*end == '/')
			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
				xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
		if (*end != '\0')
			xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
		info->mark = value;
		info->mask = mask;

		if (c == '=')
			info->mask = value | mask;
		break;

	case '&': /* --and-mark */
		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
		xtables_param_act(XTF_NO_INVERT, "MARK", "--and-mark", invert);
		if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "MARK", "--and-mark", optarg);
		info->mark = 0;
		info->mask = ~mask;
		break;

	case '|': /* --or-mark */
		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
		xtables_param_act(XTF_NO_INVERT, "MARK", "--or-mark", invert);
		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "MARK", "--or-mark", optarg);
		info->mark = value;
		info->mask = value;
		break;

	case '^': /* --xor-mark */
		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
		xtables_param_act(XTF_NO_INVERT, "MARK", "--xor-mark", invert);
		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "MARK", "--xor-mark", optarg);
		info->mark = value;
		info->mask = 0;
		break;

	default:
		return false;
	}

	*flags |= F_MARK;
	return true;
}
Beispiel #5
0
static int
statistic_parse(int c, char **argv, int invert, unsigned int *flags,
                const void *entry, struct xt_entry_match **match)
{
	struct xt_statistic_info *info = (void *)(*match)->data;
	unsigned int val;
	double prob;

	if (invert)
		info->flags |= XT_STATISTIC_INVERT;

	switch (c) {
	case '1':
		if (*flags & 0x1)
			xtables_error(PARAMETER_PROBLEM, "double --mode");
		if (!strcmp(optarg, "random"))
			info->mode = XT_STATISTIC_MODE_RANDOM;
		else if (!strcmp(optarg, "nth"))
			info->mode = XT_STATISTIC_MODE_NTH;
		else
			xtables_error(PARAMETER_PROBLEM, "Bad mode \"%s\"", optarg);
		*flags |= 0x1;
		break;
	case '2':
		if (*flags & 0x2)
			xtables_error(PARAMETER_PROBLEM, "double --probability");
		prob = atof(optarg);
		if (prob < 0 || prob > 1)
			xtables_error(PARAMETER_PROBLEM,
				   "--probability must be between 0 and 1");
		info->u.random.probability = 0x80000000 * prob;
		*flags |= 0x2;
		break;
	case '3':
		if (*flags & 0x4)
			xtables_error(PARAMETER_PROBLEM, "double --every");
		if (!xtables_strtoui(optarg, NULL, &val, 0, UINT32_MAX))
			xtables_error(PARAMETER_PROBLEM,
				   "cannot parse --every `%s'", optarg);
		info->u.nth.every = val;
		if (info->u.nth.every == 0)
			xtables_error(PARAMETER_PROBLEM, "--every cannot be 0");
		info->u.nth.every--;
		*flags |= 0x4;
		break;
	case '4':
		if (*flags & 0x8)
			xtables_error(PARAMETER_PROBLEM, "double --packet");
		if (!xtables_strtoui(optarg, NULL, &val, 0, UINT32_MAX))
			xtables_error(PARAMETER_PROBLEM,
				   "cannot parse --packet `%s'", optarg);
		info->u.nth.packet = val;
		*flags |= 0x8;
		break;
	default:
		return 0;
	}
	return 1;
}
static int ttl_parse(int c, char **argv, int invert, unsigned int *flags,
                     const void *entry, struct xt_entry_match **match)
{
	struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
	unsigned int value;

	xtables_check_inverse(optarg, &invert, &optind, 0);

	switch (c) {
		case '2':
			if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX))
				xtables_error(PARAMETER_PROBLEM,
				           "ttl: Expected value between 0 and 255");

			if (invert)
				info->mode = IPT_TTL_NE;
			else
				info->mode = IPT_TTL_EQ;

			/* is 0 allowed? */
			info->ttl = value;
			break;
		case '3':
			if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX))
				xtables_error(PARAMETER_PROBLEM,
				           "ttl: Expected value between 0 and 255");

			if (invert) 
				xtables_error(PARAMETER_PROBLEM,
						"ttl: unexpected `!'");

			info->mode = IPT_TTL_LT;
			info->ttl = value;
			break;
		case '4':
			if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX))
				xtables_error(PARAMETER_PROBLEM,
				           "ttl: Expected value between 0 and 255");

			if (invert)
				xtables_error(PARAMETER_PROBLEM,
						"ttl: unexpected `!'");

			info->mode = IPT_TTL_GT;
			info->ttl = value;
			break;
		default:
			return 0;

	}

	if (*flags) 
		xtables_error(PARAMETER_PROBLEM,
				"Can't specify TTL option twice");
	*flags = 1;

	return 1;
}
static int ipmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
                           const void *entry, struct xt_entry_target **target)
{
	struct xt_ipmark_tginfo *info = (void *)(*target)->data;
	unsigned int n;

	switch (c) {
	case '1':
		xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "addr", *flags & FL_ADDR_USED);
		xtables_param_act(XTF_NO_INVERT, "IPMARK", "addr", invert);
		if (strcmp(optarg, "src") == 0)
			info->selector = XT_IPMARK_SRC;
		else if (strcmp(optarg, "dst") == 0)
			info->selector = XT_IPMARK_DST;
		else
			xtables_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
		*flags |= FL_ADDR_USED;
		return true;

	case '2':
		xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "and-mask", *flags & FL_AND_MASK_USED);
		xtables_param_act(XTF_NO_INVERT, "IPMARK", "and-mask", invert);
		if (!xtables_strtoui(optarg, NULL, &n, 0, ~0U))
			xtables_param_act(XTF_BAD_VALUE, "IPMARK", "and-mask", optarg);
		info->andmask = n;
		*flags |= FL_AND_MASK_USED;
		return true;

	case '3':
		xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "or-mask", *flags & FL_OR_MASK_USED);
		xtables_param_act(XTF_NO_INVERT, "IPMARK", "or-mask", invert);
		if (!xtables_strtoui(optarg, NULL, &n, 0, ~0U))
			xtables_param_act(XTF_BAD_VALUE, "IPMARK", "or-mask", optarg);
		info->ormask = n;
		*flags |= FL_OR_MASK_USED;
		return true;

	case '4':
		xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "--shift", *flags & FL_SHIFT);
		xtables_param_act(XTF_NO_INVERT, "IPMARK", "--shift", invert);
		/*
		 * Anything >31 does not make sense for IPv4, but it still
		 * does the right thing.
		 */
		if (!xtables_strtoui(optarg, NULL, &n, 0, 128))
			xtables_param_act(XTF_BAD_VALUE, "IPMARK", "--shift", optarg);
		info->shift = n;
		*flags |= FL_SHIFT;
		return true;
	}

	return false;
}
Beispiel #8
0
static int length_mt_parse(int c, char **argv, int invert, unsigned int *flags,
                           const void *entry, struct xt_entry_match **match)
{
	struct xt_length_mtinfo2 *info = (void *)(*match)->data;
	unsigned int from, to;
	char *end;

	switch (c) {
	case '3': /* --layer3 */
		xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
		info->flags &= ~XT_LENGTH_LAYER_MASK;
		info->flags |= XT_LENGTH_LAYER3;
		*flags |= F_LAYER;
		return true;
	case '4': /* --layer4 */
		xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
		info->flags &= ~XT_LENGTH_LAYER_MASK;
		info->flags |= XT_LENGTH_LAYER4;
		*flags |= F_LAYER;
		return true;
	case '5': /* --layer5 */
		xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
		info->flags &= ~XT_LENGTH_LAYER_MASK;
		info->flags |= XT_LENGTH_LAYER5;
		*flags |= F_LAYER;
		return true;
	case '7': /* --layer7 */
		xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
		info->flags &= ~XT_LENGTH_LAYER_MASK;
		info->flags |= XT_LENGTH_LAYER7;
		*flags |= F_LAYER;
		return true;
	case '=': /* --length */
		xtables_param_act(XTF_ONLY_ONCE, "length", "--length", *flags & F_LENGTH);
		if (invert)
			info->flags |= XT_LENGTH_INVERT;
		if (!xtables_strtoui(optarg, &end, &from, 0, ~0U))
			xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg);
		to = from;
		if (*end == ':')
			if (!xtables_strtoui(end + 1, &end, &to, 0, ~0U))
				xtables_param_act(XTF_BAD_VALUE, "length",
				          "--length", optarg);
		if (*end != '\0')
			xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg);
		info->min = from;
		info->max = to;
		*flags |= F_LENGTH;
		return true;
	}
	return false;
}
static void 
parse_icmp(const char *icmptype, uint8_t *type, uint8_t code[])
{
	static const unsigned int limit = ARRAY_SIZE(icmp_codes);
	unsigned int match = limit;
	unsigned int i;

	for (i = 0; i < limit; i++) {
		if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype))
		    == 0) {
			if (match != limit)
				xtables_error(PARAMETER_PROBLEM,
					   "Ambiguous ICMP type `%s':"
					   " `%s' or `%s'?",
					   icmptype,
					   icmp_codes[match].name,
					   icmp_codes[i].name);
			match = i;
		}
	}

	if (match != limit) {
		*type = icmp_codes[match].type;
		code[0] = icmp_codes[match].code_min;
		code[1] = icmp_codes[match].code_max;
	} else {
		char *slash;
		char buffer[strlen(icmptype) + 1];
		unsigned int number;

		strcpy(buffer, icmptype);
		slash = strchr(buffer, '/');

		if (slash)
			*slash = '\0';

		if (!xtables_strtoui(buffer, NULL, &number, 0, UINT8_MAX))
			xtables_error(PARAMETER_PROBLEM,
				   "Invalid ICMP type `%s'\n", buffer);
		*type = number;
		if (slash) {
			if (!xtables_strtoui(slash+1, NULL, &number, 0, UINT8_MAX))
				xtables_error(PARAMETER_PROBLEM,
					   "Invalid ICMP code `%s'\n",
					   slash+1);
			code[0] = code[1] = number;
		} else {
			code[0] = 0;
			code[1] = 0xFF;
		}
	}
}
Beispiel #10
0
static int tos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
                         const void *entry, struct xt_entry_target **target)
{
	struct xt_tos_target_info *info = (void *)(*target)->data;
	struct tos_value_mask tvm;
	unsigned int bits;

	switch (c) {
	case '=': /* --set-tos */
		xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
		xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert);
		if (!tos_parse_symbolic(optarg, &tvm, 0x3F))
			xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg);
		info->tos_value = tvm.value;
		info->tos_mask  = tvm.mask;
		break;

	case '&': /* --and-tos */
		xtables_param_act(XTF_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS);
		xtables_param_act(XTF_NO_INVERT, "TOS", "--and-tos", invert);
		if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX))
			xtables_param_act(XTF_BAD_VALUE, "TOS", "--and-tos", optarg);
		info->tos_value = 0;
		info->tos_mask  = ~bits;
		break;

	case '|': /* --or-tos */
		xtables_param_act(XTF_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS);
		xtables_param_act(XTF_NO_INVERT, "TOS", "--or-tos", invert);
		if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX))
			xtables_param_act(XTF_BAD_VALUE, "TOS", "--or-tos", optarg);
		info->tos_value = bits;
		info->tos_mask  = bits;
		break;

	case '^': /* --xor-tos */
		xtables_param_act(XTF_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS);
		xtables_param_act(XTF_NO_INVERT, "TOS", "--xor-tos", invert);
		if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX))
			xtables_param_act(XTF_BAD_VALUE, "TOS", "--xor-tos", optarg);
		info->tos_value = bits;
		info->tos_mask  = 0;
		break;

	default:
		return false;
	}

	*flags |= FLAG_TOS;
	return true;
}
Beispiel #11
0
static int psd_mt_parse(int c, char **argv, int invert, unsigned int *flags,
                     const void *entry, struct xt_entry_match **match)
{
	struct xt_psd_info *psdinfo = (struct xt_psd_info *)(*match)->data;
	unsigned int num;

	switch (c) {
		/* PSD-weight-threshold */
		case '1':
			if (*flags & XT_PSD_OPT_CTRESH)
				xtables_error(PARAMETER_PROBLEM,"Can't specify --psd-weight-threshold twice");
			if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
				xtables_error(PARAMETER_PROBLEM, "bad --psd-weight-threshold '%s'", optarg);
			psdinfo->weight_threshold = num;
			*flags |= XT_PSD_OPT_CTRESH;
			return true;

		/* PSD-delay-threshold */
		case '2':
			if (*flags & XT_PSD_OPT_DTRESH)
				xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-delay-threshold twice");
			if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
				xtables_error(PARAMETER_PROBLEM, "bad --psd-delay-threshold '%s'", optarg);
			psdinfo->delay_threshold = num;
			*flags |= XT_PSD_OPT_DTRESH;
			return true;

		/* PSD-lo-ports-weight */
		case '3':
			if (*flags & XT_PSD_OPT_LPWEIGHT)
				xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-lo-ports-weight twice");
			if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
				xtables_error(PARAMETER_PROBLEM, "bad --psd-lo-ports-weight '%s'", optarg);
			psdinfo->lo_ports_weight = num;
			*flags |= XT_PSD_OPT_LPWEIGHT;
			return true;

		/* PSD-hi-ports-weight */
		case '4':
			if (*flags & XT_PSD_OPT_HPWEIGHT)
				xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-hi-ports-weight twice");
			if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
				xtables_error(PARAMETER_PROBLEM, "bad --psd-hi-ports-weight '%s'", optarg);
			psdinfo->hi_ports_weight = num;
			*flags |= XT_PSD_OPT_HPWEIGHT;
			return true;
	}
	return false;
}
Beispiel #12
0
static void owner_parse_range(const char *s, unsigned int *from,
                              unsigned int *to, const char *opt)
{
	char *end;

	/* -1 is reversed, so the max is one less than that. */
	if (!xtables_strtoui(s, &end, from, 0, UINT32_MAX - 1))
		xtables_param_act(XTF_BAD_VALUE, "owner", opt, s);
	*to = *from;
	if (*end == '-' || *end == ':')
		if (!xtables_strtoui(end + 1, &end, to, 0, UINT32_MAX - 1))
			xtables_param_act(XTF_BAD_VALUE, "owner", opt, s);
	if (*end != '\0')
		xtables_param_act(XTF_BAD_VALUE, "owner", opt, s);
}
Beispiel #13
0
static void parse_tproxy_mark(char *s, uint32_t *markp, uint32_t *maskp)
{
	unsigned int value, mask = UINT32_MAX;
	char *end;

	if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX))
		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
	if (*end == '/')
		if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
	if (*end != '\0')
		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);

	*markp = value;
	*maskp = mask;
}
Beispiel #14
0
uint16_t
xtables_parse_protocol(const char *s)
{
	const struct protoent *pent;
	unsigned int proto, i;

	if (xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX))
		return proto;

	/* first deal with the special case of 'all' to prevent
	 * people from being able to redefine 'all' in nsswitch
	 * and/or provoke expensive [not working] ldap/nis/...
	 * lookups */
	if (strcmp(s, "all") == 0)
		return 0;

	pent = getprotobyname(s);
	if (pent != NULL)
		return pent->p_proto;

	for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) {
		if (xtables_chain_protos[i].name == NULL)
			continue;
		if (strcmp(s, xtables_chain_protos[i].name) == 0)
			return xtables_chain_protos[i].num;
	}
	xt_params->exit_err(PARAMETER_PROBLEM,
		"unknown protocol \"%s\" specified", s);
	return -1;
}
Beispiel #15
0
static int
limit_parse(int c, char **argv, int invert, unsigned int *flags,
            const void *entry, struct xt_entry_match **match)
{
	struct xt_rateinfo *r = (struct xt_rateinfo *)(*match)->data;
	unsigned int num;

	switch(c) {
	case '%':
		if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) break;
		if (!parse_rate(optarg, &r->avg))
			xtables_error(PARAMETER_PROBLEM,
				   "bad rate `%s'", optarg);
		break;

	case '$':
		if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) break;
		if (!xtables_strtoui(optarg, NULL, &num, 0, 10000))
			xtables_error(PARAMETER_PROBLEM,
				   "bad --limit-burst `%s'", optarg);
		r->burst = num;
		break;

	default:
		return 0;
	}

	if (invert)
		xtables_error(PARAMETER_PROBLEM,
			   "limit does not support invert");

	return 1;
}
static void parse_tproxy_mark(char *s, struct xt_tproxy_target_info *info)
{
	unsigned int value, mask = UINT32_MAX;
	char *end;

	if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX))
		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
	if (*end == '/')
		if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
	if (*end != '\0')
		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);

	info->mark_mask = mask;
	info->mark_value = value;
}
Beispiel #17
0
static u_int32_t
parse_led(const char *name)
{
	unsigned int led = -1;
	unsigned int set = 0;

	if (!xtables_strtoui(name, NULL, &led, 0, 7)) {
		unsigned int i = 0;

		for (i = 0; ipt_led_names[i].name; i++) {
			if (strcasecmp(name, ipt_led_names[i].name) == 0) {
				set++;
				led = ipt_led_names[i].led;
				break;
			}
			if (strncasecmp(name, ipt_led_names[i].name,
					strlen(name)) == 0) {
				if (set++)
					xtables_error(PARAMETER_PROBLEM,
						   "led `%s' ambiguous", name);
				led = ipt_led_names[i].led;
			}
		}

		if (!set)
			xtables_error(PARAMETER_PROBLEM,
				   "led `%s' unknown", name);
	}

	return led;
}
Beispiel #18
0
static unsigned int name_to_type(const char *name)
{
	int namelen = strlen(name);
	static const unsigned int limit = ARRAY_SIZE(mh_names);
	unsigned int match = limit;
	unsigned int i;

	for (i = 0; i < limit; i++) {
		if (strncasecmp(mh_names[i].name, name, namelen) == 0) {
			int len = strlen(mh_names[i].name);
			if (match == limit || len == namelen)
				match = i;
		}
	}

	if (match != limit) {
		return mh_names[match].type;
	} else {
		unsigned int number;

		if (!xtables_strtoui(name, NULL, &number, 0, UINT8_MAX))
			xtables_error(PARAMETER_PROBLEM,
				   "Invalid MH type `%s'\n", name);
		return number;
	}
}
Beispiel #19
0
static struct in6_addr *parse_ip6mask(char *mask)
{
	static struct in6_addr maskaddr;
	struct in6_addr *addrp;
	unsigned int bits;

	if (mask == NULL) {
		/* no mask at all defaults to 128 bits */
		memset(&maskaddr, 0xff, sizeof maskaddr);
		return &maskaddr;
	}
	if ((addrp = xtables_numeric_to_ip6addr(mask)) != NULL)
		return addrp;
	if (!xtables_strtoui(mask, NULL, &bits, 0, 128))
		xt_params->exit_err(PARAMETER_PROBLEM,
			   "invalid mask `%s' specified", mask);
	if (bits != 0) {
		char *p = (void *)&maskaddr;
		memset(p, 0xff, bits / 8);
		memset(p + (bits / 8) + 1, 0, (128 - bits) / 8);
		p[bits/8] = 0xff << (8 - (bits & 7));
		return &maskaddr;
	}

	memset(&maskaddr, 0, sizeof(maskaddr));
	return &maskaddr;
}
Beispiel #20
0
static int
MARK_parse_v1(int c, char **argv, int invert, unsigned int *flags,
              const void *entry, struct xt_entry_target **target)
{
	struct xt_mark_target_info_v1 *markinfo
		= (struct xt_mark_target_info_v1 *)(*target)->data;
	unsigned int mark = 0;

	switch (c) {
	case '1':
	        markinfo->mode = XT_MARK_SET;
		break;
	case '2':
	        markinfo->mode = XT_MARK_AND;
		break;
	case '3':
	        markinfo->mode = XT_MARK_OR;
		break;
	default:
		return 0;
	}

	if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX))
		xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
	markinfo->mark = mark;
	if (*flags)
		xtables_error(PARAMETER_PROBLEM,
			   "MARK target: Can't specify --set-mark twice");

	*flags = 1;
	return 1;
}
Beispiel #21
0
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;
}
Beispiel #22
0
static void owner_mt_parse_v0(struct xt_option_call *cb)
{
	struct ipt_owner_info *info = cb->data;
	struct passwd *pwd;
	struct group *grp;
	unsigned int id;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_USER:
		if ((pwd = getpwnam(cb->arg)) != NULL)
			id = pwd->pw_uid;
		else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1))
			xtables_param_act(XTF_BAD_VALUE, "owner", "--uid-owner", cb->arg);
		if (cb->invert)
			info->invert |= IPT_OWNER_UID;
		info->match |= IPT_OWNER_UID;
		info->uid    = id;
		break;
	case O_GROUP:
		if ((grp = getgrnam(cb->arg)) != NULL)
			id = grp->gr_gid;
		else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1))
			xtables_param_act(XTF_BAD_VALUE, "owner", "--gid-owner", cb->arg);
		if (cb->invert)
			info->invert |= IPT_OWNER_GID;
		info->match |= IPT_OWNER_GID;
		info->gid    = id;
		break;
	case O_PROCESS:
		if (cb->invert)
			info->invert |= IPT_OWNER_PID;
		info->match |= IPT_OWNER_PID;
		break;
	case O_SESSION:
		if (cb->invert)
			info->invert |= IPT_OWNER_SID;
		info->match |= IPT_OWNER_SID;
		break;
	case O_COMM:
		if (cb->invert)
			info->invert |= IPT_OWNER_COMM;
		info->match |= IPT_OWNER_COMM;
		break;
	}
}
Beispiel #23
0
static struct in_addr *__numeric_to_ipaddr(const char *dotted, bool is_mask)
{
	static struct in_addr addr;
	unsigned char *addrp;
	unsigned int onebyte;
	char buf[20], *p, *q;
	int i;

	/* copy dotted string, because we need to modify it */
	strncpy(buf, dotted, sizeof(buf) - 1);
	buf[sizeof(buf) - 1] = '\0';
	addrp = (void *)&addr.s_addr;

	p = buf;
	for (i = 0; i < 3; ++i) {
		if ((q = strchr(p, '.')) == NULL) {
			if (is_mask)
				return NULL;

			/* autocomplete, this is a network address */
			if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX))
				return NULL;

			addrp[i] = onebyte;
			while (i < 3)
				addrp[++i] = 0;

			return &addr;
		}

		*q = '\0';
		if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX))
			return NULL;

		addrp[i] = onebyte;
		p = q + 1;
	}

	/* we have checked 3 bytes, now we check the last one */
	if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX))
		return NULL;

	addrp[3] = onebyte;
	return &addr;
}
static void parse_tproxy_lport(const char *s, struct xt_tproxy_target_info *info)
{
	unsigned int lport;

	if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX))
		info->lport = htons(lport);
	else
		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s);
}
static int TTL_parse(int c, char **argv, int invert, unsigned int *flags,
                     const void *entry, struct xt_entry_target **target)
{
	struct ipt_TTL_info *info = (struct ipt_TTL_info *) (*target)->data;
	unsigned int value;

	if (*flags & IPT_TTL_USED) {
		xtables_error(PARAMETER_PROBLEM,
				"Can't specify TTL option twice");
	}

	if (!optarg) 
		xtables_error(PARAMETER_PROBLEM,
				"TTL: You must specify a value");

	if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
		xtables_error(PARAMETER_PROBLEM,
				"TTL: unexpected `!'");
	
	if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX))
		xtables_error(PARAMETER_PROBLEM,
		           "TTL: Expected value between 0 and 255");

	switch (c) {

		case '1':
			info->mode = IPT_TTL_SET;
			break;

		case '2':
			if (value == 0) {
				xtables_error(PARAMETER_PROBLEM,
					"TTL: decreasing by 0?");
			}

			info->mode = IPT_TTL_DEC;
			break;

		case '3':
			if (value == 0) {
				xtables_error(PARAMETER_PROBLEM,
					"TTL: increasing by 0?");
			}

			info->mode = IPT_TTL_INC;
			break;

		default:
			return 0;

	}
	
	info->ttl = value;
	*flags |= IPT_TTL_USED;

	return 1;
}
Beispiel #26
0
static void parse_tproxy_lport(const char *s, uint16_t *portp)
{
	unsigned int lport;

	if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX))
		*portp = htons(lport);
	else
		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s);
}
static int
NFQUEUE_parse_v1(int c, char **argv, int invert, unsigned int *flags,
                 const void *entry, struct xt_entry_target **target)
{
	struct xt_NFQ_info_v1 *info = (void *)(*target)->data;
	char *colon;
	unsigned int firstqueue, lastqueue;

	switch (c) {
	case 'F': /* fallthrough */
	case 'B':
		if (*flags)
			xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
				   "Only use --queue-num ONCE!");

		if (!xtables_strtoui(optarg, &colon, &firstqueue, 0, UINT16_MAX))
			exit_badqueue(optarg);

		info->queuenum = firstqueue;

		if (c == 'F') {
			if (*colon)
				exit_badqueue(optarg);
			break;
		}

		if (*colon != ':')
			xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", optarg);

		if (!xtables_strtoui(colon + 1, NULL, &lastqueue, 1, UINT16_MAX))
			exit_badqueue(optarg);

		if (firstqueue >= lastqueue)
			xtables_error(PARAMETER_PROBLEM, "%u should be less than %u",
							firstqueue, lastqueue);
		info->queues_total = lastqueue - firstqueue + 1;
		break;
	default:
		return 0;
	}

	return 1;
}
static u_int16_t
parse_length(const char *s)
{
	unsigned int len;
	
	if (!xtables_strtoui(s, NULL, &len, 0, UINT32_MAX))
		xtables_error(PARAMETER_PROBLEM, "length invalid: \"%s\"\n", s);
	else
		return len;
}
static void
parse_num(const char *s, struct xt_NFQ_info *tinfo)
{
	unsigned int num;

	if (!xtables_strtoui(s, NULL, &num, 0, UINT16_MAX))
		exit_badqueue(s);

	tinfo->queuenum = num;
}
Beispiel #30
0
static void
parse_tcp_option(const char *option, u_int8_t *result)
{
	unsigned int ret;

	if (!xtables_strtoui(option, NULL, &ret, 1, UINT8_MAX))
		xtables_error(PARAMETER_PROBLEM, "Bad TCP option \"%s\"", option);

	*result = ret;
}