krb5 commit: Add support for IP_SENDSRCADDR for UDP pktinfo
Greg Hudson
ghudson at mit.edu
Wed Feb 17 15:38:01 EST 2016
https://github.com/krb5/krb5/commit/457a4ac5057d44c0c947efc3c047c32897b54747
commit 457a4ac5057d44c0c947efc3c047c32897b54747
Author: Sarah Day <sarahday at mit.edu>
Date: Thu Feb 11 15:39:04 2016 -0500
Add support for IP_SENDSRCADDR for UDP pktinfo
FreeBSD uses IP_RECVDSTADDR and IP_SENDSRCADDR instead of IP_PKTINFO
for IPv4 pktinfo functionality. Add support for using this when
IP_PKTINFO is not available.
src/lib/apputils/udppktinfo.c | 77 +++++++++++++++++++++++++++++++++++++----
1 files changed, 70 insertions(+), 7 deletions(-)
diff --git a/src/lib/apputils/udppktinfo.c b/src/lib/apputils/udppktinfo.c
index aa601fa..8fafb15 100644
--- a/src/lib/apputils/udppktinfo.c
+++ b/src/lib/apputils/udppktinfo.c
@@ -36,7 +36,8 @@
#define HAVE_IPV6_PKTINFO
#endif
-#if defined(HAVE_IP_PKTINFO) || defined(HAVE_IPV6_PKTINFO)
+#if defined(HAVE_IP_PKTINFO) || defined(IP_SENDSRCADDR) || \
+ defined(HAVE_IPV6_PKTINFO)
#define HAVE_PKTINFO_SUPPORT
#endif
@@ -60,6 +61,9 @@ union pktinfo {
#ifdef HAVE_STRUCT_IN_PKTINFO
struct in_pktinfo pi4;
#endif
+#ifdef IP_RECVDSTADDR
+ struct in_addr iaddr;
+#endif
char c;
};
#endif /* HAVE_IPV6_PKTINFO && HAVE_STRUCT_CMSGHDR && HAVE_PKTINFO_SUPPORT */
@@ -100,9 +104,20 @@ set_ipv4_recvpktinfo(int sock)
sizeof(sockopt));
}
-#else /* HAVE_IP_PKTINFO */
+#elif defined(IP_RECVDSTADDR) /* HAVE_IP_PKTINFO */
+
+#define set_ipv4_pktinfo set_ipv4_recvdstaddr
+static inline krb5_error_code
+set_ipv4_recvdstaddr(int sock)
+{
+ int sockopt = 1;
+ return setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &sockopt,
+ sizeof(sockopt));
+}
+
+#else /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */
#define set_ipv4_pktinfo(s) EINVAL
-#endif /* HAVE_IP_PKTINFO */
+#endif /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */
#ifdef HAVE_IPV6_PKTINFO
@@ -170,9 +185,37 @@ check_cmsg_ip_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr *to,
return 0;
}
-#else /* HAVE_IP_PKTINFO */
+#elif defined(IP_RECVDSTADDR) /* HAVE_IP_PKTINFO */
+
+static inline struct in_addr *
+cmsg2sin(struct cmsghdr *cmsgptr)
+{
+ return (struct in_addr *)(void *)CMSG_DATA(cmsgptr);
+}
+
+#define check_cmsg_v4_pktinfo check_cmsg_ip_recvdstaddr
+static int
+check_cmsg_ip_recvdstaddr(struct cmsghdr *cmsgptr, struct sockaddr *to,
+ socklen_t *tolen, aux_addressing_info * auxaddr)
+{
+ if (cmsgptr->cmsg_level == IPPROTO_IP &&
+ cmsgptr->cmsg_type == IP_RECVDSTADDR &&
+ *tolen >= sizeof(struct sockaddr_in)) {
+ struct in_addr *sin_addr;
+
+ memset(to, 0, sizeof(struct sockaddr_in));
+ sin_addr = cmsg2sin(cmsgptr);
+ sa2sin(to)->sin_addr = *sin_addr;
+ sa2sin(to)->sin_family = AF_INET;
+ *tolen = sizeof(struct sockaddr_in);
+ return 1;
+ }
+ return 0;
+}
+
+#else /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */
#define check_cmsg_v4_pktinfo(c, t, l, a) 0
-#endif /* HAVE_IP_PKTINFO */
+#endif /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */
#ifdef HAVE_IPV6_PKTINFO
@@ -314,9 +357,29 @@ set_msg_from_ip_pktinfo(struct msghdr *msg, struct cmsghdr *cmsgptr,
return 0;
}
-#else /* HAVE_IP_PKTINFO */
+#elif defined(IP_SENDSRCADDR) /* HAVE_IP_PKTINFO */
+
+#define set_msg_from_ipv4 set_msg_from_ip_sendsrcaddr
+static krb5_error_code
+set_msg_from_ip_sendsrcaddr(struct msghdr *msg, struct cmsghdr *cmsgptr,
+ struct sockaddr *from, socklen_t fromlen,
+ aux_addressing_info *auxaddr)
+{
+ struct in_addr *sin_addr = cmsg2sin(cmsgptr);
+ const struct sockaddr_in *from4 = sa2sin(from);
+ if (fromlen != sizeof(struct sockaddr_in))
+ return EINVAL;
+ cmsgptr->cmsg_level = IPPROTO_IP;
+ cmsgptr->cmsg_type = IP_SENDSRCADDR;
+ cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+ msg->msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
+ *sin_addr = from4->sin_addr;
+ return 0;
+}
+
+#else /* HAVE_IP_PKTINFO || IP_SENDSRCADDR */
#define set_msg_from_ipv4(m, c, f, l, a) EINVAL
-#endif /* HAVE_IP_PKTINFO */
+#endif /* HAVE_IP_PKTINFO || IP_SENDSRCADDR */
#ifdef HAVE_IPV6_PKTINFO
More information about the cvs-krb5
mailing list