From 62c22767553e3a60e447b4e5e8a53406a5ed60ae Mon Sep 17 00:00:00 2001 From: david Date: Sun, 4 Jul 2010 17:42:49 +0000 Subject: [PATCH] =?UTF-8?q?Properly=20match=20up=20directly=20connect=20ro?= =?UTF-8?q?utes=20with=20alias=20interface=20addresses=20in=20getsysroutes?= =?UTF-8?q?=5Fproc.=20This=20was=20already=20being=20done=20for=20non?= =?UTF-8?q?=C3=A2=C2=80=C2=93directly=20connected=20routes,=20those=20with?= =?UTF-8?q?=20a=20gateway.=20Victor=20Rudnev=20reported=20this=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /proc/net/route file doesn't contain alias qualifications so we must match them up after the fact with the interface table. When the gateway address isn't set, use the route destination for matching instead. For example, with these interfaces and routing table, eth0 Link encap:Ethernet HWaddr 00:50:BF:16:11:61 inet addr:192.168.1.21 Bcast:192.168.1.255 Mask:255.255.255.0 eth0:1 Link encap:Ethernet HWaddr 00:50:BF:16:11:61 inet addr:192.168.0.21 Bcast:192.168.0.255 Mask:255.255.255.0 Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 nmap --iflist before this commit: DEV (SHORT) IP/MASK TYPE UP MAC eth0 (eth0) 192.168.1.21/24 ethernet up 00:50:BF:16:11:61 eth0:1 (eth0) 192.168.0.21/24 ethernet up 00:50:BF:16:11:61 DST/MASK DEV GATEWAY 192.168.1.0/24 eth0 192.168.0.0/24 eth0 nmap --iflist after this commit: DEV (SHORT) IP/MASK TYPE UP MAC eth0 (eth0) 192.168.1.21/24 ethernet up 00:50:BF:16:11:61 eth0:1 (eth0) 192.168.0.21/24 ethernet up 00:50:BF:16:11:61 DST/MASK DEV GATEWAY 192.168.1.0/24 eth0 192.168.0.0/24 eth0:1 --- libnetutil/netutil.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index a746383fe..d210b5d80 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -1298,7 +1298,7 @@ static struct sys_route *getsysroutes_proc(FILE *routefp, int *howmany, char *er char iface[16]; char *p, *endptr; struct interface_info *ii; - u32 mask; + u32 routeaddr, mask; struct sockaddr_in *sin; int numifaces = 0, numroutes = 0; int i; @@ -1395,21 +1395,24 @@ static struct sys_route *getsysroutes_proc(FILE *routefp, int *howmany, char *er /* Now to deal with some alias nonsense ... at least on Linux this file will just list the short name, even though IP information (such as source address) from an alias must be - used. So if the purported device can't reach the gateway, + used. So if the purported device can't reach the gateway + (or destination address for directly connected routes), try to find a device that starts with the same short devname, but can (e.g. eth0 -> eth0:3) */ + if (routes[numroutes].gw.s_addr != 0) + routeaddr = routes[numroutes].gw.s_addr; + else + routeaddr = routes[numroutes].dest; ii = &ifaces[i]; mask = htonl((unsigned long) (0 - 1) << (32 - ii->netmask_bits)); sin = (struct sockaddr_in *) &ii->addr; - if (routes[numroutes].gw.s_addr && (sin->sin_addr.s_addr & mask) != - (routes[numroutes].gw.s_addr & mask)) { + if ((sin->sin_addr.s_addr & mask) != (routeaddr & mask)) { for (i = 0; i < numifaces; i++) { if (ii == &ifaces[i]) continue; if (strcmp(ii->devname, ifaces[i].devname) == 0) { sin = (struct sockaddr_in *) &ifaces[i].addr; - if ((sin->sin_addr.s_addr & mask) == - (routes[numroutes].gw.s_addr & mask)) { + if ((sin->sin_addr.s_addr & mask) == (routeaddr & mask)) { routes[numroutes].device = &ifaces[i]; } }