summaryrefslogtreecommitdiff
path: root/sys/net/route.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-04-29 11:58:30 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-04-29 11:58:30 +0000
commitda56150082fce6201d87c88d1d6236b29aa3575b (patch)
treee09c17505e4c440971e4b8095cee62f6dae34821 /sys/net/route.c
parent4a4ee23f0912ef525b45e5f8518b996489abd8e4 (diff)
If you plan to write an obfuscated-by-design kernel / userland
interface, I suggest you have a look at the link-layer sockaddr interface: /* * A Link-Level Sockaddr may specify the interface in one of two * ways: either by means of a system-provided index number (computed * anew and possibly differently on every reboot), or by a human-readable * string such as "il0" (for managerial convenience). [...] */ ifa_ifwithnet() was not only checking for the sdl_index in order to get the corresponding ifp for AF_LINK sockaddr, it was also iterating over all the addresses on your system! But in this case, the `address' field of "struct sockaddr_dl" is an interface name set by link_addr(3). How can this work? Well because the kernel allocates an empty `netmask' field for each interface's lladdr, so that you can abuse a network comparison function to reimplement strcmp(3)... So when the userland does not specify an interface index, try harder to see if it passed an ifp name, but at least be explicit and use ifunit(). Found the hard way by/ok sthen@
Diffstat (limited to 'sys/net/route.c')
-rw-r--r--sys/net/route.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index ca23aa83e04..064d44712cd 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.164 2014/04/25 10:41:09 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.165 2014/04/29 11:58:29 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -658,6 +658,8 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
struct sockaddr_dl *sdl = (struct sockaddr_dl *)gateway;
struct ifnet *ifp = if_get(sdl->sdl_index);
+ if (ifp == NULL)
+ ifp = ifunit(sdl->sdl_data);
if (ifp != NULL)
ifa = ifp->if_lladdr;
} else {
@@ -702,6 +704,8 @@ rt_getifa(struct rt_addrinfo *info, u_int rtid)
sdl = (struct sockaddr_dl *)info->rti_info[RTAX_IFP];
ifp = if_get(sdl->sdl_index);
+ if (ifp == NULL)
+ ifp = ifunit(sdl->sdl_data);
}
if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)