12

How do you find the default gateway of a routing table using C on Linux?

I don't want to issue a call to the shell or read a file. There are ioctls for adding and deleteing routes (SIOCADDRT, SIOCDELRT) and I've found on reference to getting routes (SIOCGRTCONF) but it seems that the version of the kernel I'm using doesn't support SIOCGRTCONF.

Matt
  • 153
  • 1
  • 2
  • 9

3 Answers3

11

I think reading /proc/net/route will be your best bet. Would you consider this a "file"?

The format of /proc/net/route is well-known, and in-memory, so there's no I/O penalty or fear of this changing (i.e. versus reading something from /etc/network/*)

slacy
  • 11,397
  • 8
  • 56
  • 61
7

You could use/proc/net/route like this:

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;
}
Eric Ze
  • 91
  • 1
  • 4
  • 2
    If you have multiple interfaces, it makes more sense to check for the interface name in the 2nd if statement. – 3bdalla Jan 29 '15 at 15:52
  • 2
    It must use 'strtoul', otherwise some situation would be overflow. for example, default gateway is FEFEFEA9 ('169.254.254.254'). It should be 'unsigned long int ng=strtoul(g,&pEnd,16);' – Mystic Lin Dec 24 '15 at 05:06
7

You will probably need to use a NETLINK_ROUTE socket, part of the PF_NETLINK family of sockets. Check out the source code of the 'ip' program part of 'iproute'. Specifically, its 'route' subcommand.

codelogic
  • 71,764
  • 9
  • 59
  • 54
  • Here is a link to sample code. http://www.linuxquestions.org/questions/linux-networking-3/howto-find-gateway-address-through-code-397078/ I've implemented this with some modifications and it works well. – Matt Feb 17 '09 at 20:11