summaryrefslogtreecommitdiffstats
path: root/src/if.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-10-25 11:52:26 +0100
committerRoy Marples <roy@marples.name>2019-10-25 11:52:26 +0100
commitb775f27c68db39c30c1c1c3af91a8d874482eb01 (patch)
treed4cd7464061fb4d2d5dc803f084619d8fbfdbe12 /src/if.c
parent68b7565f94c549d7f4375bea30f2b52aa28b43b1 (diff)
downloaddhcpcd-b775f27c68db39c30c1c1c3af91a8d874482eb01.tar.xz
BSD: Use IP_RECVIF
IP_RECVIF is supported on all BSD platforms as well as Solaris, so it's more widely available than IP_PKTINFO. This allows us to ensure that all platforms can retrieve the receving interface from UDP network packets and thus make the code paths a lot easier.
Diffstat (limited to 'src/if.c')
-rw-r--r--src/if.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/if.c b/src/if.c
index 459af3af..c0b67ec9 100644
--- a/src/if.c
+++ b/src/if.c
@@ -740,9 +740,13 @@ if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit)
struct cmsghdr *cm;
unsigned int ifindex = 0;
struct interface *ifp;
-#if defined(INET) && defined(IP_PKTINFO)
+#ifdef INET
+#ifdef IP_RECVIF
+ struct sockaddr_dl sdl;
+#else
struct in_pktinfo ipi;
#endif
+#endif
#ifdef INET6
struct in6_pktinfo ipi6;
#else
@@ -753,15 +757,27 @@ if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit)
cm;
cm = (struct cmsghdr *)CMSG_NXTHDR(msg, cm))
{
-#if defined(INET) && defined(IP_PKTINFO)
+#ifdef INET
if (cm->cmsg_level == IPPROTO_IP) {
switch(cm->cmsg_type) {
+#ifdef IP_RECVIF
+ case IP_RECVIF:
+ if (cm->cmsg_len <
+ offsetof(struct sockaddr_dl, sdl_index) +
+ sizeof(sdl.sdl_index))
+ continue;
+ memcpy(&sdl, CMSG_DATA(cm),
+ MIN(sizeof(sdl), cm->cmsg_len));
+ ifindex = sdl.sdl_index;
+ break;
+#else
case IP_PKTINFO:
if (cm->cmsg_len != CMSG_LEN(sizeof(ipi)))
continue;
memcpy(&ipi, CMSG_DATA(cm), sizeof(ipi));
ifindex = (unsigned int)ipi.ipi_ifindex;
break;
+#endif
}
}
#endif