【问题标题】:Default Gateway in C on LinuxLinux 上 C 语言中的默认网关
【发布时间】:2009-02-13 23:30:46
【问题描述】:

如何在 Linux 上使用 C 找到路由表的默认网关?

我不想调用 shell 或读取文件。有用于添加和删除路由(SIOCADDRT、SIOCDELRT)的 ioctl,我在参考获取路由(SIOCGRTCONF)时找到了,但我使用的内核版本似乎不支持 SIOCGRTCONF。

【问题讨论】:

  • 网卡没有默认网关,路由表有默认网关。

标签: network-programming


【解决方案1】:

我认为阅读 /proc/net/route 将是您最好的选择。你会认为这是一个“文件”吗?

/proc/net/route 的格式是众所周知的,并且在内存中,因此没有 I/O 损失或担心这种变化(即与从 /etc/network/* 读取内容相比)

【讨论】:

    【解决方案2】:

    您可能需要使用NETLINK_ROUTE 套接字,它是PF_NETLINK 套接字系列的一部分。查看“iproute”的“ip”程序部分的源代码。具体来说,它的“路线”子命令。

    【讨论】:

    【解决方案3】:

    你可以像这样使用/proc/net/route:

    int GetDefaultGw ( std::string & gw )
    {
        FILE *f;
        char line[100] , *p , *c, *g, *saveptr;
        int nRet=1;
    
        f = fopen("/proc/net/route" , "r");
    
        while(fgets(line , 100 , f))
        {
            p = strtok_r(line , " \t", &saveptr);
            c = strtok_r(NULL , " \t", &saveptr);
            g = strtok_r(NULL , " \t", &saveptr);
    
            if(p!=NULL && c!=NULL)
            {
                if(strcmp(c , "00000000") == 0)
                {
                    //printf("Default interface is : %s \n" , p);
                    if (g)
                    {
                        char *pEnd;
                        int ng=strtol(g,&pEnd,16);
                        //ng=ntohl(ng);
                        struct in_addr addr;
                        addr.s_addr=ng;
                        gw=std::string( inet_ntoa(addr) );
                        nRet=0;
                    }
                    break;
                }
            }
        }
    
        fclose(f);
        return nRet;
    }
    

    【讨论】:

    • 如果你有多个接口,在第二个 if 语句中检查接口名称更有意义。
    • 必须使用'strtoul',否则有些情况会溢出。例如,默认网关是 FEFEFEA9 ('169.254.254.254')。它应该是'unsigned long int ng=strtoul(g,&pEnd,16);'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 2015-01-12
    相关资源
    最近更新 更多