c - 路由设置 : SIOCADDRT failed: Inappropriate ioctl for device

标签 c networking virtualization lxc

这个典型的“route add default gw IP”程序给我错误:

SIOCADDRT 失败:设备的 ioctl 不合适

我执行了 ifconfig 来验证接口(interface)名称。 有没有办法列出适合我的设备的所有 ioctl?

int main(char** args) {
        int sockfd;
        struct rtentry route;
        struct sockaddr_in *addr;
        int err = 0;

        // create the socket
        if(sockfd = socket(AF_INET, SOCK_DGRAM, 0)<0){
                perror("socket");
                exit(1);
        }

        memset(&route, 0, sizeof(route));
        addr = (struct sockaddr_in*) &route.rt_gateway;
        addr->sin_family = AF_INET;
        addr->sin_addr.s_addr = inet_addr("192.168.10.1");
        addr = (struct sockaddr_in*) &route.rt_dst;
        addr->sin_family = AF_INET;
        addr->sin_addr.s_addr = INADDR_ANY;
        addr = (struct sockaddr_in*) &route.rt_genmask;
        addr->sin_family = AF_INET;
        addr->sin_addr.s_addr = INADDR_ANY;

        route.rt_dev = "eth0";

        route.rt_flags = RTF_UP | RTF_GATEWAY;
        route.rt_metric = 0;
        if ((err = ioctl(sockfd, SIOCADDRT, &route)) != 0) {
                perror("SIOCADDRT failed");
                exit(1);
        }
}

将代码更改为后出现新错误:

 addr = (struct sockaddr_in*) &route.rt_gateway;
        addr->sin_family = AF_INET;
        addr->sin_addr.s_addr = inet_addr("192.168.10.1");
        addr = (struct sockaddr_in*) &route.rt_dst;
        addr->sin_family = AF_INET;
        addr->sin_addr.s_addr = inet_addr("192.168.10.3");
        addr = (struct sockaddr_in*) &route.rt_genmask;
        addr->sin_family = AF_INET;
        addr->sin_addr.s_addr = inet_addr("255.255.255.0");

gdb 输出:

37      if ((err = ioctl(sockfd, SIOCADDRT, &route)) != 0) {
(gdb) p route
$1 = {rt_pad1 = 0, rt_dst = {sa_family = 2, sa_data = "\000\000\300\250\n\003\000\000\000\000\000\000\000"}, 
  rt_gateway = {sa_family = 2, sa_data = "\000\000\300\250\n\001\000\000\000\000\000\000\000"}, 
  rt_genmask = {sa_family = 2, sa_data = "\000\000\377\377\377\000\000\000\000\000\000\000\000"}, 
  rt_flags = 3, rt_pad2 = 0, rt_pad3 = 0, rt_tos = 0 '\000', rt_class = 0 '\000', rt_pad4 = {0, 0, 0}, 
  rt_metric = 0, rt_dev = 0x4008af "em1", rt_mtu = 0, rt_window = 0, rt_irtt = 0}
(gdb) n
38          perror("SIOCADDRT failed");
(gdb) 
SIOCADDRT failed: Invalid argument

最佳答案

我猜错误在这里:

    // create the socket
    if(sockfd = socket(AF_INET, SOCK_DGRAM, 0)<0)

表达式socket(AF_INET, SOCK_DGRAM, 0)<0在分配之前进行评估。发生这种情况是因为赋值运算符的优先级低于函数调用和比较。您可以在这篇维基百科文章中阅读更多相关信息:

所以你真正拥有的是:

    // create the socket
    if(sockfd = (socket(AF_INET, SOCK_DGRAM, 0)<0))

计算结果为:

    // create the socket
    if(sockfd = 0)

所以你正在尝试执行 ioctl()关于无效的文件描述符。

将赋值放入括号中或将表达式移出条件,如下所示:

    // create the socket
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)

顺便说一句,如果您通过 -Wall,GCC 或 Clang 应该会检测到它。选项。

关于c - 路由设置 : SIOCADDRT failed: Inappropriate ioctl for device,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25000609/

相关文章:

azure - 如何提供 C++ Windows 软件即服务

使用 KVM 进行 Linux 内核开发

c - 正在跳过获取标准输入的 Getline

networking - 使用电话线的游戏

Python 原始套接字监听 UDP 数据包;只收到一半的数据包

sockets - 了解WebSockets

memory - 使用 VMX 模拟内存映射 I/O 是否需要指令解码?

C中多个数组的笛卡尔积

c - 关于 C 程序输出的说明

c - 为什么 fileno 无法返回有效的描述符?