Exemple #1
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 #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
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 #4
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 #5
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 #6
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 #7
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 #10
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;
}
Exemple #11
0
static void put_msg(char *buf, uint16_t i, int seq)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfh;
	struct nlattr *nest1, *nest2;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
	nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
	nlh->nlmsg_seq = seq;

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

	nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_ORIG);
	nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
	mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr("1.1.1.1"));
	mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr("2.2.2.2"));
	mnl_attr_nest_end(nlh, nest2);

	nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO);
	mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP);
	mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(i));
	mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(1025));
	mnl_attr_nest_end(nlh, nest2);
	mnl_attr_nest_end(nlh, nest1);

	nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_REPLY);
	nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
	mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr("2.2.2.2"));
	mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr("1.1.1.1"));
	mnl_attr_nest_end(nlh, nest2);

	nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO);
	mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP);
	mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(1025));
	mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(i));
	mnl_attr_nest_end(nlh, nest2);
	mnl_attr_nest_end(nlh, nest1);

	nest1 = mnl_attr_nest_start(nlh, CTA_PROTOINFO);
	nest2 = mnl_attr_nest_start(nlh, CTA_PROTOINFO_TCP);
	mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_STATE, TCP_CONNTRACK_SYN_SENT);
	mnl_attr_nest_end(nlh, nest2);
	mnl_attr_nest_end(nlh, nest1);

	mnl_attr_put_u32(nlh, CTA_STATUS, htonl(IPS_CONFIRMED));
	mnl_attr_put_u32(nlh, CTA_TIMEOUT, htonl(1000));
}
Exemple #12
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 #13
0
static void nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seq)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfg;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = type;
	nlh->nlmsg_flags = NLM_F_REQUEST;
	nlh->nlmsg_seq = seq;

	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_INET;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = NFNL_SUBSYS_NFTABLES;
}
Exemple #14
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 #15
0
/**
 * nflog_nlmsg_put_header - reserve and prepare room for nflog Netlink header
 * \param buf memory already allocated to store the Netlink header
 * \param type message type one of the enum nfulnl_msg_types
 * \param family protocol family to be an object of
 * \param qnum queue number to be an object of
 *
 * This function creates Netlink header in the memory buffer passed
 * as parameter that will send to nfnetlink log. This function
 * returns a pointer to the Netlink header structure.
 */
struct nlmsghdr *
nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t qnum)
{
	struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
	struct nfgenmsg *nfg;

	nlh->nlmsg_type	= (NFNL_SUBSYS_ULOG << 8) | type;
	nlh->nlmsg_flags = NLM_F_REQUEST;

	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = family;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(qnum);

	return nlh;
}
Exemple #16
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 #17
0
struct nlmsghdr *nftnl_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
				     uint16_t type, uint32_t seq)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfh;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | cmd;
	nlh->nlmsg_flags = NLM_F_REQUEST | type;
	nlh->nlmsg_seq = seq;

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

	return nlh;
}
Exemple #18
0
struct nlmsghdr *
genl_nlmsg_build_hdr(char *buf, uint16_t type, uint16_t flags, uint32_t seq,
		     uint8_t cmd)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = type;
	nlh->nlmsg_flags = NLM_F_REQUEST | flags;
	nlh->nlmsg_seq = seq;

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

	return nlh;
}
/**
 * nfacct_nlmsg_build_hdr - build netlink message header for nfacct subsystem
 * \param buf: buffer where this function outputs the netlink message.
 * \param cmd: nfacct nfnetlink command.
 * \param flags: netlink flags.
 * \param seq: sequence number for this message.
 *
 * Possible commands:
 * - NFNL_MSG_ACCT_NEW: new accounting object.
 * - NFNL_MSG_ACCT_GET: get accounting object.
 * - NFNL_MSG_ACCT_GET_CTRZERO: get accounting object and atomically reset.
 *
 * Examples:
 * - Command NFNL_MSG_ACCT_NEW + flags NLM_F_CREATE | NLM_F_ACK, to create
 *   one new accounting object (if it does not already exists). You receive
 *   one acknoledgment in any case with the result of the operation.
 *
 * - Command NFNL_MSG_ACCT_GET + flags NLM_F_DUMP, to obtain all the
 *   existing accounting objects.
 *
 * - Command NFNL_MSG_ACCT_GET_CTRZERO + flags NLM_F_DUMP, to atomically
 *   obtain all the existing accounting objects and reset them.
 *
 * - Command NFNL_MSG_ACCT_DEL, to delete all existing unused objects.
 *
 * - Command NFNL_MSG_ACCT_DEL, to delete one specific nfacct object (if
 *   unused, otherwise you hit EBUSY).
 */
struct nlmsghdr *
nfacct_nlmsg_build_hdr(char *buf, uint8_t cmd, uint16_t flags, uint32_t seq)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfh;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_ACCT << 8) | cmd;
	nlh->nlmsg_flags = NLM_F_REQUEST | flags;
	nlh->nlmsg_seq = seq;

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

	return nlh;
}
Exemple #20
0
    static struct nlmsghdr *
nflog_build_cfg_pf_request(char *buf, uint8_t command)
{
    struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type	= (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
    nlh->nlmsg_flags = NLM_F_REQUEST;

    struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
    nfg->nfgen_family = AF_INET;
    nfg->version = NFNETLINK_V0;

    struct nfulnl_msg_config_cmd cmd = {
        .command = command,
    };
    mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(cmd), &cmd);

    return nlh;
}
Exemple #21
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 #22
0
static struct nlmsghdr *__mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
					   uint16_t flags, uint32_t id,
					   uint8_t version)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;

	nlh = mnl_nlmsg_put_header(nlg->buf);
	nlh->nlmsg_type	= id;
	nlh->nlmsg_flags = flags;
	nlg->seq = time(NULL);
	nlh->nlmsg_seq = nlg->seq;

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

	return nlh;
}
Exemple #23
0
static struct nlmsghdr *
nfq_build_cfg_params(char *buf, uint8_t mode, int range, int queue_num)
{
	struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
	nlh->nlmsg_flags = NLM_F_REQUEST;

	struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_UNSPEC;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(queue_num);

	struct nfqnl_msg_config_params params = {
		.copy_range = htonl(range),
		.copy_mode = mode,
	};
	mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), &params);

	return nlh;
}
Exemple #24
0
static struct nlmsghdr *
nfq_build_cfg_request(char *buf, uint8_t command, int queue_num)
{
	struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
	nlh->nlmsg_flags = NLM_F_REQUEST;

	struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_UNSPEC;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(queue_num);

	struct nfqnl_msg_config_cmd cmd = {
		.command = command,
		.pf = htons(AF_INET),
	};
	mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(cmd), &cmd);

	return nlh;
}
Exemple #25
0
static struct nlmsghdr *
genl_nlmsg_build_lookup(char *buf, const char *subsys_name)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= GENL_ID_CTRL;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_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, subsys_name);

	return nlh;
}
Exemple #26
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 #27
0
static struct nlmsghdr *
nfq_build_verdict(char *buf, int id, int queue_num, int verd)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfg;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT;
	nlh->nlmsg_flags = NLM_F_REQUEST;
	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_UNSPEC;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(queue_num);

	struct nfqnl_msg_verdict_hdr vh = {
		.verdict = htonl(verd),
		.id = htonl(id),
	};
	mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);

	return nlh;
}
Exemple #28
0
struct nlmsghdr *msg_init(char *buf, int cmd)
{
	int family;
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;

	family = get_family();
	if (family <= 0) {
		fprintf(stderr,
			"Unable to get TIPC nl family id (module loaded?)\n");
		return NULL;
	}

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= family;

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

	return nlh;
}
Exemple #29
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 #30
0
static int get_family(void)
{
	int err;
	int nl_family;
	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;
	char buf[MNL_SOCKET_BUFFER_SIZE];

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= GENL_ID_CTRL;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;

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

	mnl_attr_put_u16(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL);
	mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, TIPC_GENL_V2_NAME);

	if ((err = msg_query(nlh, family_id_cb, &nl_family)))
		return err;

	return nl_family;
}