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