Beispiel #1
0
static void
parse_target(char **argv, int invert, unsigned int *flags,
             struct ipt_set_info *info, const char *what)
{
	if (info->flags[0])
		xtables_error(PARAMETER_PROBLEM,
			   "--%s can be specified only once", what);

	if (xtables_check_inverse(optarg, &invert, NULL, 0))
		xtables_error(PARAMETER_PROBLEM,
			   "Unexpected `!' after --%s", what);

	if (!argv[optind]
	    || argv[optind][0] == '-' || argv[optind][0] == '!')
		xtables_error(PARAMETER_PROBLEM,
			   "--%s requires two args.", what);

	if (strlen(argv[optind-1]) > IP_SET_MAXNAMELEN - 1)
		xtables_error(PARAMETER_PROBLEM,
			   "setname `%s' too long, max %d characters.",
			   argv[optind-1], IP_SET_MAXNAMELEN - 1);

	get_set_byname(argv[optind - 1], info);
	parse_bindings(argv[optind], info);
	optind++;
	
	*flags = 1;
}
static int set_parse(int c, char **argv, int invert, unsigned int *flags,
                     const void *entry, struct xt_entry_match **match)
{
	struct ipt_set_info_match *myinfo = 
		(struct ipt_set_info_match *) (*match)->data;
	struct ipt_set_info *info = &myinfo->match_set;

	switch (c) {
	case '2':
#if 0
		fprintf(stderr,
			"--set option deprecated, please use --match-set\n");
#endif
	case '1':		/* --match-set <set> <flag>[,<flag> */
		if (info->flags[0])
			xtables_error(PARAMETER_PROBLEM,
				   "--match-set can be specified only once");

		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
		if (invert)
			info->flags[0] |= IPSET_MATCH_INV;

		if (!argv[optind]
		    || argv[optind][0] == '-'
		    || argv[optind][0] == '!')
			xtables_error(PARAMETER_PROBLEM,
				   "--match-set requires two args.");

		if (strlen(optarg) > IP_SET_MAXNAMELEN - 1)
			xtables_error(PARAMETER_PROBLEM,
				   "setname `%s' too long, max %d characters.",
				   optarg, IP_SET_MAXNAMELEN - 1);

		get_set_byname(optarg, info);
		parse_bindings(argv[optind], info);
		DEBUGP("parse: set index %u\n", info->index);
		optind++;
		
		*flags = 1;
		break;

	default:
		return 0;
	}

	return 1;
}
Beispiel #3
0
/* Function which parses command options; returns true if it ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      unsigned int *nfcache, struct ipt_entry_match **match)
{
	struct ipt_set_info_match *myinfo = 
		(struct ipt_set_info_match *) (*match)->data;
	struct ipt_set_info *info = &myinfo->match_set;

	switch (c) {
	case '1':		/* --set <set> <flag>[,<flag> */
		if (info->flags[0])
			exit_error(PARAMETER_PROBLEM,
				   "--set can be specified only once");

		check_inverse(optarg, &invert, &optind, 0);
		if (invert)
			info->flags[0] |= IPSET_MATCH_INV;

		if (!argv[optind]
		    || argv[optind][0] == '-'
		    || argv[optind][0] == '!')
			exit_error(PARAMETER_PROBLEM,
				   "--set requires two args.");

		if (strlen(argv[optind-1]) > IP_SET_MAXNAMELEN - 1)
			exit_error(PARAMETER_PROBLEM,
				   "setname `%s' too long, max %d characters.",
				   argv[optind-1], IP_SET_MAXNAMELEN - 1);

		get_set_byname(argv[optind - 1], info);
		parse_bindings(argv[optind], info);
		DEBUGP("parse: set index %u\n", info->index);
		optind++;
		
		*flags = 1;
		break;

	default:
		return 0;
	}

	return 1;
}
Beispiel #4
0
static int
set_parse_v2(int c, char **argv, int invert, unsigned int *flags,
	     const void *entry, struct xt_entry_match **match)
{
	struct xt_set_info_match_v1 *myinfo = 
		(struct xt_set_info_match_v1 *) (*match)->data;
	struct xt_set_info *info = &myinfo->match_set;

	switch (c) {
	case '3':
		info->flags |= IPSET_RETURN_NOMATCH;
		break;
	case '2':
		fprintf(stderr,
			"--set option deprecated, please use --match-set\n");
	case '1':		/* --match-set <set> <flag>[,<flag> */
		if (info->dim)
			xtables_error(PARAMETER_PROBLEM,
				      "--match-set can be specified only once");
		if (invert)
			info->flags |= IPSET_INV_MATCH;

		if (!argv[optind]
		    || argv[optind][0] == '-'
		    || argv[optind][0] == '!')
			xtables_error(PARAMETER_PROBLEM,
				      "--match-set requires two args.");

		if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
			xtables_error(PARAMETER_PROBLEM,
				      "setname `%s' too long, max %d characters.",
				      optarg, IPSET_MAXNAMELEN - 1);

		get_set_byname(optarg, info);
		parse_dirs(argv[optind], info);
		DEBUGP("parse: set index %u\n", info->index);
		optind++;
		
		*flags = 1;
		break;
	}

	return 1;
}
Beispiel #5
0
static int ipset_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
			    struct bstr *args)
{
	struct xt_set_info set_info = {};
	int ret;

#define PARSE_ERR(CARG, FMT, ARGS...) \
	em_parse_error(EINVAL, args, CARG, &ipset_ematch_util, FMT, ##ARGS)

	if (args == NULL)
		return PARSE_ERR(args, "ipset: missing set name");

	if (args->len >= IPSET_MAXNAMELEN)
		return PARSE_ERR(args, "ipset: set name too long (max %u)", IPSET_MAXNAMELEN - 1);
	ret = get_set_byname(args->data, &set_info);
	if (ret < 0)
		return PARSE_ERR(args, "ipset: unknown set name '%s'", args->data);

	if (args->next == NULL)
		return PARSE_ERR(args, "ipset: missing set flags");

	args = bstr_next(args);
	if (parse_dirs(args->data, &set_info))
		return PARSE_ERR(args, "ipset: error parsing set flags");

	if (args->next) {
		args = bstr_next(args);
		return PARSE_ERR(args, "ipset: unknown parameter");
	}

	addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));
	addraw_l(n, MAX_MSG, &set_info, sizeof(set_info));

#undef PARSE_ERR
	return 0;
}
Beispiel #6
0
/* Revision 4 */
static int
set_parse_v4(int c, char **argv, int invert, unsigned int *flags,
	     const void *entry, struct xt_entry_match **match)
{
	struct xt_set_info_match_v4 *info =
		(struct xt_set_info_match_v4 *) (*match)->data;

	switch (c) {
	case 'a':
		if (invert)
			info->flags |= IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE;
		break;
	case '0':
		if (info->bytes.op != IPSET_COUNTER_NONE)
			xtables_error(PARAMETER_PROBLEM,
				      "only one of the --bytes-[eq|lt|gt]"
				      " is allowed\n");
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
				      "--bytes-gt option cannot be inverted\n");
		info->bytes.op = IPSET_COUNTER_GT;
		info->bytes.value = parse_counter(optarg);
		break;
	case '9':
		if (info->bytes.op != IPSET_COUNTER_NONE)
			xtables_error(PARAMETER_PROBLEM,
				      "only one of the --bytes-[eq|lt|gt]"
				      " is allowed\n");
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
				      "--bytes-lt option cannot be inverted\n");
		info->bytes.op = IPSET_COUNTER_LT;
		info->bytes.value = parse_counter(optarg);
		break;
	case '8':
		if (info->bytes.op != IPSET_COUNTER_NONE)
			xtables_error(PARAMETER_PROBLEM,
				      "only one of the --bytes-[eq|lt|gt]"
				      " is allowed\n");
		info->bytes.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ;
		info->bytes.value = parse_counter(optarg);
		break;
	case '7':
		if (info->packets.op != IPSET_COUNTER_NONE)
			xtables_error(PARAMETER_PROBLEM,
				      "only one of the --packets-[eq|lt|gt]"
				      " is allowed\n");
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
				      "--packets-gt option cannot be inverted\n");
		info->packets.op = IPSET_COUNTER_GT;
		info->packets.value = parse_counter(optarg);
		break;
	case '6':
		if (info->packets.op != IPSET_COUNTER_NONE)
			xtables_error(PARAMETER_PROBLEM,
				      "only one of the --packets-[eq|lt|gt]"
				      " is allowed\n");
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
				      "--packets-lt option cannot be inverted\n");
		info->packets.op = IPSET_COUNTER_LT;
		info->packets.value = parse_counter(optarg);
		break;
	case '5':
		if (info->packets.op != IPSET_COUNTER_NONE)
			xtables_error(PARAMETER_PROBLEM,
				      "only one of the --packets-[eq|lt|gt]"
				      " is allowed\n");
		info->packets.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ;
		info->packets.value = parse_counter(optarg);
		break;
	case '4':
		if (invert)
			info->flags |= IPSET_FLAG_SKIP_COUNTER_UPDATE;
		break;
	case '3':
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
				      "--return-nomatch flag cannot be inverted\n");
		info->flags |= IPSET_FLAG_RETURN_NOMATCH;
		break;
	case '2':
		fprintf(stderr,
			"--set option deprecated, please use --match-set\n");
	case '1':		/* --match-set <set> <flag>[,<flag> */
		if (info->match_set.dim)
			xtables_error(PARAMETER_PROBLEM,
				      "--match-set can be specified only once");
		if (invert)
			info->match_set.flags |= IPSET_INV_MATCH;

		if (!argv[optind]
		    || argv[optind][0] == '-'
		    || argv[optind][0] == '!')
			xtables_error(PARAMETER_PROBLEM,
				      "--match-set requires two args.");

		if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
			xtables_error(PARAMETER_PROBLEM,
				      "setname `%s' too long, max %d characters.",
				      optarg, IPSET_MAXNAMELEN - 1);

		get_set_byname(optarg, &info->match_set);
		parse_dirs(argv[optind], &info->match_set);
		DEBUGP("parse: set index %u\n", info->match_set.index);
		optind++;

		*flags = 1;
		break;
	}

	return 1;
}
Beispiel #7
0
int ip6tables_add_rules(struct ip6tc_handle* handle, const char* chain_name, int rulenum, int dim, int src_dst, const char* target_name, const char* set_name, uint16_t protocol, int param, int cmd, bool ignore_errors)
{
	size_t size;
	struct ip6t_entry *fw;
	struct xt_entry_target *target;
	struct xt_entry_match *match;
#ifdef HAVE_XT_SET_INFO_MATCH_V1
	struct xt_set_info_match_v1 *setinfo;
#else
	struct xt_set_info_match *setinfo;
#endif
	ip6t_chainlabel chain;
	int res;
	int sav_errno;

	/* Add an entry */

	memset(chain, 0, sizeof(chain));

	size = XT_ALIGN(sizeof (struct ip6t_entry)) +
			XT_ALIGN(sizeof(struct xt_entry_match)) +
			XT_ALIGN(sizeof(struct xt_entry_target) + 1) +
			XT_ALIGN(sizeof(*setinfo));

	if (protocol == IPPROTO_ICMPV6)
		size += XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(struct ip6t_icmp));

	fw = (struct ip6t_entry*)MALLOC(size);

	fw->target_offset = XT_ALIGN(sizeof(struct ip6t_entry));

	// set
	match = (struct xt_entry_match*)((char*)fw + fw->target_offset);
	match->u.match_size = XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(*setinfo));
#ifdef HAVE_XT_SET_INFO_MATCH_V1
	match->u.user.revision = 1;
#else
	match->u.user.revision = 0;
#endif
	fw->target_offset += match->u.match_size;
	strcpy(match->u.user.name, "set");

#ifdef HAVE_XT_SET_INFO_MATCH_V1
	setinfo = (struct xt_set_info_match_v1 *)match->data;
#else
	setinfo = (struct xt_set_info_match *)match->data;
#endif
	get_set_byname (set_name, &setinfo->match_set, NFPROTO_IPV6, ignore_errors);
	if (setinfo->match_set.index == IPSET_INVALID_ID) {
		FREE(fw);
		return -1;
	}

	setinfo->match_set.dim = dim;
	setinfo->match_set.flags = src_dst;

	if (protocol != IPPROTO_NONE) {
		fw->ipv6.proto = protocol;

		fw->ipv6.flags |= IP6T_F_PROTO ;		// IPv6 only

		if (protocol == IPPROTO_ICMPV6)
		{
			match = (struct xt_entry_match*)((char*)fw + fw->target_offset);
			match->u.match_size = XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(struct ip6t_icmp));
			match->u.user.revision = 0;
			fw->target_offset += match->u.match_size;
			strcpy(match->u.user.name, "icmp6");

			struct ip6t_icmp *icmpinfo = (struct ip6t_icmp *)match->data;
			icmpinfo->type = param;		// type to match
			icmpinfo->code[0] = 0;		// code lower
			icmpinfo->code[1] = 0xff;	// code upper
			icmpinfo->invflags = 0;		// don't invert
		}
	}

// target is XTC_LABEL_DROP/XTC_LABEL_ACCEPT
	fw->next_offset = size;
	target = ip6t_get_target(fw);
	target->u.user.target_size = XT_ALIGN(sizeof(struct xt_entry_target) + 1);
	strcpy(target->u.user.name, target_name);
//	fw->ip.flags |= IP6T_F_GOTO;
	strcpy(chain, chain_name);

	// Use iptc_append_entry to add to the chain
	if (cmd == IPADDRESS_DEL) {
		unsigned char matchmask[fw->next_offset];
		memset(matchmask, 0xff, fw->next_offset);
		res = ip6tc_delete_entry(chain, fw, matchmask, handle);
	}
	else if (rulenum == -1)
		res = ip6tc_append_entry(chain, fw, handle) ;
	else
		res = ip6tc_insert_entry(chain, fw, rulenum, handle) ;

	sav_errno = errno;

	FREE(fw);

	if (res!= 1)
	{
		if (!ignore_errors)
			log_message(LOG_INFO, "ip6tc_insert_entry for chain %s returned %d: %s", chain, res, ip6tc_strerror(sav_errno)) ;

		return sav_errno;
	}

	return 0;
}