static void
parse_dccp_ports(const char *portstring, 
		 u_int16_t *ports)
{
	char *buffer;
	char *cp;

	buffer = strdup(portstring);
	DEBUGP("%s\n", portstring);
	if ((cp = strchr(buffer, ':')) == NULL) {
		ports[0] = ports[1] = xtables_parse_port(buffer, "dccp");
	}
	else {
		*cp = '\0';
		cp++;

		ports[0] = buffer[0] ? xtables_parse_port(buffer, "dccp") : 0;
		ports[1] = cp[0] ? xtables_parse_port(cp, "dccp") : 0xFFFF;

		if (ports[0] > ports[1])
			xtables_error(PARAMETER_PROBLEM,
				   "invalid portrange (min > max)");
	}
	free(buffer);
}
static void
parse_multi_ports_v1(const char *portstring, 
		     struct xt_multiport_v1 *multiinfo,
		     const char *proto)
{
	char *buffer, *cp, *next, *range;
	unsigned int i;
	u_int16_t m;

	buffer = strdup(portstring);
	if (!buffer) xtables_error(OTHER_PROBLEM, "strdup failed");

	for (i=0; i<XT_MULTI_PORTS; i++)
		multiinfo->pflags[i] = 0;
 
	for (cp=buffer, i=0; cp && i<XT_MULTI_PORTS; cp=next, i++) {
		next=strchr(cp, ',');
 		if (next) *next++='\0';
		range = strchr(cp, ':');
		if (range) {
			if (i == XT_MULTI_PORTS-1)
				xtables_error(PARAMETER_PROBLEM,
					   "too many ports specified");
			*range++ = '\0';
		}
		multiinfo->ports[i] = xtables_parse_port(cp, proto);
		if (range) {
			multiinfo->pflags[i] = 1;
			multiinfo->ports[++i] = xtables_parse_port(range, proto);
			if (multiinfo->ports[i-1] >= multiinfo->ports[i])
				xtables_error(PARAMETER_PROBLEM,
					   "invalid portrange specified");
			m <<= 1;
		}
 	}
	multiinfo->count = i;
	if (cp) xtables_error(PARAMETER_PROBLEM, "too many ports specified");
 	free(buffer);
}
Esempio n. 3
0
static void
parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
{
	char *buffer;
	char *cp;

	buffer = strdup(portstring);
	if ((cp = strchr(buffer, ':')) == NULL)
		ports[0] = ports[1] = xtables_parse_port(buffer, NULL);
	else {
		*cp = '\0';
		cp++;

		ports[0] = buffer[0] ? xtables_parse_port(buffer, NULL) : 0;
		ports[1] = cp[0] ? xtables_parse_port(cp, NULL) : 0xFFFF;

		if (ports[0] > ports[1])
			xtables_error(PARAMETER_PROBLEM,
				      "invalid portrange (min > max)");
	}
	free(buffer);
}
static unsigned int
parse_multi_ports(const char *portstring, u_int16_t *ports, const char *proto)
{
	char *buffer, *cp, *next;
	unsigned int i;

	buffer = strdup(portstring);
	if (!buffer) xtables_error(OTHER_PROBLEM, "strdup failed");

	for (cp=buffer, i=0; cp && i<XT_MULTI_PORTS; cp=next,i++)
	{
		next=strchr(cp, ',');
		if (next) *next++='\0';
		ports[i] = xtables_parse_port(cp, proto);
	}
	if (cp) xtables_error(PARAMETER_PROBLEM, "too many ports specified");
	free(buffer);
	return i;
}
Esempio n. 5
0
/* Function which parses command options; returns true if it ate an option */
static int ipvs_mt_parse(int c, char **argv, int invert, unsigned int *flags,
			 const void *entry, struct xt_entry_match **match,
			 unsigned int family)
{
	struct xt_ipvs_mtinfo *data = (void *)(*match)->data;
	char *p = NULL;
	u_int8_t op = 0;

	if ('0' <= c && c <= '6') {
		static const int ops[] = {
			XT_IPVS_IPVS_PROPERTY,
			XT_IPVS_PROTO,
			XT_IPVS_VADDR,
			XT_IPVS_VPORT,
			XT_IPVS_DIR,
			XT_IPVS_METHOD,
			XT_IPVS_VPORTCTL
		};
		op = ops[c - '0'];
	} else
		return 0;

	if (*flags & op & XT_IPVS_ONCE_MASK)
		goto multiple_use;

	switch (c) {
	case '0': /* --ipvs */
		/* Nothing to do here. */
		break;

	case '1': /* --vproto */
		/* Canonicalize into lower case */
		for (p = optarg; *p != '\0'; ++p)
			*p = tolower(*p);

		data->l4proto = xtables_parse_protocol(optarg);
		break;

	case '2': /* --vaddr */
		ipvs_mt_parse_addr_and_mask(optarg, &data->vaddr,
					    &data->vmask, family);
		break;

	case '3': /* --vport */
		data->vport = htons(xtables_parse_port(optarg, "tcp"));
		break;

	case '4': /* --vdir */
		xtables_param_act(XTF_NO_INVERT, "ipvs", "--vdir", invert);
		if (strcasecmp(optarg, "ORIGINAL") == 0) {
			data->bitmask |= XT_IPVS_DIR;
			data->invert   &= ~XT_IPVS_DIR;
		} else if (strcasecmp(optarg, "REPLY") == 0) {
			data->bitmask |= XT_IPVS_DIR;
			data->invert  |= XT_IPVS_DIR;
		} else {
			xtables_param_act(XTF_BAD_VALUE,
					  "ipvs", "--vdir", optarg);
		}
		break;

	case '5': /* --vmethod */
		if (strcasecmp(optarg, "GATE") == 0)
			data->fwd_method = IP_VS_CONN_F_DROUTE;
		else if (strcasecmp(optarg, "IPIP") == 0)
			data->fwd_method = IP_VS_CONN_F_TUNNEL;
		else if (strcasecmp(optarg, "MASQ") == 0)
			data->fwd_method = IP_VS_CONN_F_MASQ;
		else
			xtables_param_act(XTF_BAD_VALUE,
					  "ipvs", "--vmethod", optarg);
		break;

	case '6': /* --vportctl */
		data->vportctl = htons(xtables_parse_port(optarg, "tcp"));
		break;

	default:
		/* Hu? How did we come here? */
		assert(false);
		return 0;
	}

	if (op & XT_IPVS_ONCE_MASK) {
		if (data->invert & XT_IPVS_IPVS_PROPERTY)
			xtables_error(PARAMETER_PROBLEM,
				      "! --ipvs cannot be together with"
				      " other options");
		data->bitmask |= XT_IPVS_IPVS_PROPERTY;
	}

	data->bitmask |= op;
	if (invert)
		data->invert |= op;
	*flags |= op;
	return 1;

multiple_use:
	xtables_error(PARAMETER_PROBLEM,
		      "multiple use of the same IPVS option is not allowed");
}