NOTE: this is patch 3/3 over feat_ipv6_transport branch,
      commit 1b96baa8fc964bfba8bfba87f1e0e1fbabf0b47b

   - _both_ for IPv4 (which was missing) and for IPv6
   - tested on OpenBSD 4.7, FreeBSD 8.1

Signed-off-by: JuanJo Ciarlante <j...@google.com>
---
 socket.c  |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 socket.h  |   10 ++++++++++
 syshead.h |    5 +++--
 3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/socket.c b/socket.c
index d9e6bc9..a6f41b5 100644
--- a/socket.c
+++ b/socket.c
@@ -813,9 +813,17 @@ create_socket_udp (const unsigned int flags)
   else if (flags & SF_USE_IP_PKTINFO)
     {
       int pad = 1;
+#ifdef IP_PKTINFO
       if (setsockopt (sd, SOL_IP, IP_PKTINFO,
                      (void*)&pad, sizeof(pad)) < 0)
         msg(M_SOCKERR, "UDP: failed setsockopt for IP_PKTINFO");
+#elif defined(IP_RECVDSTADDR)
+      if (setsockopt (sd, IPPROTO_IP, IP_RECVDSTADDR,
+                     (void*)&pad, sizeof(pad)) < 0)
+        msg(M_SOCKERR, "UDP: failed setsockopt for IP_RECVDSTADDR");
+#else
+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix 
syshead.h)
+#endif
     }
 #endif
   return sd;
@@ -2474,8 +2482,15 @@ print_link_socket_actual_ex (const struct 
link_socket_actual *act,
                  struct openvpn_sockaddr sa;
                  CLEAR (sa);
                  sa.addr.in4.sin_family = AF_INET;
+#ifdef IP_PKTINFO
                  sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst;
                  if_indextoname(act->pi.in4.ipi_ifindex, ifname);
+#elif defined(IP_RECVDSTADDR)
+                 sa.addr.in4.sin_addr = act->pi.in4;
+                 ifname[0]=0;
+#else
+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix 
syshead.h)
+#endif
                  buf_printf (&out, " (via %s%%%s)",
                              print_sockaddr_ex (&sa, separator, 0, gc),
                              ifname);
@@ -2819,7 +2834,12 @@ link_socket_read_tcp (struct link_socket *sock,
 struct openvpn_in4_pktinfo
 {
   struct cmsghdr cmsghdr;
+#ifdef HAVE_IN_PKTINFO
   struct in_pktinfo pi4;
+#endif
+#ifdef IP_RECVDSTADDR
+  struct in_addr pi4;
+#endif
 };
 #ifdef USE_PF_INET6
 struct openvpn_in6_pktinfo
@@ -2864,13 +2884,26 @@ link_socket_read_udp_posix_recvmsg (struct link_socket 
*sock,
       cmsg = CMSG_FIRSTHDR (&mesg);
       if (cmsg != NULL
          && CMSG_NXTHDR (&mesg, cmsg) == NULL
+#ifdef IP_PKTINFO
          && cmsg->cmsg_level == SOL_IP 
          && cmsg->cmsg_type == IP_PKTINFO
+#elif defined(IP_RECVDSTADDR)
+         && cmsg->cmsg_level == IPPROTO_IP
+         && cmsg->cmsg_type == IP_RECVDSTADDR
+#else
+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix 
syshead.h)
+#endif
          && cmsg->cmsg_len >= sizeof (struct openvpn_in4_pktinfo))
        {
+#ifdef IP_PKTINFO
          struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
          from->pi.in4.ipi_ifindex = pkti->ipi_ifindex;
          from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst;
+#elif defined(IP_RECVDSTADDR)
+         from->pi.in4 = *(struct in_addr*) CMSG_DATA (cmsg);
+#else
+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix 
syshead.h)
+#endif
        }
 #ifdef USE_PF_INET6
       else if (cmsg != NULL
@@ -2955,7 +2988,6 @@ link_socket_write_udp_posix_sendmsg (struct link_socket 
*sock,
     case AF_INET:
       {
         struct openvpn_in4_pktinfo msgpi4;
-        struct in_pktinfo *pkti;
         mesg.msg_name = &to->dest.addr.sa;
         mesg.msg_namelen = sizeof (struct sockaddr_in);
         mesg.msg_control = &msgpi4;
@@ -2963,12 +2995,23 @@ link_socket_write_udp_posix_sendmsg (struct link_socket 
*sock,
         mesg.msg_flags = 0;
         cmsg = CMSG_FIRSTHDR (&mesg);
         cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo);
+#ifdef HAVE_IN_PKTINFO
         cmsg->cmsg_level = SOL_IP;
         cmsg->cmsg_type = IP_PKTINFO;
+       {
+        struct in_pktinfo *pkti;
         pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
         pkti->ipi_ifindex = to->pi.in4.ipi_ifindex;
         pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst;
         pkti->ipi_addr.s_addr = 0;
+       }
+#elif defined(IP_RECVDSTADDR)
+        cmsg->cmsg_level = IPPROTO_IP;
+        cmsg->cmsg_type = IP_RECVDSTADDR;
+        *(struct in_addr *) CMSG_DATA (cmsg) = to->pi.in4;
+#else
+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix 
syshead.h)
+#endif
         break;
       }
 #ifdef USE_PF_INET6
diff --git a/socket.h b/socket.h
index 757c1f8..de6d525 100644
--- a/socket.h
+++ b/socket.h
@@ -86,7 +86,12 @@ struct link_socket_actual
   struct openvpn_sockaddr dest;
 #if ENABLE_IP_PKTINFO
   union {
+#ifdef HAVE_IN_PKTINFO
     struct in_pktinfo in4;
+#endif
+#ifdef IP_RECVDSTADDR
+    struct in_addr in4;
+#endif
 #ifdef USE_PF_INET6
     struct in6_pktinfo in6;
 #endif
@@ -576,7 +581,12 @@ addr_defined_ipi (const struct link_socket_actual *lsa)
 #if ENABLE_IP_PKTINFO
   if (!lsa) return 0;
   switch (lsa->dest.addr.sa.sa_family) {
+#ifdef HAVE_IN_PKTINFO
     case AF_INET: return lsa->pi.in4.ipi_spec_dst.s_addr != 0;
+#endif
+#ifdef IP_RECVDSTADDR
+    case AF_INET: return lsa->pi.in4.s_addr != 0;
+#endif
 #ifdef USE_PF_INET6
     case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&lsa->pi.in6.ipi6_addr);
 #endif
diff --git a/syshead.h b/syshead.h
index 7577cd5..ca3358a 100644
--- a/syshead.h
+++ b/syshead.h
@@ -393,9 +393,10 @@
 #endif
 
 /*
- * Does this platform support linux-style IP_PKTINFO?
+ * Does this platform support linux-style IP_PKTINFO
+ * or bsd-style IP_RECVDSTADDR ?
  */
-#if defined(ENABLE_MULTIHOME) && defined(HAVE_IN_PKTINFO) && 
defined(IP_PKTINFO) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && 
defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && 
defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG)
+#if defined(ENABLE_MULTIHOME) && 
((defined(HAVE_IN_PKTINFO)&&defined(IP_PKTINFO)) || defined(IP_RECVDSTADDR)) && 
defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && 
defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && 
defined(HAVE_SENDMSG)
 #define ENABLE_IP_PKTINFO 1
 #else
 #define ENABLE_IP_PKTINFO 0
-- 
1.7.1




-- 
--JuanJo
oO Juan Jose Ciarlante - juanjosec Ogmail.com - jjo O{um.edu.ar,google.com}
Oo gpg --keyserver wwwkeys.eu.pgp.net --recv-key 81276430

Attachment: signature.asc
Description: Digital signature

Reply via email to