Linux 平台上面获取默认网关的办法很多,但是兼容性那真的就不用多说了,然而以下方法几乎所有的 Linux 系统上面都可以使用,答案则是通过读取 /proc/net/route 内存文件(IPv4 Routing Table)来检索默认的网关与其出站网卡设备。
IPv4 路由表文件:/proc/net/route
IPv6 路由表文件:/proc/net/ipv6_route
无论是 IPv4 或者 IPv6 路由表文件的格式都差不多的,具体可以 Google 上搜索GUN LINUX关于路由的文档来看看。
/* raw https://github.com/getlantern/libnatpmp/blob/master/getgateway.c
parse /proc/net/route which is as follow :
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
wlan0 0001A8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
eth0 0000FEA9 00000000 0001 0 0 0 0000FFFF 0 0 0
wlan0 00000000 0101A8C0 0003 0 0 0 00000000 0 0 0
eth0 00000000 00000000 0001 0 0 1000 00000000 0 0 0
One header line, and then one line by route by route table entry.
*/
bool GetDefaultGateway(char* ifrName, uint32_t* address) {
unsigned long d, g;
char buf[256];
int line = 0;
FILE * f;
char * p;
f = fopen("/proc/net/route", "r");
if (!f) {
return false;
}
while (fgets(buf, sizeof(buf), f)) {
if(line > 0) { /* skip the first line */
p = buf;
/* skip the interface name */
while (*p && !isspace(*p)) {
p++;
}
while (*p && isspace(*p)) {
p++;
}
if (sscanf(p, "%lx%lx", &d, &g) >= 2) {
if (d == 0 && g != 0) { /* default */
if (sscanf(buf, "%[^\t\x20]", ifrName) > 0) {
*address = g;
fclose(f);
return true;
}
}
}
}
line++;
}
/* default route not found ! */
if (f) {
fclose(f);
}
return false;
}