Example #1
0
static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
    char **argv, struct nlmsghdr *n)
{
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	char *end;

	if (handle) {
		t->tcm_handle = strtoul(handle, &end, 0);
		if (*end) {
			fprintf(stderr, "Illegal filter ID\n");
			return -1;
		}
	}
	if (!argc) return 0;
	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
	while (argc) {
		if (!strcmp(*argv, "hash")) {
			int hash;

			NEXT_ARG();
			hash = strtoul(*argv, &end, 0);
			if (*end || !hash || hash > 0x10000) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_HASH, &hash, sizeof(hash));
		} else if (!strcmp(*argv,"mask")) {
			__u16 mask;

			NEXT_ARG();
			mask = strtoul(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_MASK, &mask, sizeof(mask));
		} else if (!strcmp(*argv,"shift")) {
			int shift;

			NEXT_ARG();
			shift = strtoul(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_SHIFT, &shift,
			    sizeof(shift));
		} else if (!strcmp(*argv,"fall_through")) {
			int value = 1;

			addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
			    sizeof(value));
		} else if (!strcmp(*argv,"pass_on")) {
			int value = 0;

			addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
			    sizeof(value));
		} else if (!strcmp(*argv,"classid")) {
			__u32 handle;

			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4);
		} else if (!strcmp(*argv,"police")) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (!strcmp(*argv,"action")) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_TCINDEX_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;
		} else {
			explain();
			return -1;
		}
		argc--;
		argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Example #2
0
static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	__u32 mask = 0;
	int mask_set = 0;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		char *slash;
		if ((slash = strchr(handle, '/')) != NULL)
			*slash = '\0';
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
		if (slash) {
			if (get_u32(&mask, slash+1, 0)) {
				fprintf(stderr, "Illegal \"handle\" mask\n");
				return -1;
			}
			mask_set = 1;
		}
	}

	if (argc == 0)
		return 0;

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	if (mask_set)
		addattr32(n, MAX_MSG, TCA_FW_MASK, mask);

	while (argc > 0) {
		if (matches(*argv, "classid") == 0 ||
		    matches(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_FW_CLASSID, &handle, 4);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_FW_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_FW_ACT, n)) {
				fprintf(stderr, "Illegal fw \"action\"\n");
				return -1;
			}
			continue;
		} else if (strcmp(*argv, "indev") == 0) {
			char d[IFNAMSIZ+1];
			memset(d, 0, sizeof (d));
			argc--;
			argv++;
			if (argc < 1) {
				fprintf(stderr, "Illegal indev\n");
				return -1;
			}
			strncpy(d, *argv, sizeof (d) - 1);
			addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1);
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
static int flow_parse_opt(struct filter_util *fu, char *handle,
			  int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	__u32 mask = ~0U, xor = 0;
	__u32 keys = 0, nkeys = 0;
	__u32 mode = FLOW_MODE_MAP;
	__u32 tmp;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "map") == 0) {
			mode = FLOW_MODE_MAP;
		} else if (matches(*argv, "hash") == 0) {
			mode = FLOW_MODE_HASH;
		} else if (matches(*argv, "keys") == 0) {
			NEXT_ARG();
			if (flow_parse_keys(&keys, &nkeys, *argv))
				return -1;
			addattr32(n, 4096, TCA_FLOW_KEYS, keys);
		} else if (matches(*argv, "and") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"mask\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, tmp, 0);
		} else if (matches(*argv, "or") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"or\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, ~tmp, tmp);
		} else if (matches(*argv, "xor") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"xor\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, ~0, tmp);
		} else if (matches(*argv, "rshift") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"rshift\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_RSHIFT, tmp);
		} else if (matches(*argv, "addend") == 0) {
			NEXT_ARG();
			if (get_addend(&tmp, *argv, keys)) {
				fprintf(stderr, "Illegal \"addend\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_ADDEND, tmp);
		} else if (matches(*argv, "divisor") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_DIVISOR, tmp);
		} else if (matches(*argv, "baseclass") == 0) {
			NEXT_ARG();
			if (get_tc_classid(&tmp, *argv) || TC_H_MIN(tmp) == 0) {
				fprintf(stderr, "Illegal \"baseclass\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_BASECLASS, tmp);
		} else if (matches(*argv, "perturb") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"perturb\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_PERTURB, tmp);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_FLOW_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_FLOW_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_ematch(&argc, &argv, TCA_FLOW_EMATCHES, n)) {
				fprintf(stderr, "Illegal \"ematch\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argv++, argc--;
	}

	if (nkeys > 1 && mode != FLOW_MODE_HASH) {
		fprintf(stderr, "Invalid mode \"map\" for multiple keys\n");
		return -1;
	}
	addattr32(n, 4096, TCA_FLOW_MODE, mode);

	if (mask != ~0 || xor != 0) {
		addattr32(n, 4096, TCA_FLOW_MASK, mask);
		addattr32(n, 4096, TCA_FLOW_XOR, xor);
	}

	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
	return 0;
}
Example #4
0
static int rsvp_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	int family = strcmp(qu->id, "rsvp") == 0 ? AF_INET : AF_INET6;
	struct tc_rsvp_pinfo pinfo;
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	int pinfo_ok = 0;
	struct rtattr *tail;

	memset(&pinfo, 0, sizeof(pinfo));
	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	if (argc == 0)
		return 0;

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "session") == 0) {
			inet_prefix addr;
			NEXT_ARG();
			if (get_addr_and_pi(&argc, &argv, &addr, &pinfo, 1, family)) {
				fprintf(stderr, "Illegal \"session\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_RSVP_DST, &addr.data, addr.bytelen);
			if (pinfo.dpi.mask || pinfo.protocol)
				pinfo_ok++;
			continue;
		} else if (matches(*argv, "sender") == 0 ||
			   matches(*argv, "flowspec") == 0) {
			inet_prefix addr;
			NEXT_ARG();
			if (get_addr_and_pi(&argc, &argv, &addr, &pinfo, 0, family)) {
				fprintf(stderr, "Illegal \"sender\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_RSVP_SRC, &addr.data, addr.bytelen);
			if (pinfo.spi.mask || pinfo.protocol)
				pinfo_ok++;
			continue;
		} else if (matches("ipproto", *argv) == 0) {
			int num;
			NEXT_ARG();
			num = inet_proto_a2n(*argv);
			if (num < 0) {
				fprintf(stderr, "Illegal \"ipproto\"\n");
				return -1;
			}
			pinfo.protocol = num;
			pinfo_ok++;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_RSVP_CLASSID, &handle, 4);
		} else if (strcmp(*argv, "tunnelid") == 0) {
			unsigned tid;
			NEXT_ARG();
			if (get_unsigned(&tid, *argv, 0)) {
				fprintf(stderr, "Illegal \"tunnelid\"\n");
				return -1;
			}
			pinfo.tunnelid = tid;
			pinfo_ok++;
		} else if (strcmp(*argv, "tunnel") == 0) {
			unsigned tid;
			NEXT_ARG();
			if (get_unsigned(&tid, *argv, 0)) {
				fprintf(stderr, "Illegal \"tunnel\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_RSVP_CLASSID, &tid, 4);
			NEXT_ARG();
			if (strcmp(*argv, "skip") == 0) {
				NEXT_ARG();
			}
			if (get_unsigned(&tid, *argv, 0)) {
				fprintf(stderr, "Illegal \"skip\"\n");
				return -1;
			}
			pinfo.tunnelhdr = tid;
			pinfo_ok++;
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_RSVP_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}

	if (pinfo_ok)
		addattr_l(n, 4096, TCA_RSVP_PINFO, &pinfo, sizeof(pinfo));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}