summaryrefslogtreecommitdiffstats
path: root/src/if.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-02-19 21:46:06 +0000
committerRoy Marples <roy@marples.name>2019-02-19 21:46:06 +0000
commit5c1785fd64d7825de472a254a5d9413deb0fb032 (patch)
treec552fe32f5fe4319f8ea04bc37b9ff1a6e540375 /src/if.c
parentfa975d48ab5b26b61174ecccd9b9657b6ed09a3f (diff)
downloaddhcpcd-5c1785fd64d7825de472a254a5d9413deb0fb032.tar.xz
Fold all CMSG parsing into a common function.
Makes dhcpcd smaller still.
Diffstat (limited to 'src/if.c')
-rw-r--r--src/if.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/if.c b/src/if.c
index 42b3e7b3..9ba286d1 100644
--- a/src/if.c
+++ b/src/if.c
@@ -801,6 +801,68 @@ if_sortinterfaces(struct dhcpcd_ctx *ctx)
TAILQ_CONCAT(ctx->ifaces, &sorted, next);
}
+struct interface *
+if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit)
+{
+ struct cmsghdr *cm;
+ unsigned int ifindex = 0;
+ struct interface *ifp;
+#ifdef INET
+ struct in_pktinfo ipi;
+#endif
+#ifdef INET6
+ struct in6_pktinfo ipi6;
+#else
+ UNUSED(hoplimit);
+#endif
+
+ for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(msg);
+ cm;
+ cm = (struct cmsghdr *)CMSG_NXTHDR(msg, cm))
+ {
+#ifdef INET
+ if (cm->cmsg_level == IPPROTO_IP) {
+ switch(cm->cmsg_type) {
+ 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
+#ifdef INET6
+ if (cm->cmsg_level == IPPROTO_IPV6) {
+ switch(cm->cmsg_type) {
+ case IPV6_PKTINFO:
+ if (cm->cmsg_len != CMSG_LEN(sizeof(ipi6)))
+ continue;
+ memcpy(&ipi6, CMSG_DATA(cm), sizeof(ipi6));
+ ifindex = (unsigned int)ipi6.ipi6_ifindex;
+ break;
+ case IPV6_HOPLIMIT:
+ if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
+ continue;
+ if (hoplimit == NULL)
+ break;
+ memcpy(hoplimit, CMSG_DATA(cm), sizeof(int));
+ break;
+ }
+ }
+#endif
+ }
+
+ /* Find the receiving interface */
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+ if (ifp->index == ifindex)
+ break;
+ }
+ if (ifp == NULL)
+ errno = ESRCH;
+ return ifp;
+}
+
int
xsocket(int domain, int type, int protocol)
{