From b5c1e8347182a0191bd70c06252873b8d1bcecf2 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 26 Mar 2012 22:24:55 +0000 Subject: [PATCH] Substitute on-link routes' gateways with an all-zero address. On OS X, the code in route_loop in route-bsd.c can get a gateway sockaddr_dl that looks like this: $1 = { sdl_len = 20 '\024', sdl_family = 18 '\022', sdl_index = 4, sdl_type = 6 '\006', sdl_nlen = 0 '\0', sdl_alen = 0 '\0', sdl_slen = 0 '\0', sdl_data = '\0' } route_loop would throw these out because there's no hardward address there. This is a routing table entry that indicates that there is no gateway, and that packets for this particular destination need to go on interface #4. It corresponds to this type of line from netstat output: Destination Gateway Flags Refs Use Netif Expire 192.168.0 link#4 UCS 2 0 en0 I've changed it so that instead of throwing out the entry, it creates an all-zero address of the same type as the destination address, which is a convention used (by Nmap at least) to indicate an on-link route. --- libdnet-stripped/src/route-bsd.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c index 2eca1dfdd..9bfd58d76 100644 --- a/libdnet-stripped/src/route-bsd.c +++ b/libdnet-stripped/src/route-bsd.c @@ -217,6 +217,33 @@ route_get(route_t *r, struct route_entry *entry) } #if defined(HAVE_SYS_SYSCTL_H) || defined(HAVE_STREAMS_ROUTE) || defined(HAVE_GETKERNINFO) +/* This wrapper around addr_ston, on failure, checks for a gateway address + * family of AF_LINK, and if it finds one, stores an all-zero address of the + * same type as dst. The all-zero address is a convention for same-subnet + * routing table entries. */ +static int +addr_ston_gateway(const struct addr *dst, + const struct sockaddr *sa, struct addr *a) +{ + int rc; + + rc = addr_ston(sa, a); + if (rc == 0) + return rc; + +#ifdef HAVE_NET_IF_DL_H +# ifdef AF_LINK + if (sa->sa_family == AF_LINK) { + memset(a, 0, sizeof(*a)); + a->addr_type = dst->addr_type; + return (0); + } +# endif +#endif + + return (-1); +} + int route_loop(route_t *r, route_handler callback, void *arg) { @@ -301,7 +328,7 @@ route_loop(route_t *r, route_handler callback, void *arg) /* Need a gateway. */ continue; sa = NEXTSA(sa); - if (addr_ston(sa, &entry.route_gw) < 0) + if (addr_ston_gateway(&entry.route_dst, sa, &entry.route_gw) < 0) continue; if (entry.route_dst.addr_type != entry.route_gw.addr_type ||