u_int rr_counter;
};
+/**
+ * Get the destination IPv4 address of a received packet, depending on the
+ * available mechanism.
+ */
+#ifdef IP_PKTINFO
+
+static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ struct sockaddr_in dst = {
+ .sin_family = AF_INET,
+ .sin_port = htons(port),
+ };
+ struct in_pktinfo *pktinfo;
+ struct in_addr *addr;
+
+ if (cmsgptr->cmsg_type == IP_PKTINFO)
+ {
+ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
+ addr = &pktinfo->ipi_addr;
+ memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
+ return host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ return NULL;
+}
+
+#elif defined(IP_RECVDSTADDR)
+
+static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ struct sockaddr_in dst = {
+ .sin_family = AF_INET,
+ .sin_port = htons(port),
+ };
+ struct in_addr *addr;
+
+ if (cmsgptr->cmsg_type == IP_RECVDSTADDR)
+ {
+ addr = (struct in_addr*)CMSG_DATA(cmsgptr);
+ memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
+ return host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ return NULL;
+}
+
+#else /* IP_PKTINFO || IP_RECVDSTADDR */
+
+static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ return NULL;
+}
+
+#endif /* IP_PKTINFO || IP_RECVDSTADDR */
+
+/**
+ * Get the destination IPv6 address of a received packet, depending on the
+ * available mechanism.
+ */
+#ifdef HAVE_IN6_PKTINFO
+
+static host_t *get_dst_v6(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ struct in6_pktinfo *pktinfo;
+ struct sockaddr_in6 dst = {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons(port),
+ };
+
+ if (cmsgptr->cmsg_type == IPV6_PKTINFO)
+ {
+ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
+ memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
+ return host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ return NULL;
+}
+
+#else /* HAVE_IN6_PKTINFO */
+
+static host_t *get_dst_v6(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ return NULL;
+}
+
+#endif /* HAVE_IN6_PKTINFO */
+
METHOD(socket_t, receiver, status_t,
private_socket_default_socket_t *this, packet_t **packet)
{
DBG1(DBG_NET, "error reading ancillary data");
return FAILED;
}
-
-#ifdef HAVE_IN6_PKTINFO
- if (cmsgptr->cmsg_level == SOL_IPV6 &&
- cmsgptr->cmsg_type == IPV6_PKTINFO)
+ if (cmsgptr->cmsg_level == SOL_IP)
{
- struct in6_pktinfo *pktinfo;
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
- struct sockaddr_in6 dst;
-
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
- dst.sin6_family = AF_INET6;
- dst.sin6_port = htons(port);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+ dest = get_dst_v4(cmsgptr, port);
}
-#endif /* HAVE_IN6_PKTINFO */
- if (cmsgptr->cmsg_level == SOL_IP &&
-#ifdef IP_PKTINFO
- cmsgptr->cmsg_type == IP_PKTINFO
-#elif defined(IP_RECVDSTADDR)
- cmsgptr->cmsg_type == IP_RECVDSTADDR
-#else
- FALSE
-#endif
- )
+ else if (cmsgptr->cmsg_level == SOL_IPV6)
{
- struct in_addr *addr;
- struct sockaddr_in dst;
-
-#ifdef IP_PKTINFO
- struct in_pktinfo *pktinfo;
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
- addr = &pktinfo->ipi_addr;
-#elif defined(IP_RECVDSTADDR)
- addr = (struct in_addr*)CMSG_DATA(cmsgptr);
-#endif
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
-
- dst.sin_family = AF_INET;
- dst.sin_port = htons(port);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+ dest = get_dst_v6(cmsgptr, port);
}
if (dest)
{