Linux上的C中的默认网关

Mat*_*att 9 network-programming

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

我不想发出对shell的调用或读取文件.有添加和删除路由的ioctl(SIOCADDRT,SIOCDELRT),我发现了获取路由(SIOCGRTCONF),但似乎我使用的内核版本不支持SIOCGRTCONF.

sla*_*acy 9

我认为阅读/ proc/net/route将是你最好的选择.你会认为这是一个"档案"吗?

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


cod*_*gic 5

你可能会需要使用NETLINK_ROUTE插座,该部分PF_NETLINK家庭插座.查看'iproute'的'ip'程序部分的源代码.具体来说,它的'route'子命令.


小智 5

您可以像这样使用/ 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您有多个接口,则在第二个if语句中检查接口名称更有意义。 (2认同)
  • 它必须使用“ strtoul”,否则某些情况将会溢出。例如,默认网关为FEFEFEA9('169.254.254.254')。它应该是“ unsigned long int ng = strtoul(g,&pEnd,16);” (2认同)