Exemplo n.º 1
0
static int rule_delete(struct firewall_handle *handle)
{
	struct nftnl_rule *rule;
	struct mnl_socket *nl;
	int err;

	DBG("");

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, handle->chain);
	nftnl_rule_set_u64(rule, NFTNL_RULE_HANDLE, handle->handle);

	err = socket_open_and_bind(&nl);
	if (err < 0) {
		nftnl_rule_free(rule);
		return err;
	}

	err = rule_cmd(nl, rule, NFT_MSG_DELRULE, NFPROTO_IPV4,
			NLM_F_ACK, 0, NULL);
	nftnl_rule_free(rule);
	mnl_socket_close(nl);

	return err;
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
	struct nftnl_rule *a, *b;
	struct nftnl_expr *ex;
	struct nlmsghdr *nlh;
	char buf[4096];
	struct nftnl_expr_iter *iter_a, *iter_b;
	struct nftnl_expr *rule_a, *rule_b;
	uint32_t chain_t = 0x12345678;
	uint32_t data_t = 0x12345678;

	a = nftnl_rule_alloc();
	b = nftnl_rule_alloc();
	if (a == NULL || b == NULL)
		print_err("OOM");
	ex = nftnl_expr_alloc("immediate");
	if (ex == NULL)
		print_err("OOM");

	nftnl_expr_set_u32(ex, NFTNL_EXPR_IMM_DREG, 0x1234568);
	nftnl_expr_set(ex, NFTNL_EXPR_IMM_DATA, &chain_t, sizeof(chain_t));
	nftnl_expr_set_u32(ex, NFTNL_EXPR_IMM_VERDICT, 0x12345678);
	nftnl_expr_set(ex, NFTNL_EXPR_IMM_CHAIN, &data_t, sizeof(data_t));

	nftnl_rule_add_expr(a, ex);

	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
	nftnl_rule_nlmsg_build_payload(nlh, a);

	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
		print_err("parsing problems");

	iter_a = nftnl_expr_iter_create(a);
	iter_b = nftnl_expr_iter_create(b);
	if (iter_a == NULL || iter_b == NULL)
		print_err("OOM");

	rule_a = nftnl_expr_iter_next(iter_a);
	rule_b = nftnl_expr_iter_next(iter_b);
	if (rule_a == NULL || rule_b == NULL)
		print_err("OOM");

	cmp_nftnl_expr(rule_a, rule_b);

	if (nftnl_expr_iter_next(iter_a) != NULL ||
	    nftnl_expr_iter_next(iter_b) != NULL)
		print_err("More 1 expr.");

	nftnl_expr_iter_destroy(iter_a);
	nftnl_expr_iter_destroy(iter_b);
	nftnl_rule_free(a);
	nftnl_rule_free(b);

	if (!test_ok)
		exit(EXIT_FAILURE);

	printf("%s: \033[32mOK\e[0m\n", argv[0]);
	return EXIT_SUCCESS;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
	struct nftnl_rule *a, *b;
	struct nftnl_expr *ex;
	struct nlmsghdr *nlh;
	char buf[4096];
	struct nftnl_expr_iter *iter_a, *iter_b;
	struct nftnl_expr *rule_a, *rule_b;

	a = nftnl_rule_alloc();
	b = nftnl_rule_alloc();
	if (a == NULL || b == NULL)
		print_err("OOM");
	ex = nftnl_expr_alloc("byteorder");
	if (ex == NULL)
		print_err("OOM");

	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_SREG, 0x12345678);
	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_DREG, 0x12345678);
	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_OP, 0x12345678);
	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_LEN, 0x12345678);
	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_SIZE, 0x12345678);

	nftnl_rule_add_expr(a, ex);

	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
	nftnl_rule_nlmsg_build_payload(nlh, a);

	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
		print_err("parsing problems");

	iter_a = nftnl_expr_iter_create(a);
	iter_b = nftnl_expr_iter_create(b);
	if (iter_a == NULL || iter_b == NULL)
		print_err("OOM");

	rule_a = nftnl_expr_iter_next(iter_a);
	rule_b = nftnl_expr_iter_next(iter_b);
	if (rule_a == NULL || rule_b == NULL)
		print_err("OOM");

	cmp_nftnl_expr(rule_a,rule_b);

	if (nftnl_expr_iter_next(iter_a) != NULL ||
	    nftnl_expr_iter_next(iter_b) != NULL)
		print_err("More 1 expr.");

	nftnl_expr_iter_destroy(iter_a);
	nftnl_expr_iter_destroy(iter_b);
	nftnl_rule_free(a);
	nftnl_rule_free(b);

	if (!test_ok)
		exit(EXIT_FAILURE);

	printf("%s: \033[32mOK\e[0m\n", argv[0]);
	return EXIT_SUCCESS;
}
Exemplo n.º 4
0
int __connman_firewall_enable_marking(struct firewall_context *ctx,
					enum connman_session_id_type id_type,
					char *id, const char *src_ip,
					uint32_t mark)
{
	struct nftnl_rule *rule;
	struct mnl_socket *nl;
	struct passwd *pw;
	uid_t uid;
	int err;

	DBG("");

	if (id_type == CONNMAN_SESSION_ID_TYPE_UID) {
		pw = getpwnam(id);
		if (!pw)
			return -EINVAL;
		uid = pw->pw_uid;
	}
	else if (!src_ip)
		return -ENOTSUP;

        err = socket_open_and_bind(&nl);
        if (err < 0)
		return err;

	if (id_type == CONNMAN_SESSION_ID_TYPE_UID) {
		err = build_rule_marking(uid, mark, &rule);
		if (err < 0)
			goto out;

		ctx->rule.chain = CONNMAN_CHAIN_ROUTE_OUTPUT;
		err = rule_cmd(nl, rule, NFT_MSG_NEWRULE, NFPROTO_IPV4,
				NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK,
				CALLBACK_RETURN_HANDLE, &ctx->rule.handle);

		nftnl_rule_free(rule);
	}

	if (src_ip) {
		err = build_rule_src_ip(src_ip, mark, &rule);
		if (err < 0)
			goto out;

		ctx->rule.chain = CONNMAN_CHAIN_ROUTE_OUTPUT;
		err = rule_cmd(nl, rule, NFT_MSG_NEWRULE, NFPROTO_IPV4,
				NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK,
				CALLBACK_RETURN_HANDLE, &ctx->rule.handle);

		nftnl_rule_free(rule);
	}
out:
	mnl_socket_close(nl);
	return err;
}
Exemplo n.º 5
0
int __connman_firewall_enable_snat(struct firewall_context *ctx,
				int index, const char *ifname, const char *addr)
{
	struct nftnl_rule *rule;
	struct mnl_socket *nl;
	int err;

	DBG("");

        err = socket_open_and_bind(&nl);
        if (err < 0)
		return err;

	err = build_rule_snat(index, addr, &rule);
	if (err)
		goto out;

	ctx->rule.chain = CONNMAN_CHAIN_NAT_POST;
        err = rule_cmd(nl, rule, NFT_MSG_NEWRULE, NFPROTO_IPV4,
			NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK,
			CALLBACK_RETURN_HANDLE, &ctx->rule.handle);
	nftnl_rule_free(rule);
out:
	mnl_socket_close(nl);
	return err;
}
Exemplo n.º 6
0
static int build_rule_snat(int index, const char *address,
				struct nftnl_rule **res)
{
	struct nftnl_rule *rule;
	struct nftnl_expr *expr;
	uint32_t snat;
	int err;

	/*
	 * # nft --debug netlink add rule connman nat-postrouting \
	 *	oif eth0 snat 1.2.3.4
	 *	ip connman nat-postrouting
	 *	  [ meta load oif => reg 1 ]
	 *	  [ cmp eq reg 1 0x0000000b ]
	 *	  [ immediate reg 1 0x04030201 ]
	 *	  [ nat snat ip addr_min reg 1 addr_max reg 0 ]
	 */

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, CONNMAN_CHAIN_NAT_POST);

	/* OIF */
	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_OIF);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, &index, sizeof(index));
	if (err < 0)
		goto err;

	/* snat */
	expr = nftnl_expr_alloc("immediate");
	if (!expr)
		goto err;
	snat = inet_addr(address);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG_1);
	nftnl_expr_set(expr, NFTNL_EXPR_IMM_DATA, &snat, sizeof(snat));
	nftnl_rule_add_expr(rule, expr);

	expr = nftnl_expr_alloc("nat");
        if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_NAT_TYPE, NFT_NAT_SNAT);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_NAT_FAMILY, NFPROTO_IPV4);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_NAT_REG_ADDR_MIN, NFT_REG_1);
        nftnl_rule_add_expr(rule, expr);

	*res = rule;
	return 0;

err:
	nftnl_rule_free(rule);
	return -ENOMEM;
}
Exemplo n.º 7
0
int __connman_firewall_enable_nat(struct firewall_context *ctx,
					char *address, unsigned char prefixlen,
					char *interface)
{
	struct mnl_socket *nl;
	struct nftnl_rule *rule;
	int err;

	DBG("address %s/%d interface %s", address, (int)prefixlen, interface);

        err = socket_open_and_bind(&nl);
        if (err < 0)
		return err;

	err = build_rule_nat(address, prefixlen, interface, &rule);
	if (err)
		goto out;

	ctx->rule.chain = CONNMAN_CHAIN_NAT_POST;
        err = rule_cmd(nl, rule, NFT_MSG_NEWRULE, NFPROTO_IPV4,
			NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK,
			CALLBACK_RETURN_HANDLE, &ctx->rule.handle);
	nftnl_rule_free(rule);
out:
	mnl_socket_close(nl);
	return err;
}
Exemplo n.º 8
0
static int rule_cb(const struct nlmsghdr *nlh, int event,
		struct callback_data *cb)
{
	struct nftnl_rule *rule;

	rule = nftnl_rule_alloc();
	if (!rule)
		return MNL_CB_OK;

	if (nftnl_rule_nlmsg_parse(nlh, rule) < 0)
		goto out;

	switch (cb->type) {
	case CALLBACK_RETURN_HANDLE:
		cb->value = nftnl_rule_get_u64(rule, NFTNL_RULE_HANDLE);
		cb->success = true;
		break;

	case CALLBACK_RETURN_BYTE_COUNTER:
		nftnl_expr_foreach(rule, rule_expr_cb, cb);
		break;

	default:
		DBG("unhandled callback type %d\n", cb->type);
		break;
	}

out:
	nftnl_rule_free(rule);
	return MNL_CB_STOP;
}
Exemplo n.º 9
0
static int build_rule_nat(const char *address, unsigned char prefixlen,
				const char *interface, struct nftnl_rule **res)
{
	struct nftnl_rule *rule;
	struct in_addr ipv4_addr, ipv4_mask;
	struct nftnl_expr *expr;
	int err;

	/*
	 * # nft --debug netlink add rule connman nat-postrouting	\
	 *	oifname eth0 ip saddr 10.10.0.0/24 masquerade
	 *
	 *	ip connman nat-postrouting
	 *	  [ meta load oifname => reg 1 ]
	 *	  [ cmp eq reg 1 0x30687465 0x00000000 0x00000000 0x00000000 ]
	 *	  [ payload load 4b @ network header + 12 => reg 1 ]
	 *	  [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ]
	 *	  [ cmp eq reg 1 0x00000a0a ]
	 *	  [ masq ]
	 */

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, CONNMAN_CHAIN_NAT_POST);

	/* family ipv4 */
	nftnl_rule_set_u32(rule, NFTNL_RULE_FAMILY, NFPROTO_IPV4);

	/* oifname */
	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_OIFNAME);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, interface,
			strlen(interface) + 1);
	if (err < 0)
		goto err;

	/* source */
	ipv4_mask.s_addr = htonl((0xffffffff << (32 - prefixlen)) & 0xffffffff);
	ipv4_addr.s_addr = inet_addr(address);
	ipv4_addr.s_addr &= ipv4_mask.s_addr;

	err = add_payload(rule, NFT_PAYLOAD_NETWORK_HEADER, NFT_REG_1,
			offsetof(struct iphdr, saddr), sizeof(struct in_addr));
	if (err < 0)
		goto err;
	err = add_bitwise(rule, NFT_REG_1, &ipv4_mask.s_addr,
				sizeof(struct in_addr));
	if (err < 0)
		goto err;
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, &ipv4_addr.s_addr,
			sizeof(struct in_addr));
	if (err < 0)
		goto err;

	/* masquerade */
        expr = nftnl_expr_alloc("masq");
        if (!expr)
		goto err;
        nftnl_rule_add_expr(rule, expr);

	*res = rule;
	return 0;

err:
	nftnl_rule_free(rule);
	return -ENOMEM;
}
Exemplo n.º 10
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	struct nftnl_rule *r;
	struct nlmsghdr *nlh;
	struct mnl_nlmsg_batch *batch;
	uint8_t family;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	uint32_t seq = time(NULL);
	int ret;

	if (argc < 4 || argc > 5) {
		fprintf(stderr, "Usage: %s <family> <table> <chain>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	if (strcmp(argv[1], "ip") == 0)
		family = NFPROTO_IPV4;
	else if (strcmp(argv[1], "ip6") == 0)
		family = NFPROTO_IPV6;
	else {
		fprintf(stderr, "Unknown family: ip, ip6\n");
		exit(EXIT_FAILURE);
	}

	if (argc != 5)
		r = setup_rule(family, argv[2], argv[3], NULL);
	else
		r = setup_rule(family, argv[2], argv[3], argv[4]);

	nl = mnl_socket_open(NETLINK_NETFILTER);
	if (nl == NULL) {
		perror("mnl_socket_open");
		exit(EXIT_FAILURE);
	}

	if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
		perror("mnl_socket_bind");
		exit(EXIT_FAILURE);
	}

	batch = mnl_nlmsg_batch_start(buf, sizeof(buf));

	nftnl_mnl_batch_put(mnl_nlmsg_batch_current(batch),
			  NFNL_MSG_BATCH_BEGIN, seq++);
	mnl_nlmsg_batch_next(batch);

	nlh = nftnl_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
			NFT_MSG_NEWRULE,
			nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY),
			NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK, seq++);

	nftnl_rule_nlmsg_build_payload(nlh, r);
	nftnl_rule_free(r);
	mnl_nlmsg_batch_next(batch);

	nftnl_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END,
			 seq++);
	mnl_nlmsg_batch_next(batch);

	ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch),
				mnl_nlmsg_batch_size(batch));
	if (ret == -1) {
		perror("mnl_socket_sendto");
		exit(EXIT_FAILURE);
	}

	mnl_nlmsg_batch_stop(batch);

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	if (ret == -1) {
		perror("mnl_socket_recvfrom");
		exit(EXIT_FAILURE);
	}

	ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(nl), NULL, NULL);
	if (ret < 0) {
		perror("mnl_cb_run");
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}