使用 ioctl 在 C++ 中以编程方式添加路由

Posted

技术标签:

【中文标题】使用 ioctl 在 C++ 中以编程方式添加路由【英文标题】:Add route programmatically in C++ using ioctl 【发布时间】:2019-09-16 15:09:51 【问题描述】:

我编写了简单的 C++ 函数,添加了新的路由:

void addRoute()

    int fd = socket( PF_INET, SOCK_DGRAM, IPPROTO_IP );

    struct rtentry route;
    memset( &route, 0, sizeof( route ) );

    struct sockaddr_in *addr = (struct sockaddr_in *)&route.rt_gateway;
    addr->sin_family = AF_INET;
    addr->sin_addr.s_addr = inet_addr( "192.168.20.1" );

    addr = (struct sockaddr_in*) &route.rt_dst;
    addr->sin_family = AF_INET;
    addr->sin_addr.s_addr = inet_addr( "10.0.0.50" );

    addr = (struct sockaddr_in*) &route.rt_genmask;
    addr->sin_family = AF_INET;
    addr->sin_addr.s_addr = INADDR_ANY;

    route.rt_flags = RTF_UP | RTF_GATEWAY;
    route.rt_metric = 0;

    int rc = ioctl( fd, SIOCADDRT, &route );
    cout << "rc = " << rc << endl; //rc = -1
    close( fd );


int main()

    addRoute();
    return 0;

问题是 ioctl 返回 -1 (rc = -1)。我的代码有什么问题? 我从 root 启动它。我想执行 ip route 看到这一行:

10.0.0.50 via 192.168.20.1 dev ***_linux

【问题讨论】:

您应该会看到 errno 被设置为什么错误代码(提示:使用 strerror()perror() 来获得人类可读的版本,而不是神秘数字)。 @Shawn 嘿,我使用了 strerror():“无效参数”。也许我没有正确设置 struct rtentry route ? 我可以使用终端和以下命令添加路由:sudo ip ro add 10.0.0.50 via 192.168.20.1 【参考方案1】:

您使用INADDR_ANY (0.0.0.0) 屏蔽格式为a.b.c.d/32 的地址,因此它应该使用255.255.255.255

/32 的解决方案是:

addr = (struct sockaddr_in*) &route.rt_dst;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr( "10.0.0.50" );

addr = (struct sockaddr_in*) &route.rt_genmask;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr( "255.255.255.255" );

【讨论】:

以上是关于使用 ioctl 在 C++ 中以编程方式添加路由的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react-router 中以编程方式进行服务器端路由?

如何在 SvelteKit 中以编程方式路由?

在 C++ 中以编程方式在编译时创建静态数组

在 C++ 程序中以编程方式检测字节顺序

无法在 Windows 中以编程方式 (C++) 从其他用户帐户读取文件

在 React-Router V4 中以编程方式设置路由参数最终会出现“找不到页面”