Makes dhcpcd smaller still.
inet_ntop(AF_INET, &from.sin_addr, sfrom, sizeof(sfrom));
if (ifp == NULL) {
- struct cmsghdr *cm;
- struct in_pktinfo pi;
-
- pi.ipi_ifindex = 0;
- for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&msg);
- cm;
- cm = (struct cmsghdr *)CMSG_NXTHDR(&msg, cm))
- {
- if (cm->cmsg_level != IPPROTO_IP)
- continue;
- switch(cm->cmsg_type) {
- case IP_PKTINFO:
- if (cm->cmsg_len == CMSG_LEN(sizeof(pi)))
- memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
- break;
- }
- }
- if (pi.ipi_ifindex == 0) {
- logerrx("DHCP reply did not contain index from %s",
- sfrom);
- return;
- }
-
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (ifp->index == (unsigned int)pi.ipi_ifindex)
- break;
- }
+ ifp = if_findifpfromcmsg(ctx, &msg, NULL);
if (ifp == NULL) {
- logerrx("DHCP reply for unexpected interface from %s",
- sfrom);
+ logerr(__func__);
return;
}
}
if (ia != NULL)
ifp = ia->iface;
else {
- struct cmsghdr *cm;
- struct in6_pktinfo pi;
-
- pi.ipi6_ifindex = 0;
- for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&msg);
- cm;
- cm = (struct cmsghdr *)CMSG_NXTHDR(&msg, cm))
- {
- if (cm->cmsg_level != IPPROTO_IPV6)
- continue;
- switch(cm->cmsg_type) {
- case IPV6_PKTINFO:
- if (cm->cmsg_len == CMSG_LEN(sizeof(pi)))
- memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
- break;
- }
- }
- if (pi.ipi6_ifindex == 0) {
- logerrx("DHCPv6 reply did not contain index from %s",
- sfrom);
- return;
- }
-
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (ifp->index == (unsigned int)pi.ipi6_ifindex)
- break;
- }
+ ifp = if_findifpfromcmsg(ctx, &msg, NULL);
if (ifp == NULL) {
- logerrx("DHCPv6 reply for unexpected interface from %s",
- sfrom);
+ logerr(__func__);
return;
}
}
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)
{
#endif
int if_machinearch(char *, size_t);
+struct interface *if_findifpfromcmsg(struct dhcpcd_ctx *,
+ struct msghdr *, int *);
int xsocket(int, int, int);
#endif
.msg_control = ctl, .msg_controllen = sizeof(ctl),
};
ssize_t len;
- struct cmsghdr *cm;
char sfrom[INET6_ADDRSTRLEN];
- int hoplimit;
- struct in6_pktinfo pkt;
+ int hoplimit = 0;
struct icmp6_hdr *icp;
struct interface *ifp;
return;
}
- pkt.ipi6_ifindex = 0;
- hoplimit = 0;
- for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&msg);
- cm;
- cm = (struct cmsghdr *)CMSG_NXTHDR(&msg, cm))
- {
- if (cm->cmsg_level != IPPROTO_IPV6)
- continue;
- switch(cm->cmsg_type) {
- case IPV6_PKTINFO:
- if (cm->cmsg_len == CMSG_LEN(sizeof(pkt)))
- memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt));
- break;
- case IPV6_HOPLIMIT:
- if (cm->cmsg_len == CMSG_LEN(sizeof(int)))
- memcpy(&hoplimit, CMSG_DATA(cm), sizeof(int));
- break;
- }
- }
-
- if (pkt.ipi6_ifindex == 0) {
- logerrx("IPv6 RA/NA did not contain index from %s", sfrom);
+ ifp = if_findifpfromcmsg(ctx, &msg, &hoplimit);
+ if (ifp == NULL) {
+ logerr(__func__);
return;
}
- /* Find the receiving interface */
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (ifp->index == (unsigned int)pkt.ipi6_ifindex)
- break;
- }
-
/* Don't do anything if the user hasn't configured it. */
- if (ifp != NULL &&
- (ifp->active != IF_ACTIVE_USER ||
- !(ifp->options->options & DHCPCD_IPV6)))
+ if (ifp->active != IF_ACTIVE_USER ||
+ !(ifp->options->options & DHCPCD_IPV6))
return;
icp = (struct icmp6_hdr *)buf;