Пример #1
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);
}
Пример #2
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;
}
Пример #3
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);
}
Пример #4
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;
}