示例#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;
}
示例#2
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;
}
示例#3
0
//Out cleanup callback, nothing interesting here
static void nt_linux_cleanup(struct neat_ctx *nc)
{
    if (nc->mnl_sock)
        mnl_socket_close(nc->mnl_sock);

    free(nc->mnl_rcv_buf);
}
示例#4
0
int main(void)
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	int ret;

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

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

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return 0;
}
示例#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;
}
示例#6
0
static int cleanup_table_and_chains(void)
{
	struct nftnl_table *table;
	struct mnl_socket *nl;
	int err;

	DBG("");

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

	/*
	 * Cleanup everythying in one go. There is little point in
	 * step-by-step removal of rules and chains if you can get it
	 * as simple as this.
	 */
	/*
	 * # nft delete table connman
	 */
	table = build_table(CONNMAN_TABLE, NFPROTO_IPV4);
	err = table_cmd(nl, table, NFT_MSG_DELTABLE, NFPROTO_IPV4, NLM_F_ACK);

	mnl_socket_close(nl);
	return err;
}
示例#7
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;
	int ret;
	unsigned int seq, portid;

	if (argc != 2) {
		printf("%s [family name]\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= GENL_ID_CTRL;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_seq = seq = time(NULL);

	genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
	genl->cmd = CTRL_CMD_GETFAMILY;
	genl->version = 1;

	mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL);
	mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, argv[1]);

	nl = mnl_socket_open(NETLINK_GENERIC);
	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return 0;
}
示例#8
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct rtmsg *rtm;
	int ret;
	unsigned int seq, portid;

	if (argc != 2) {
		fprintf(stderr, "Usage: %s <inet|inet6>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = RTM_GETROUTE;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	nlh->nlmsg_seq = seq = time(NULL);
	rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));

	if (strcmp(argv[1], "inet") == 0)
		rtm->rtm_family = AF_INET;
	else if (strcmp(argv[1], "inet6") == 0)
		rtm->rtm_family = AF_INET6;

	nl = mnl_socket_open(NETLINK_ROUTE);
	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
		if (ret <= MNL_CB_STOP)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return 0;
}
示例#9
0
int nftnl_batch_is_supported(void)
{
	struct mnl_socket *nl;
	struct mnl_nlmsg_batch *b;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	uint32_t seq = time(NULL), req_seq;
	int ret;

	nl = mnl_socket_open(NETLINK_NETFILTER);
	if (nl == NULL)
		return -1;

	if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
		return -1;

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

	nftnl_batch_begin(mnl_nlmsg_batch_current(b), seq++);
	mnl_nlmsg_batch_next(b);

	req_seq = seq;
	nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(b),
				NFT_MSG_NEWSET, AF_INET,
				NLM_F_ACK, seq++);
	mnl_nlmsg_batch_next(b);

	nftnl_batch_end(mnl_nlmsg_batch_current(b), seq++);
	mnl_nlmsg_batch_next(b);

	ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b),
				mnl_nlmsg_batch_size(b));
	if (ret < 0)
		goto err;

	mnl_nlmsg_batch_stop(b);

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, req_seq, mnl_socket_get_portid(nl),
				 NULL, NULL);
		if (ret <= 0)
			break;

		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	mnl_socket_close(nl);

	/* We're sending an incomplete message to see if the kernel supports
	 * set messages in batches. EINVAL means that we sent an incomplete
	 * message with missing attributes. The kernel just ignores messages
	 * that we cannot include in the batch.
	 */
	return (ret == -1 && errno == EINVAL) ? 1 : 0;
err:
	mnl_nlmsg_batch_stop(b);
	return -1;
}
int main(int argc, char *argv[])
{
	char buf[getpagesize()];
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;
	struct mnl_socket *nl;
	int ret;
	unsigned int seq, oper, portid;

	if (argc != 2) {
		printf("%s <genetlink family ID>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = atoi(argv[1]);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_seq = seq = time(NULL);
	genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
	genl->cmd = NLEX_CMD_GET;

	nl = mnl_socket_open(NETLINK_GENERIC);
	if (nl == NULL) {
		perror("mnl_socket_open");
		exit(EXIT_FAILURE);
	}
	ret = mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID);
	if (ret == -1) {
		perror("mnl_socket_bind");
		exit(EXIT_FAILURE);
	}
	portid = mnl_socket_get_portid(nl);

	ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
	if (ret == -1) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

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

	ret = mnl_cb_run(buf, ret, seq, portid, cb, NULL);
	if (ret == -1) {
		perror("mnl_cb_run");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	printf("done\n");

	return 0;
}
示例#11
0
int main(void)
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfh;
	uint32_t seq, portid;
	int ret;

	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);
	}

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET;
	nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
	nlh->nlmsg_seq = seq = time(NULL);

	nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
	nfh->nfgen_family = AF_INET;
	nfh->version = NFNETLINK_V0;
	nfh->res_id = 0;

	ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
	if (ret == -1) {
		perror("mnl_socket_sendto");
		exit(EXIT_FAILURE);
	}
	portid = mnl_socket_get_portid(nl);

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

		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
		if (ret == -1) {
			perror("mnl_cb_run");
			exit(EXIT_FAILURE);
		} else if (ret <= MNL_CB_STOP)
                        break;
	}

	mnl_socket_close(nl);

	return 0;
}
示例#12
0
/* method: close */
static int mnl_socket__close__meth(lua_State *L) {
  int this_flags_idx1 = 0;
  mnl_socket * this_idx1;
  int rc_mnl_socket_close_idx1 = 0;
  this_idx1 = obj_type_mnl_socket_delete(L,1,&(this_flags_idx1));
  if(!(this_flags_idx1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
  rc_mnl_socket_close_idx1 = mnl_socket_close(this_idx1);
  lua_pushinteger(L, rc_mnl_socket_close_idx1);
  return 1;
}
示例#13
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;
}
示例#14
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	int ret, type;

	switch (argc) {
	case 1:
		type = NFT_OUTPUT_DEFAULT;
		break;
	case 2:
		if (strcmp(argv[1], "xml") == 0) {
			type = NFT_OUTPUT_XML;
		} else if (strcmp(argv[1], "json") == 0) {
			type = NFT_OUTPUT_JSON;
		} else if (strcmp(argv[1], "default") == 0) {
			type = NFT_OUTPUT_DEFAULT;
		} else {
			fprintf(stderr, "unknown format type `%s'\n", argv[1]);
			return EXIT_FAILURE;
		}
		break;
	default:
		fprintf(stderr, "%s [<default|xml|json>]\n", argv[0]);
		return EXIT_FAILURE;
	}

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

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

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
示例#15
0
int main(void)
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct rtgenmsg *rt;
	int ret;
	unsigned int seq, portid;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= RTM_GETLINK;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	nlh->nlmsg_seq = seq = time(NULL);
	rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
	rt->rtgen_family = AF_PACKET;

	nl = mnl_socket_open(NETLINK_ROUTE);
	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
		if (ret <= MNL_CB_STOP)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return 0;
}
示例#16
0
文件: nfq.c 项目: chamaken/nurs
static enum nurs_return_t nfq_organize(struct nurs_producer *producer)
{
	struct nfq_priv *priv = nurs_producer_context(producer);

	if (nfq_common_organize(producer) != NURS_RET_OK)
		return NURS_RET_ERROR;

	priv->fd = nurs_fd_create(mnl_socket_get_fd(priv->nl),
				  NURS_FD_F_READ);
	if (!priv->fd)
		goto fail;
	return NURS_RET_OK;
fail:
#ifdef NLMMAP
	mnl_socket_unmap(priv->nlr);
#endif
	mnl_socket_close(priv->nl);
	return NURS_RET_ERROR;

}
示例#17
0
int main(int argc, char ** argv) {
	struct mnl_socket * nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	int ret;

	program = argv[0];

	printf("%s: %s v%s (compiled: %s)\n", argv[0], PROGNAME, VERSION, DATE);

	if(!notify_init("Netlink-Notification")) {
		fprintf(stderr, "%s: Can't create notify.\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	nl = mnl_socket_open(NETLINK_ROUTE);
	if (!nl) {
		fprintf(stderr, "%s: Can't create netlink socket.\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	if (mnl_socket_bind(nl, RTMGRP_LINK, MNL_SOCKET_AUTOPID) < 0) {
		fprintf(stderr, "%s: Can't bind netlink socket.\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		fprintf(stderr, "%s: An error occured reading from netlink socket.\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
示例#18
0
int main(void)
{
        char buf[getpagesize()];
        struct nlmsghdr *nlh;
        struct mnl_socket *nl;
        int ret;
        unsigned int seq, portid;

        nlh = mnl_nlmsg_put_header(buf);
        nlh->nlmsg_type = NLEX_MSG_UPD;
        nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
        nlh->nlmsg_seq = seq = time(NULL);
		nlh->nlmsg_pid = getpid();

        mnl_attr_put_u32(nlh, NLE_MYVAR, 31337);

        nl = mnl_socket_open(NETLINK_EXAMPLE);
        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);
        }
        portid = mnl_socket_get_portid(nl);

        if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
                perror("mnl_socket_sendto");
                exit(EXIT_FAILURE);
        }

        ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
        if (ret == -1) {
                perror("mnl_cb_callback");
                exit(EXIT_FAILURE);
        }
        mnl_socket_close(nl);

        return 0;
}
示例#19
0
static int socket_open_and_bind(struct mnl_socket **n)
{

	struct mnl_socket *nl = NULL;
        int err;

        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (!nl)
                return -errno;

        err = mnl_socket_bind(nl, 1 << (NFNLGRP_NFTABLES-1),
				MNL_SOCKET_AUTOPID);
        if (err < 0) {
		err = errno;
		mnl_socket_close(nl);
                return -err;
	}

        *n = nl;
        return 0;
}
示例#20
0
文件: msg.c 项目: dtaht/tc-adv
static int msg_recv(struct mnl_socket *nl, mnl_cb_t callback, void *data, int seq)
{
	int ret;
	unsigned int portid;
	char buf[MNL_SOCKET_BUFFER_SIZE];

	portid = mnl_socket_get_portid(nl);

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, callback, data);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1)
		perror("error");

	mnl_socket_close(nl);

	return ret;
}
示例#21
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	int ret;
	unsigned int portid, queue_num;

	if (argc != 2) {
		printf("Usage: %s [queue_num]\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	queue_num = atoi(argv[1]);

	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);
	}
	portid = mnl_socket_get_portid(nl);

	nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_UNBIND);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_BIND);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	if (ret == -1) {
		perror("mnl_socket_recvfrom");
		exit(EXIT_FAILURE);
	}
	while (ret > 0) {
		uint32_t id;

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

		id = ret - MNL_CB_OK;
		nlh = nfq_build_verdict(buf, id, queue_num, NF_ACCEPT);
		if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
			perror("mnl_socket_send");
			exit(EXIT_FAILURE);
		}

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

	mnl_socket_close(nl);

	return 0;
}
示例#22
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	uint32_t portid, seq, table_seq, family;
	struct nft_table *t;
	struct mnl_nlmsg_batch *batch;
	int ret, batching;

	if (argc != 3) {
		fprintf(stderr, "%s <family> <name>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	t = table_add_parse(argc, argv);
	if (t == NULL)
		exit(EXIT_FAILURE);

	batching = nft_batch_is_supported();
	if (batching < 0) {
		perror("cannot talk to nfnetlink");
		exit(EXIT_FAILURE);
	}

	seq = time(NULL);
	batch = mnl_nlmsg_batch_start(buf, sizeof(buf));

	if (batching) {
		nft_batch_begin(mnl_nlmsg_batch_current(batch), seq++);
		mnl_nlmsg_batch_next(batch);
	}

	table_seq = seq;
	family = nft_table_attr_get_u32(t, NFT_TABLE_ATTR_FAMILY);
	nlh = nft_table_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
					NFT_MSG_NEWTABLE, family,
					NLM_F_ACK, seq++);
	nft_table_nlmsg_build_payload(nlh, t);
	nft_table_free(t);
	mnl_nlmsg_batch_next(batch);

	if (batching) {
		nft_batch_end(mnl_nlmsg_batch_current(batch), seq++);
		mnl_nlmsg_batch_next(batch);
	}

	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch),
			      mnl_nlmsg_batch_size(batch)) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	mnl_nlmsg_batch_stop(batch);

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, table_seq, portid, NULL, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
示例#23
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct mnl_nlmsg_batch *batch;
	uint32_t portid, seq;
	struct nft_rule *r = NULL;
	int ret, family;

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

	r = nft_rule_alloc();
	if (r == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}

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

	seq = time(NULL);
	nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, argv[2]);
	nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, argv[3]);

	/* If no handle is specified, delete all rules in the chain */
	if (argc == 5)
		nft_rule_attr_set_u64(r, NFT_RULE_ATTR_HANDLE, atoi(argv[4]));

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

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

	nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
				NFT_MSG_DELRULE,
				family,
				NLM_F_ACK, seq++);

	nft_rule_nlmsg_build_payload(nlh, r);
	nft_rule_free(r);
	mnl_nlmsg_batch_next(batch);

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

	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch),
			      mnl_nlmsg_batch_size(batch)) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	mnl_nlmsg_batch_stop(batch);

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, 0, portid, NULL, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
示例#24
0
文件: nflog.c 项目: t0mm13b/afwall
void cleanup(void) {
  if(nl != 0)
    mnl_socket_close(nl);
  free_net_devices();
}
示例#25
0
void *nfacct_main(void *ptr) {
	if(ptr) { ; }

	info("NFACCT thread created with task id %d", gettid());

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("nfacct.plugin: Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("nfacct.plugin: Cannot set pthread cancel state to ENABLE.");

	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct mnl_socket *nl = NULL;
	struct nlmsghdr *nlh = NULL;
	unsigned int seq = 0, portid = 0;

	seq = time(NULL) - 1;

	nl  = mnl_socket_open(NETLINK_NETFILTER);
	if(!nl) {
		error("nfacct.plugin: mnl_socket_open() failed");
		pthread_exit(NULL);
		return NULL;
	}

	if(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
		mnl_socket_close(nl);
		error("nfacct.plugin: mnl_socket_bind() failed");
		pthread_exit(NULL);
		return NULL;
	}
	portid = mnl_socket_get_portid(nl);

	// ------------------------------------------------------------------------

	struct timeval last, now;
	unsigned long long usec = 0, susec = 0;
	RRDSET *st = NULL;

	gettimeofday(&last, NULL);

	// ------------------------------------------------------------------------

	while(1) {
		if(unlikely(netdata_exit)) break;

		seq++;

		nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq);
		if(!nlh) {
			mnl_socket_close(nl);
			error("nfacct.plugin: nfacct_nlmsg_build_hdr() failed");
			pthread_exit(NULL);
			return NULL;
		}

		if(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
			error("nfacct.plugin: mnl_socket_send");
			pthread_exit(NULL);
			return NULL;
		}

		if(nfacct_list) nfacct_list->len = 0;

		int ret;
		while((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) {
			if((ret = mnl_cb_run(buf, ret, seq, portid, nfacct_callback, NULL)) <= 0) break;
		}

		if (ret == -1) {
			error("nfacct.plugin: error communicating with kernel.");
			pthread_exit(NULL);
			return NULL;
		}

		// --------------------------------------------------------------------

		gettimeofday(&now, NULL);
		usec = usecdiff(&now, &last) - susec;
		debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);

		if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec;
		else susec = rrd_update_every * 1000000ULL / 2ULL;


		// --------------------------------------------------------------------

		if(nfacct_list && nfacct_list->len) {
			int i;

			st = rrdset_find_bytype("netfilter", "nfacct_packets");
			if(!st) {
				st = rrdset_create("netfilter", "nfacct_packets", NULL, "nfacct", NULL, "Netfilter Accounting Packets", "packets/s", 1006, rrd_update_every, RRDSET_TYPE_STACKED);

				for(i = 0; i < nfacct_list->len ; i++)
					rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL);
			}
			else rrdset_next(st);

			for(i = 0; i < nfacct_list->len ; i++) {
				RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name);

				if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL);
				if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts);
			}

			rrdset_done(st);

			// ----------------------------------------------------------------

			st = rrdset_find_bytype("netfilter", "nfacct_bytes");
			if(!st) {
				st = rrdset_create("netfilter", "nfacct_bytes", NULL, "nfacct", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 1007, rrd_update_every, RRDSET_TYPE_STACKED);

				for(i = 0; i < nfacct_list->len ; i++)
					rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
			}
			else rrdset_next(st);

			for(i = 0; i < nfacct_list->len ; i++) {
				RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name);

				if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
				if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes);
			}

			rrdset_done(st);
		}

		// --------------------------------------------------------------------

		usleep(susec);

		// copy current to last
		bcopy(&now, &last, sizeof(struct timeval));
	}

	mnl_socket_close(nl);
	pthread_exit(NULL);
	return NULL;
}
示例#26
0
static int create_table_and_chains(struct nftables_info *nft_info)
{
	struct mnl_socket *nl;
	struct nftnl_table *table;
	struct nftnl_chain *chain;
	int err;


	DBG("");

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

	/*
	 * Add table
	 * http://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables
	 */

	/*
	 * # nft add table connman
	 */
	table = build_table(CONNMAN_TABLE, NFPROTO_IPV4);
	if (!table) {
		err = -ENOMEM;
		goto out;
	}

        err = table_cmd(nl, table, NFT_MSG_NEWTABLE, NFPROTO_IPV4,
			NLM_F_CREATE|NLM_F_ACK);
        if (err < 0)
                goto out;

	/*
	 * Add basic chains
	 * http://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains
	 */

	/*
	 * # nft add chain connman nat-prerouting		\
	 *	{ type nat hook prerouting priority 0 ; }
	 */
	chain = build_chain(CONNMAN_CHAIN_NAT_PRE, CONNMAN_TABLE,
				"nat", NF_INET_PRE_ROUTING, 0);
	if (!chain) {
		err = -ENOMEM;
		goto out;
	}

	err = chain_cmd(nl, chain, NFT_MSG_NEWCHAIN,
			NFPROTO_IPV4, NLM_F_CREATE | NLM_F_ACK,
			CALLBACK_RETURN_NONE, NULL);
	if (err < 0)
		goto out;

	/*
	 * # nft add chain connman nat-postrouting		\
	 *	{ type nat hook postrouting priority 0 ; }
	 */
	chain = build_chain(CONNMAN_CHAIN_NAT_POST, CONNMAN_TABLE,
				"nat", NF_INET_POST_ROUTING, 0);
	if (!chain) {
		err = -ENOMEM;
		goto out;
	}

	err = chain_cmd(nl, chain, NFT_MSG_NEWCHAIN,
			NFPROTO_IPV4, NLM_F_CREATE | NLM_F_ACK,
			CALLBACK_RETURN_NONE, NULL);
	if (err < 0)
		goto out;

	/*
	 * # nft add chain connman route-output		\
	 *	{ type route hook output priority 0 ; }
	 */
	chain = build_chain(CONNMAN_CHAIN_ROUTE_OUTPUT, CONNMAN_TABLE,
				"route", NF_INET_LOCAL_OUT, 0);
	if (!chain) {
		err = -ENOMEM;
		goto out;
	}

	err = chain_cmd(nl, chain, NFT_MSG_NEWCHAIN,
			NFPROTO_IPV4, NLM_F_CREATE | NLM_F_ACK,
			CALLBACK_RETURN_NONE, NULL);
	if (err < 0)
		goto out;

out:
	if (err)
		connman_warn("Failed to create basic chains: %s",
				strerror(-err));
	mnl_socket_close(nl);
	return err;
}
示例#27
0
int main(void)
{
	struct mnl_socket *nl;
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfh;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	unsigned int seq, portid;
	struct nf_conntrack *ct;
	int ret;

	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);
	}
	portid = mnl_socket_get_portid(nl);

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_DELETE;
	nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
	nlh->nlmsg_seq = seq = time(NULL);

	nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
	nfh->nfgen_family = AF_INET;
	nfh->version = NFNETLINK_V0;
	nfh->res_id = 0;

	ct = nfct_new();
	if (ct == NULL) {
		perror("nfct_new");
		return 0;
	}

	nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(ct, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
	nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr("2.2.2.2"));

	nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(20));
	nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(10));

	nfct_nlmsg_build(nlh, ct);

	ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
	if (ret == -1) {
		perror("mnl_socket_recvfrom");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
		if (ret <= MNL_CB_STOP)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("mnl_socket_recvfrom");
		exit(EXIT_FAILURE);
	}

	mnl_socket_close(nl);

	return 0;
}
示例#28
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	uint32_t portid, seq, family, data;
	struct nft_set *s;
	struct nft_set_elem *e;
	int ret;

	if (argc != 4) {
		fprintf(stderr, "%s <family> <table> <set>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	s = nft_set_alloc();
	if (s == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}

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

	nft_set_attr_set(s, NFT_SET_ATTR_TABLE, argv[2]);
	nft_set_attr_set(s, NFT_SET_ATTR_NAME, argv[3]);

	/* Add to dummy elements to set */
	e = nft_set_elem_alloc();
	if (e == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}

	data = 0x1;
	nft_set_elem_attr_set(e, NFT_SET_ELEM_ATTR_KEY, &data, sizeof(data));
	nft_set_elem_add(s, e);

	e = nft_set_elem_alloc();
	if (e == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}
	data = 0x2;
	nft_set_elem_attr_set(e, NFT_SET_ELEM_ATTR_KEY, &data, sizeof(data));
	nft_set_elem_add(s, e);

	nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_NEWSETELEM, family,
				      NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK, seq);
	nft_set_elems_nlmsg_build_payload(nlh, s);
	nft_set_free(s);

	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
示例#29
0
int main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	uint32_t portid, seq, family;
	uint32_t type = NFT_OUTPUT_DEFAULT;
	struct nft_set *t = NULL;
	int ret;

	if (argc < 4 || argc > 5) {
		fprintf(stderr, "%s <family> <table> <set> [<json|xml>]\n",
			argv[0]);
		return EXIT_FAILURE;
	}
	t = nft_set_alloc();
	if (t == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}
	seq = time(NULL);
	if (strcmp(argv[1], "ip") == 0)
		family = NFPROTO_IPV4;
	else if (strcmp(argv[1], "ip6") == 0)
		family = NFPROTO_IPV6;
	else if (strcmp(argv[1], "bridge") == 0)
		family = NFPROTO_BRIDGE;
	else if (strcmp(argv[1], "arp") == 0)
		family = NFPROTO_ARP;
	else {
		fprintf(stderr, "Unknown family: ip, ip6, bridge, arp\n");
		exit(EXIT_FAILURE);
	}

	if (argc == 5 && strcmp(argv[4], "json") == 0 )
		type = NFT_OUTPUT_JSON;
	else if (argc == 5 && strcmp(argv[4], "xml") == 0)
		type = NFT_OUTPUT_XML;

	nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, family,
					NLM_F_DUMP|NLM_F_ACK, seq);
	nft_set_attr_set(t, NFT_SET_ATTR_NAME, argv[3]);
	nft_set_attr_set(t, NFT_SET_ATTR_TABLE, argv[2]);
	nft_set_elems_nlmsg_build_payload(nlh, t);
	nft_set_free(t);

	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);
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, set_cb, &type);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
示例#30
0
static int32_t multi_link_event_loop(struct multi_config *mc){
    struct multi_link_info *li;
    pthread_attr_t detach_attr;
    uint8_t buf[MAX_PIPE_MSG_LEN];
    uint8_t mnl_buf[MNL_SOCKET_BUFFER_SIZE];
    int32_t retval, numbytes;
    uint32_t i;
    int32_t mnl_sock_event, mnl_sock_set, mnl_sock_get;
    fd_set masterfds, readfds;
    int fdmax = 0;
    struct timeval tv;

    FD_ZERO(&masterfds);
    FD_ZERO(&readfds);

    //NETLINK_ROUTE is where I want to hook into the kernel
    if(!(multi_link_nl_request = mnl_socket_open(NETLINK_ROUTE))){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create mnl socket (request)\n");
        return EXIT_FAILURE;
    }

    if(!(multi_link_nl_set = mnl_socket_open(NETLINK_ROUTE))){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create mnl socket (set)\n");
        return EXIT_FAILURE;
    }

    if(!(multi_link_nl_event = mnl_socket_open(NETLINK_ROUTE))){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create mnl socket (event)\n");
        return EXIT_FAILURE;
    }

    if(mnl_socket_bind(multi_link_nl_request, 0, MNL_SOCKET_AUTOPID) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not bind mnl event socket\n");
        mnl_socket_close(multi_link_nl_event);
        return EXIT_FAILURE;
    }

    if(mnl_socket_bind(multi_link_nl_set, 0, MNL_SOCKET_AUTOPID) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not bind mnl event socket\n");
        mnl_socket_close(multi_link_nl_event);
        return EXIT_FAILURE;
    }

    if(mnl_socket_bind(multi_link_nl_event, 1 << (RTNLGRP_LINK - 1), MNL_SOCKET_AUTOPID) 
            < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not bind mnl event socket\n");
        mnl_socket_close(multi_link_nl_event);
        return EXIT_FAILURE;
    }

    if(pipe(multi_link_dhcp_pipes) < 0){
        //perror("Pipe failed\n");
        MULTI_DEBUG_PRINT_SYSLOG(stderr,"Pipe failed\n");
        return EXIT_FAILURE;
    }

    /* Find interfaces that are already up, removes info and then reruns 
     * DHCP (need config) */
    multi_link_populate_links_list();

    /* Check if I have any PPP links. */
    //TODO: Give this one a better name since it is not only for PPP any more
    LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_ppp, li, NULL);

    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Done populating links list!\n");

    if(multi_link_flush_links() == EXIT_FAILURE)
        return EXIT_FAILURE;

    //Go through already seen interfaces and start DHCP as needed
    if(multi_link_num_links > 0){
        pthread_attr_init(&detach_attr);
        pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED);

        for(li = multi_link_links_2.lh_first; li != NULL;
                li = li->next.le_next){
            /* Start DHCP */
            if(li->state == WAITING_FOR_DHCP){
                MULTI_DEBUG_PRINT_SYSLOG(stderr, "Starting DHCP for existing "
                        "interface %s\n", li->dev_name);
                pthread_create(&(li->dhcp_thread), &detach_attr, 
                        multi_dhcp_main, (void *) li);
            }
        }
    }

	/* Do a scan of the list here to check for links with static IP/PPP */
    LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_link, li, mc);

    mnl_sock_event = mnl_socket_get_fd(multi_link_nl_event);
    mnl_sock_set = mnl_socket_get_fd(multi_link_nl_set);
    mnl_sock_get = mnl_socket_get_fd(multi_link_nl_request);

    FD_SET(mnl_sock_event, &masterfds); 
    fdmax = fdmax > mnl_sock_event ? fdmax : mnl_sock_event;
    FD_SET(mnl_sock_get, &masterfds);
    fdmax = fdmax > mnl_sock_get ? fdmax : mnl_sock_get;
    FD_SET(mnl_sock_set, &masterfds);
    fdmax = fdmax > mnl_sock_set ? fdmax : mnl_sock_set;
    FD_SET(multi_link_dhcp_pipes[0], &masterfds);
    fdmax = fdmax > multi_link_dhcp_pipes[0] ? fdmax : multi_link_dhcp_pipes[0];

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    while(1){
        readfds = masterfds;

        retval = select(fdmax+1, &readfds, NULL, NULL, &tv);

        if(retval == 0){
            //Check for any PPP that is marked as down 
            LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_ppp,
                    li, NULL);
            LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_link,
                    li, mc);

            tv.tv_sec = 5;
            tv.tv_usec = 0;
            continue;
        }

        //TODO: Rewrite this so I only call the callbacks at the end, not per
        //message
        for(i=0; i<=fdmax; i++){
            if(FD_ISSET(i, &readfds)){
                if (i == mnl_sock_event){
                    numbytes = mnl_socket_recvfrom(multi_link_nl_event, 
                            mnl_buf, sizeof(mnl_buf));
                    mnl_cb_run(mnl_buf, numbytes, 0, 0, 
                            multi_link_parse_netlink, mc);
                    LIST_FOREACH_CB(&multi_link_links_2, next,
                            multi_link_check_link, li, mc);
                } else if (i == mnl_sock_set){
                    numbytes = mnl_socket_recvfrom(multi_link_nl_set, mnl_buf, 
                            sizeof(mnl_buf));
                } else if (i == mnl_sock_get){
                    numbytes = mnl_socket_recvfrom(multi_link_nl_request, 
                            mnl_buf, sizeof(mnl_buf));
                } else if (i == multi_link_dhcp_pipes[0]){
                    numbytes = read(i, buf, MAX_PIPE_MSG_LEN);
                    LIST_FOREACH_CB(&multi_link_links_2, next,
                            multi_link_check_link, li, mc);
                    multi_link_clean_links();
                }
            } 
        }
    }
}