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

3

我编写了一个简单的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 vpn_linux

你应该查看错误代码 errno 被设定为什么 (提示: 使用 strerror()perror() 获取人类可读的版本,而不是加密数字)。 - Shawn
@Shawn 嘿,我使用了strerror()函数:"Invalid argument"。也许我没有正确设置struct rtentry route结构体? - Sfdfsg
我可以使用终端和以下命令添加路由:sudo ip ro add 10.0.0.50 via 192.168.20.1 - Sfdfsg
1个回答

0

你正在使用 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" );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接