Пример #1
0
void nl_cli_ct_parse_family(struct nfnl_ct *ct, char *arg)
{
	int family;

	if ((family = nl_str2af(arg)) == AF_UNSPEC)
		nl_cli_fatal(EINVAL,
			     "Unable to nl_cli_ct_parse family \"%s\": %s",
			     arg, nl_geterror(NLE_INVAL));

	nfnl_ct_set_family(ct, family);
}
Пример #2
0
static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr,
		int attr, struct nl_addr ** ct_addr)
{
	if (ct->ce_mask & CT_ATTR_FAMILY) {
		if (addr->a_family != ct->ct_family)
			return -NLE_AF_MISMATCH;
	} else
		nfnl_ct_set_family(ct, addr->a_family);

	if (*ct_addr)
		nl_addr_put(*ct_addr);

	nl_addr_get(addr);
	*ct_addr = addr;
	ct->ce_mask |= attr;

	return 0;
}
Пример #3
0
int main(int argc, char *argv[])
{
	struct nl_sock *sock;
	struct nfnl_ct *ct;
	struct nl_dump_params params = {
		.dp_type = NL_DUMP_LINE,
		.dp_fd = stdout,
	};
	int err, nlflags = NLM_F_CREATE;

	ct = nl_cli_ct_alloc();

	for (;;) {
		int c, optidx = 0;
		enum {
			ARG_ORIG_SRC = 257,
			ARG_ORIG_SPORT = 258,
			ARG_ORIG_DST,
			ARG_ORIG_DPORT,
			ARG_REPLY_SRC,
			ARG_REPLY_SPORT,
			ARG_REPLY_DST,
			ARG_REPLY_DPORT,
			ARG_MARK,
			ARG_TIMEOUT,
			ARG_STATUS,
			ARG_ZONE,
		};
		static struct option long_opts[] = {
			{ "quiet", 0, 0, 'q' },
			{ "help", 0, 0, 'h' },
			{ "version", 0, 0, 'v' },
			{ "proto", 1, 0, 'p' },
			{ "orig-src", 1, 0, ARG_ORIG_SRC },
			{ "orig-sport", 1, 0, ARG_ORIG_SPORT },
			{ "orig-dst", 1, 0, ARG_ORIG_DST },
			{ "orig-dport", 1, 0, ARG_ORIG_DPORT },
			{ "reply-src", 1, 0, ARG_REPLY_SRC },
			{ "reply-sport", 1, 0, ARG_REPLY_SPORT },
			{ "reply-dst", 1, 0, ARG_REPLY_DST },
			{ "reply-dport", 1, 0, ARG_REPLY_DPORT },
			{ "family", 1, 0, 'F' },
			{ "mark", 1, 0, ARG_MARK },
			{ "timeout", 1, 0, ARG_TIMEOUT },
			{ "status", 1, 0, ARG_STATUS },
			{ "zone", 1, 0, ARG_ZONE },
			{ 0, 0, 0, 0 }
		};

		c = getopt_long(argc, argv, "46q:hv:p:F:", long_opts, &optidx);
		if (c == -1)
			break;

		switch (c) {
		case '?': exit(NLE_INVAL);
		case 'q': quiet = 1; break;
		case '4': nfnl_ct_set_family(ct, AF_INET); break;
		case '6': nfnl_ct_set_family(ct, AF_INET6); break;
		case 'h': print_usage(); break;
		case 'v': nl_cli_print_version(); break;
		case 'p': nl_cli_ct_parse_protocol(ct, optarg); break;
		case ARG_ORIG_SRC: nl_cli_ct_parse_src(ct, 0, optarg); break;
		case ARG_ORIG_SPORT: nl_cli_ct_parse_src_port(ct, 0, optarg); break;
		case ARG_ORIG_DST: nl_cli_ct_parse_dst(ct, 0, optarg); break;
		case ARG_ORIG_DPORT: nl_cli_ct_parse_dst_port(ct, 0, optarg); break;
		case ARG_REPLY_SRC: nl_cli_ct_parse_src(ct, 1, optarg); break;
		case ARG_REPLY_SPORT: nl_cli_ct_parse_src_port(ct, 1, optarg); break;
		case ARG_REPLY_DST: nl_cli_ct_parse_dst(ct, 1, optarg); break;
		case ARG_REPLY_DPORT: nl_cli_ct_parse_dst_port(ct, 1, optarg); break;
		case 'F': nl_cli_ct_parse_family(ct, optarg); break;
		case ARG_MARK: nl_cli_ct_parse_mark(ct, optarg); break;
		case ARG_TIMEOUT: nl_cli_ct_parse_timeout(ct, optarg); break;
		case ARG_STATUS: nl_cli_ct_parse_status(ct, optarg); break;
		case ARG_ZONE: nl_cli_ct_parse_zone(ct, optarg); break;
		}
	}

	if (!quiet) {
		printf("Adding ");
		nl_object_dump(OBJ_CAST(ct), &params);
	}

	sock = nl_cli_alloc_socket();
	nl_cli_connect(sock, NETLINK_NETFILTER);

	if ((err = nfnl_ct_add(sock, ct, nlflags)) < 0)
		nl_cli_fatal(err, "Unable to add conntrack: %s", nl_geterror(err));

	if (!quiet) {
		printf("Added ");
		nl_object_dump(OBJ_CAST(ct), &params);
	}

	return 0;
}
Пример #4
0
int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
{
	struct nfnl_ct *ct;
	struct nlattr *tb[CTA_MAX+1];
	int err;

	ct = nfnl_ct_alloc();
	if (!ct)
		return -NLE_NOMEM;

	ct->ce_msgtype = nlh->nlmsg_type;

	err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX,
			  ct_policy);
	if (err < 0)
		goto errout;

	nfnl_ct_set_family(ct, nfnlmsg_family(nlh));

	if (tb[CTA_TUPLE_ORIG]) {
		err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_TUPLE_REPLY]) {
		err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_PROTOINFO]) {
		err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_STATUS])
		nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS])));
	if (tb[CTA_TIMEOUT])
		nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT])));
	if (tb[CTA_MARK])
		nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK])));
	if (tb[CTA_USE])
		nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE])));
	if (tb[CTA_ID])
		nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID])));
	if (tb[CTA_ZONE])
		nfnl_ct_set_zone(ct, ntohs(nla_get_u16(tb[CTA_ZONE])));

	if (tb[CTA_COUNTERS_ORIG]) {
		err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_COUNTERS_REPLY]) {
		err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_TIMESTAMP]) {
		err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]);
		if (err < 0)
			goto errout;
	}

	*result = ct;
	return 0;

errout:
	nfnl_ct_put(ct);
	return err;
}