通过rtnetlink添加路由不起作用

时间:2019-09-25 08:00:23

标签: c linux-kernel routing network-programming netlink

我想将路由添加到内核的MAIN路由表中(使用rtnetlink)。当我运行我的代码时,不会发生错误。但是该路由未成功添加到路由表中。

我的代码:

//include
#include <stdio.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <sys/types.h>
#include <linux/rtnetlink.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <string.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

//open_netlink
int open_netlink(){

    struct sockaddr_nl saddr;

    int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

    if (sock < 0) {
        perror("Failed to open netlink socket");
        return -1;
    }

    memset(&saddr, 0, sizeof(saddr));

    saddr.nl_family = AF_NETLINK;
    saddr.nl_pid = 0; 
    saddr.nl_pad = 0 ;   //set 0
    saddr.nl_groups = 0;

    if (bind(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
        perror("Failed to bind to netlink socket");
        close(sock);
        return -1;
    }

    return sock;
}

/* Add new data to rtattr */
int rtattr_add(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
{
    int len = RTA_LENGTH(alen);
    struct rtattr *rta;

    if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
        fprintf(stderr, "rtattr_add error: message exceeded bound of %d\n", maxlen);
        return -1;
    }

    rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
    rta->rta_type = type;
    rta->rta_len = len; 

    if (alen) {
        memcpy(RTA_DATA(rta), data, alen);
    }

    n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
    fprintf(stderr,"\attr len=%d\n",n->nlmsg_len);
    return 0;
}

//route_add
void route_add(__u32* des, __u32* gw, unsigned int netmask, int if_index){

    struct {
        struct nlmsghdr n;
        struct rtmsg r;
        char buf[4096];
    } nl_req;

    int rt_sock=open_netlink();
    memset(&nl_req, 0, sizeof(nl_req));
    nl_req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    nl_req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
    nl_req.n.nlmsg_type=RTM_NEWROUTE;
    nl_req.r.rtm_family = AF_INET;
    nl_req.r.rtm_table = RT_TABLE_MAIN;
    nl_req.r.rtm_protocol = RTPROT_BOOT;
    nl_req.r.rtm_scope = RT_SCOPE_UNIVERSE;
    nl_req.r.rtm_type = RTN_UNICAST;
    nl_req.r.rtm_dst_len=netmask;
    nl_req.r.rtm_src_len=0;
    nl_req.r.rtm_tos=0;
    //nl_req.r.rtm_flags=RT_TABLE_MAIN;

    rtattr_add(&nl_req.n, sizeof(nl_req), RTA_DST, des, 4);
    rtattr_add(&nl_req.n, sizeof(nl_req), RTA_GATEWAY, gw, 4);
    rtattr_add(&nl_req.n, sizeof(nl_req), RTA_OIF, &if_index, 4);

    int status=send(rt_sock,&nl_req,nl_req.n.nlmsg_len,0);
    fprintf(stderr,"status=%d,route add successfully\n",status);

}

//main
int main(){

    __u32 des;
    __u32 gw; 
    des=inet_addr("192.168.153.0");   //des ip
    //fprintf(stderr, "%d\n",des );
    gw=inet_addr("192.168.152.4");   //gateway ip
    //fprintf(stderr, "%d\n",gw );
    route_add(&des,&gw,24,2);
    return 0;
}

我的代码有什么错误吗?或任何建议?

代码执行的结果显示在this image中。

0 个答案:

没有答案