Exemple #1
0
static int32_t multi_link_flush_links(){
    struct ip_info ip_info;
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtgenmsg *rt;
    uint32_t seq;

    memset(buf, 0, MNL_SOCKET_BUFFER_SIZE);
    memset(&ip_info, 0, sizeof(ip_info));

    //Initialize list
    TAILQ_INIT(&(ip_info.ip_addr_n));
    TAILQ_INIT(&(ip_info.ip_rules_n));
    TAILQ_INIT(&(ip_info.ip_routes_n));

    //Sets room for one nlmsghdr in buffer buf
    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = RTM_GETADDR;
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
    nlh->nlmsg_seq = seq = time(NULL); //How will this work with event? Send 0?
    rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
    rt->rtgen_family = AF_INET; //I need all interfaces

    //Address
    if(mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Cannot request address dump\n");
        return EXIT_FAILURE;
    }

    multi_link_filter(seq, multi_link_filter_ipaddr, &ip_info);

    //Rules
    nlh->nlmsg_type = RTM_GETRULE;
    if(mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Cannot request rules dump\n");
        return EXIT_FAILURE;
    }

    multi_link_filter(seq, multi_link_filter_iprules, &ip_info);

    //Routes
    nlh->nlmsg_type = RTM_GETROUTE;
    if(mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Cannot request rules dump\n");
        return EXIT_FAILURE;
    }

    multi_link_filter(seq, multi_link_filter_iproutes, &ip_info);
 
    /* Remove existing information and free memory */
    multi_link_del_info(ip_info.ip_routes_n, RTM_DELROUTE);
    multi_link_del_info(ip_info.ip_rules_n, RTM_DELRULE);
    multi_link_del_info(ip_info.ip_addr_n, RTM_DELADDR);
    multi_link_free_ip_info(&ip_info);
    return EXIT_SUCCESS;
}
Exemple #2
0
static void multi_link_populate_links_list(){
    //MNL_SOCKET_BUFFER_SIZE is 8k, which is the max nlmsg size (see
    //linux/netlink.h)
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtgenmsg *rt;
    uint32_t seq;

    memset(buf, 0, MNL_SOCKET_BUFFER_SIZE);

    //Sets room for one nlmsghdr in buffer buf
    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); //How will this work with event? Send 0?
    rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
    rt->rtgen_family = AF_UNSPEC; //I need all interfaces

    if(mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Cannot request info dump\n");
        return;
    }

    multi_link_filter(seq, multi_link_filter_links, NULL);
}
Exemple #3
0
static struct mnl_socket *msg_send(struct nlmsghdr *nlh)
{
	int ret;
	struct mnl_socket *nl;

	nl = mnl_socket_open(NETLINK_GENERIC);
	if (nl == NULL) {
		perror("mnl_socket_open");
		return NULL;
	}

	ret = mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID);
	if (ret < 0) {
		perror("mnl_socket_bind");
		return NULL;
	}

	ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
	if (ret < 0) {
		perror("mnl_socket_send");
		return NULL;
	}

	return nl;
}
Exemple #4
0
/* Add/delete ip rule */
static int32_t multi_link_modify_rule(uint32_t msg_type, uint32_t flags, 
        uint32_t table_id, struct multi_link_info *li){
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtmsg *rt;

    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = msg_type;
    nlh->nlmsg_flags = NLM_F_REQUEST | flags;
    nlh->nlmsg_seq = 0;

    rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
    rt->rtm_family = AF_INET;
    rt->rtm_dst_len = 0;
    rt->rtm_table = table_id; //The table to perform the lookup in
    rt->rtm_protocol = RTPROT_BOOT;
    rt->rtm_scope = RT_SCOPE_UNIVERSE;
    rt->rtm_type = RTN_UNICAST;
    //Need the length of the src address that will be provided later on
    rt->rtm_src_len = 32; 
    mnl_attr_put_u32(nlh, FRA_SRC, li->cfg.address.s_addr);

    if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT(stderr,"Could not send gateway to kernel "
                "(can be ignored if caused by an interface that went down, "
                "iface idx %u)\n", li->ifi_idx);
        return -1;
    }

    return 0;

}
Exemple #5
0
void multi_link_get_iface_info(struct multi_link_info *li){
    //MNL_SOCKET_BUFFER_SIZE is 8k, which is the max nlmsg size (see
    //linux/netlink.h)
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtgenmsg *rt;
    uint32_t seq;

    //It seems like I cant request one interface, has to dump!
    ////Play with this later and see what is up
    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = RTM_GETADDR;
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
    nlh->nlmsg_seq = seq = time(NULL); //How will this work with event? Send 0?
    rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
    //I need all interfaces, also those without IP (check)
    rt->rtgen_family = AF_UNSPEC; 

    if(mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT(stderr, "Cannot request info dump\n");
        return;
    }

    if(li->state == LINK_DOWN_PPP)
        multi_link_filter(seq, multi_link_filter_ppp, (void*) li);
    else if(li->state == LINK_DOWN_AP)
        multi_link_filter(seq, multi_link_filter_ap, (void*) li);
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
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;
}
Exemple #9
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;
}
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;
}
int resolve_genladdr(const char *name, struct tcpe_client* cl)
{
	struct mnl_socket *sock = cl->mnl_sock;
	char buf[MNL_SOCKET_BUFFER_SIZE];

	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;
	int ret;
	unsigned int seq, portid;
	struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
        int fmly_id = 0;
        const char *mcast_grp_name;
	int mcast_grp_id = 0;
	struct nlattr *pos;

	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 = 0;

	mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, name);
	portid = mnl_socket_get_portid(sock);

	if (mnl_socket_sendto(sock, nlh, nlh->nlmsg_len) < 0) {
		dbgprintf("mnl_socket_send");
		return -1;
	}

	while (1) {
		ret = mnl_socket_recvfrom(sock, buf, sizeof(buf));
		if (ret == -1) {
			dbgprintf("mnl_socket_recvfrom");
			break;
		}
		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, tb);
		if (ret == -1) {
			dbgprintf("mnl_cb_run");
			break;
		} else if (ret == 0)
			break;
	}
	if (tb[CTRL_ATTR_FAMILY_ID]) {
                fmly_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
	}

	cl->fam_id = fmly_id;

	return 0;
}
Exemple #12
0
//Addresses and routes are always deleted when an interface goes down, but not
//rules. Netlink is not reliable and there are scenarios where we will loose
//messages and not clean up properly. We therefore need to make sure that there
//exists no rules poining to this address/interface
static int32_t multi_link_rules_sanity(struct multi_link_info *li)
{
    struct ip_info ip_info;
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtgenmsg *rt;
    uint32_t seq;
    int32_t ret;
    struct multi_link_filter_iprule filter_iprule = {0};

    memset(buf, 0, MNL_SOCKET_BUFFER_SIZE);
    memset(&ip_info, 0, sizeof(ip_info));

    //I am lazy and will use ip_info for now
    TAILQ_INIT(&(ip_info.ip_rules_n));

    filter_iprule.li = li;
    ip_info.data = &filter_iprule;

    //Sets room for one nlmsghdr in buffer buf
    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = RTM_GETRULE;
    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_INET; //Multi only supports v4

    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Will check for dirty rules\n");

    if(mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Cannot request rules dump\n");
        return EXIT_FAILURE;
    }

    ret = multi_link_filter(seq, multi_link_filter_iprules_addr, &ip_info);

    if (ret) {
        //Some rules might have been added
        multi_link_free_ip_info(&ip_info);
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Sanity check failed (memory)\n");
        return EXIT_FAILURE;
    }

    if (!ip_info.ip_rules_n.tqh_first)
        return EXIT_SUCCESS;

    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Will delete dirty rules\n");

    multi_link_del_info(ip_info.ip_rules_n, RTM_DELRULE);
    multi_link_free_ip_info(&ip_info);

    return EXIT_SUCCESS;
}
/* method: sendto */
static int mnl_socket__sendto__meth(lua_State *L) {
  mnl_socket * this_idx1;
  const void * req_idx2;
  size_t siz_idx3;
  ssize_t rc_mnl_socket_sendto_idx1 = 0;
  this_idx1 = obj_type_mnl_socket_check(L,1);
  req_idx2 = lua_touserdata(L,2);
  siz_idx3 = luaL_checkinteger(L,3);
  rc_mnl_socket_sendto_idx1 = mnl_socket_sendto(this_idx1, req_idx2, siz_idx3);
  lua_pushinteger(L, rc_mnl_socket_sendto_idx1);
  return 1;
}
Exemple #14
0
static void multi_link_del_info(struct filter_list nlmsg_list, uint16_t nlmsg_type){
    struct filter_msg *msg;
    struct nlmsghdr *nlh;
    uint32_t seq;

    for(msg = nlmsg_list.tqh_first; msg != NULL; msg = msg->list_ptr.tqe_next){
        nlh = (struct nlmsghdr*) &(msg->nlh);
        nlh->nlmsg_type = nlmsg_type;
        nlh->nlmsg_flags = NLM_F_REQUEST;
        nlh->nlmsg_seq = seq = time(NULL);

        mnl_socket_sendto(multi_link_nl_request, nlh, nlh->nlmsg_len);
    }
}
Exemple #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;
}
Exemple #16
0
/* Adds/deletes route. The reason for having metric as a seperate parameter is
 * that the value depends on wether this is the private table (0) or not. If the
 * route is intended for the private table, then ignore metric */
static int32_t multi_link_modify_route(uint32_t msg_type, uint32_t flags, 
        uint32_t table_id, struct multi_link_info *li, uint32_t metric){
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtmsg *rt;
    uint32_t nw_ip = 0;

    //The desired destination IP is store in different places for PPP and
    //"normal" interfaces. This is the network route!
    if(li->state == GOT_IP_PPP || li->state == LINK_UP_PPP)
        nw_ip = li->cfg.broadcast.s_addr;
    else
        nw_ip = li->cfg.address.s_addr & li->cfg.netmask.s_addr;

    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = msg_type;
    nlh->nlmsg_flags = NLM_F_REQUEST | flags;
    nlh->nlmsg_seq = 0;

    rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
 
    rt->rtm_scope = RT_SCOPE_NOWHERE;
    rt->rtm_type = RTN_UNICAST;
    rt->rtm_family = AF_INET;
    rt->rtm_dst_len = 32 - (ffs(ntohl(li->cfg.netmask.s_addr)) - 1);
    rt->rtm_table = table_id;

    if(msg_type != RTM_DELROUTE){
        rt->rtm_protocol = RTPROT_BOOT;
        rt->rtm_scope = RT_SCOPE_LINK;
    }

    mnl_attr_put_u32(nlh, RTA_DST, nw_ip);
    mnl_attr_put_u32(nlh, RTA_PREFSRC, li->cfg.address.s_addr);
    mnl_attr_put_u32(nlh, RTA_OIF, li->ifi_idx);

    if(metric)
        mnl_attr_put_u32(nlh, RTA_PRIORITY, metric);

    if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT(stderr,"Could not send private route to kernel "
                "(can be ignored if caused by an interface that went down, "
                "iface idx %u)\n", li->ifi_idx);
        return -1;
    }

    return 0;
}
Exemple #17
0
//In order to build a list of available source addresses, we need to start by
//requesting all available addresses. That is the work of this function
static ssize_t neat_linux_request_addrs(struct mnl_socket *mnl_sock)
{
    uint8_t snd_buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nl_hdr = mnl_nlmsg_put_header(snd_buf);

    nl_hdr->nlmsg_type = RTM_GETADDR;
    nl_hdr->nlmsg_pid = getpid();
    nl_hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;

    struct rtgenmsg* rt_msg = (struct rtgenmsg*)
        mnl_nlmsg_put_extra_header(nl_hdr, sizeof(struct rtgenmsg));
    rt_msg->rtgen_family = AF_UNSPEC;

    //We should probably have used libuv send function, but right here it does
    //not really matter
    return mnl_socket_sendto(mnl_sock, snd_buf, nl_hdr->nlmsg_len);
}
Exemple #18
0
/* Add/delete gateway */
static int32_t multi_link_modify_gateway(uint32_t msg_type, uint32_t flags, 
        uint32_t table_id, struct multi_link_info *li, uint32_t metric){
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct rtmsg *rt;

    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = msg_type;
    nlh->nlmsg_flags = NLM_F_REQUEST | flags;
    nlh->nlmsg_seq = 0;

    rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
    rt->rtm_family = AF_INET;
    //There is no destination (the destination is global, i.e. netmask 0)
    rt->rtm_dst_len = 0; 
    rt->rtm_table = table_id;
    rt->rtm_protocol = RTPROT_UNSPEC;

    /* This is all copied from iproute  */
    if(msg_type != RTM_DELROUTE){
        rt->rtm_scope = RT_SCOPE_UNIVERSE; 
        rt->rtm_type = RTN_UNICAST;
        rt->rtm_protocol = RTPROT_BOOT;
    } else 
        rt->rtm_scope = RT_SCOPE_NOWHERE;

    if(li->cfg.gateway.s_addr > 0)
        mnl_attr_put_u32(nlh, RTA_GATEWAY, li->cfg.gateway.s_addr);

    mnl_attr_put_u32(nlh, RTA_PREFSRC, li->cfg.address.s_addr);
    mnl_attr_put_u32(nlh, RTA_OIF, li->ifi_idx);

	if(metric)
        mnl_attr_put_u32(nlh, RTA_PRIORITY, metric);

    if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT(stderr,"Could not send gateway to kernel "
                "(can be ignored if caused by an interface that went down, "
                "iface idx %u)\n", li->ifi_idx);
        return -1;
    }

    return 0;
}
Exemple #19
0
static int send_and_dispatch(struct mnl_socket *nl, const void *req,
                size_t req_size, enum callback_return_type callback_type,
                uint64_t *callback_value)
{
        struct callback_data cb = {};
        uint32_t portid;
        int err;

	debug_mnl_dump_rule(req, req_size);

        err = mnl_socket_sendto(nl, req, req_size);
        if (err < 0)
                return -errno;

        portid = mnl_socket_get_portid(nl);
        cb.type = callback_type;

        for (;;) {
                char buf[MNL_SOCKET_BUFFER_SIZE];

                err = mnl_socket_recvfrom(nl, buf, sizeof(buf));
                if (err <= 0)
                        break;

                err = mnl_cb_run(buf, err, 0, portid, events_cb, &cb);
                if (err <= 0)
                        break;
        }

        if (err < 0)
                return -errno;

        if (callback_type == CALLBACK_RETURN_NONE)
                return 0;

        if (cb.success) {
                if (callback_value)
                        *callback_value = cb.value;

                return 0;
        }

        return -ENOENT;
}
Exemple #20
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;
}
Exemple #21
0
int genl_socket_talk(struct mnl_socket *nl, struct nlmsghdr *nlh, uint32_t seq,
		     int (*cb)(const struct nlmsghdr *nlh, void *data),
		     void *data)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	int ret;

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

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, mnl_socket_get_portid(nl),
				 cb, data);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}

	return ret;
}
Exemple #22
0
/* Adds or deletes the IP of an interface. This function is never called for PPP
 * interfaces, thus, there are no special cases. */
static int32_t multi_link_modify_ip(uint32_t msg_type, uint32_t flags, 
        struct multi_link_info *li){
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    struct ifaddrmsg *ifa;

    nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type = msg_type;
    nlh->nlmsg_flags = NLM_F_REQUEST | flags;
    nlh->nlmsg_seq = 0;

    ifa = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifaddrmsg));
    
    /* Fill in info related to address */
    ifa->ifa_family = AF_INET; //Currently only IPv4

    //To avoid this rule that is generated automatically, set bitlen to 32
    ifa->ifa_prefixlen = 32 - (ffs(ntohl(li->cfg.netmask.s_addr)) - 1);     
    //Only reason for changing this is if loopback
    ifa->ifa_scope = RT_SCOPE_UNIVERSE; 
    ifa->ifa_index = li->ifi_idx;

    mnl_attr_put_u32(nlh, IFA_LOCAL, li->cfg.address.s_addr);
    mnl_attr_put_u32(nlh, IFA_ADDRESS, li->cfg.address.s_addr);

    if(li->cfg.broadcast.s_addr)
        mnl_attr_put_u32(nlh, IFA_BROADCAST, li->cfg.broadcast.s_addr);

    if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){
        MULTI_DEBUG_PRINT(stderr,"Could not send IP to kernel (can be ignored "
                "if caused by an interface that went down, iface idx %u)\n", 
                li->ifi_idx);
        return -1;
    }

    return 0;
}
Exemple #23
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;
}
Exemple #24
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;
}
Exemple #25
0
int main(int argc, char *argv[])
{
    char buf[MNL_SOCKET_BUFFER_SIZE];
    struct nlmsghdr *nlh;
    int ret;
    unsigned int portid, qnum;

    atexit(cleanup);

    if (argc != 2) {
        printf("Usage: %s [queue_num]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    qnum = 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 = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_UNBIND);

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

    nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_BIND);

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

    nlh = nflog_build_cfg_request(buf, NFULNL_CFG_CMD_BIND, qnum);

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

    nlh = nflog_build_cfg_params(buf, NFULNL_COPY_PACKET, 0xFFFF, qnum);

    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) {
        if(errno == ENOSPC || errno == ENOBUFS)  {
          /* ignore these (hopefully) recoverable errors */
        } else {
          perror("mnl_socket_recvfrom");
          exit(EXIT_FAILURE);
        }
    }
    
    while (1) {
      if (ret == -1) {
        /* reset ret and skip mnl_cb_run if previous recvfrom had an error */
        ret = 0;
      } else {
        ret = mnl_cb_run(buf, ret, 0, portid, log_cb, NULL);
        if (ret < 0) {
          perror("mnl_cb_run");
          exit(EXIT_FAILURE);
        }
      }

      ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
      if (ret == -1) {
        if (errno == ENOSPC || errno == ENOBUFS) {
          /* ignore these (hopefully) recoverable errors */
          continue;
        } else {
          perror("mnl_socket_recvfrom");
          exit(EXIT_FAILURE);
        }
      }
    }

    return 0;
}
Exemple #26
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;
}
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;
}
int main(int argc, char *argv[]){
    struct mnl_socket *nl_sock = NULL;
    struct nlmsghdr *nlh = NULL;
    struct nlmsgerr *nlerr = NULL;
    struct nlattr *linkinfo = NULL, *tunnelinfo = NULL;
    struct ifinfomsg *ifinfo = NULL;
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    size_t numbytes = 0;
    struct in_addr addr;

    memset(buf, 0, sizeof(buf));

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

    //Add and configure header
    nlh = mnl_nlmsg_put_header(buf);
    //Create only if interface does not exists from before (EXCL)
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
    nlh->nlmsg_type = RTM_NEWLINK; 

    //see rtnl_newlink in net/core/rtnetlink.c for observing how this function
    //works
    ifinfo = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifinfomsg));
    ifinfo->ifi_family = AF_UNSPEC;

    //Add a name and mtu, for testing
    mnl_attr_put_str(nlh, IFLA_IFNAME, "kre2");
    mnl_attr_put_u32(nlh, IFLA_MTU, 1234);
  
    //Type is required, set to IPIP
    linkinfo = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
    mnl_attr_put_str(nlh, IFLA_INFO_KIND, "ipip");

    //Add information about the tunnel
    tunnelinfo = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
    inet_pton(AF_INET, "192.168.203.19", &addr);
    mnl_attr_put_u32(nlh, IFLA_IPTUN_LOCAL, addr.s_addr);
    inet_pton(AF_INET, "10.0.0.2", &addr);
    mnl_attr_put_u32(nlh, IFLA_IPTUN_REMOTE, addr.s_addr);

    mnl_attr_nest_end(nlh, tunnelinfo);
    mnl_attr_nest_end(nlh, linkinfo);

    numbytes = mnl_socket_sendto(nl_sock, nlh, nlh->nlmsg_len);
    numbytes = mnl_socket_recvfrom(nl_sock, buf, sizeof(buf));

    nlh = (struct nlmsghdr*) buf;

    if(nlh->nlmsg_type == NLMSG_ERROR){
        nlerr = mnl_nlmsg_get_payload(nlh);
        //error==0 for ack
        if(nlerr->error)
            printf("Error: %s\n", strerror(-nlerr->error));
    } else {
        printf("Link added\n");
    }

    return EXIT_FAILURE;
}
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;
}
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;
}