The branch, master has been updated
       via  096c9a7 tests: Add more tests for socket options.
       via  e7f7bec swrap: Support more socket options in getsockopt().
       via  c9b06b3 echo_srv: Add support for IP_SENDSRCADDR.
       via  27be91d swrap: Call swrap_msghdr_filter_cmsghdr in 
swrap_sendmsg_before().
       via  4849b2e swrap: Add swrap_msghdr_filter_cmsg_pktinfo().
       via  69f22c9 swrap: Add swrap_sendmsg_filter_cmsg_socket().
       via  63c59be swrap: Add swrap_sendmsg_copy_cmsg().
       via  c9332d4 swrap: Add swrap_sendmsg_filter_cmsghdr().
       via  3c55e35 echo_srv: Implement support for IP_RECVDSTADDR on BSD.
       via  29f24e5 swrap: Implement support for IP_RECVDSTADDR on BSD.
       via  75271e6 echo_srv: Fix building on OpenIndiana.
       via  13ea22c swrap: Check if the in_pktinfo structure is available.
       via  f81b6e8 swrap: Silence a warning on OpenIndiana.
       via  d977b0e tests: Fix assert_sockaddr_equal() file and line output.
       via  f60415a cmake: Add some warnings were we should error out.
       via  54d74cb swrap: Properly cache the handle also in LIBC_SO case.
      from  b9404d4 cmake: Fix a typo in socket_wrapper-config.cmake.in.

http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 096c9a7545ab5a406859a67374ca8a1c9d046f28
Author: Andreas Schneider <a...@samba.org>
Date:   Thu May 22 11:32:22 2014 +0200

    tests: Add more tests for socket options.
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit e7f7bec0b56acd7b9744af53f7d96a53abd46ad3
Author: Andreas Schneider <a...@samba.org>
Date:   Thu May 22 11:18:08 2014 +0200

    swrap: Support more socket options in getsockopt().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit c9b06b39df767539e47da8b6ce2208a5463a5314
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 14:36:23 2014 +0200

    echo_srv: Add support for IP_SENDSRCADDR.
    
    Pair-Programmed-With: Michael Adam <ob...@samba.org>
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Signed-off-by: Michael Adam <ob...@samba.org>

commit 27be91da8fbb56826c361abd67ebb1e081540bfe
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 14:35:59 2014 +0200

    swrap: Call swrap_msghdr_filter_cmsghdr in swrap_sendmsg_before().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 4849b2ebbfca6176e685ac9c6c933aad8470295f
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 14:35:34 2014 +0200

    swrap: Add swrap_msghdr_filter_cmsg_pktinfo().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 69f22c94b4ad061263c40c8c271a86f444cee72d
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 15:44:23 2014 +0200

    swrap: Add swrap_sendmsg_filter_cmsg_socket().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 63c59be9ace8282ed19b15fa9d66c7448c1bdd97
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 15:48:33 2014 +0200

    swrap: Add swrap_sendmsg_copy_cmsg().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit c9332d48d55925c585641bbd7069f3a4c774e3c1
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 15:42:14 2014 +0200

    swrap: Add swrap_sendmsg_filter_cmsghdr().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 3c55e35cad90ef3c1126b390cf53b860c99fdd6e
Author: Andreas Schneider <a...@samba.org>
Date:   Mon May 26 11:07:45 2014 +0200

    echo_srv: Implement support for IP_RECVDSTADDR on BSD.
    
    Pair-Programmed-With: Michael Adam <ob...@samba.org>
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Signed-off-by: Michael Adam <ob...@samba.org>

commit 29f24e5cc059ed37117126838045f85b494fc288
Author: Andreas Schneider <a...@samba.org>
Date:   Mon May 26 11:00:09 2014 +0200

    swrap: Implement support for IP_RECVDSTADDR on BSD.
    
    Pair-Programmed-With: Michael Adam <ob...@samba.org>
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Signed-off-by: Michael Adam <ob...@samba.org>

commit 75271e62121ba207076add1378d716adcf3ee47f
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 09:26:13 2014 +0200

    echo_srv: Fix building on OpenIndiana.
    
    Solaris doesn't have support for auxillary messages.
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 13ea22cdaac3b5855232f1f59d910b628847ffe2
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 10:01:21 2014 +0200

    swrap: Check if the in_pktinfo structure is available.
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit f81b6e84d57a6d40dce96b49cf18d924ab282872
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 09:20:31 2014 +0200

    swrap: Silence a warning on OpenIndiana.
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit d977b0ee9570757cb15014c18787d366956d7901
Author: Andreas Schneider <a...@samba.org>
Date:   Wed May 21 14:52:21 2014 +0200

    tests: Fix assert_sockaddr_equal() file and line output.
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit f60415a3ae411454551adc494e65fff7412e270e
Author: Andreas Schneider <a...@samba.org>
Date:   Fri May 23 08:50:47 2014 +0200

    cmake: Add some warnings were we should error out.
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 54d74cb22eb17107bdc8c36c24c43a1f2d16914e
Author: Pino Toscano <toscano.p...@tiscali.it>
Date:   Thu May 8 16:26:43 2014 +0200

    swrap: Properly cache the handle also in LIBC_SO case.
    
    Small regression introduced by me in commit
    0fa56909442c3cfea6a697681ea0e89ba5a0aa0f.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10572
    
    Reviewed-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 ConfigureChecks.cmake                    |    1 +
 cmake/Modules/DefineCompilerFlags.cmake  |    6 +
 config.h.cmake                           |    1 +
 src/socket_wrapper.c                     |  231 ++++++++++++++++++++++++++++-
 tests/echo_srv.c                         |  102 +++++++++++--
 tests/test_echo_tcp_get_peer_sock_name.c |    3 +-
 tests/test_echo_tcp_socket_options.c     |  147 +++++++++++++++++++
 7 files changed, 466 insertions(+), 25 deletions(-)


Changeset truncated at 500 lines:

diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 2d4c409..3a31f50 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -82,6 +82,7 @@ endif (UNIX)
 set(SWRAP_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL 
"socket_wrapper required system libraries")
 
 # STRUCTS
+check_struct_has_member("struct in_pktinfo" ipi_addr 
"sys/types.h;sys/socket.h;netinet/in.h" HAVE_STRUCT_IN_PKTINFO)
 set(CMAKE_REQUIRED_FLAGS -D_GNU_SOURCE)
 check_struct_has_member("struct in6_pktinfo" ipi6_addr 
"sys/types.h;sys/socket.h;netinet/in.h" HAVE_STRUCT_IN6_PKTINFO)
 set(CMAKE_REQUIRED_FLAGS)
diff --git a/cmake/Modules/DefineCompilerFlags.cmake 
b/cmake/Modules/DefineCompilerFlags.cmake
index e522a6a..e6fab88 100644
--- a/cmake/Modules/DefineCompilerFlags.cmake
+++ b/cmake/Modules/DefineCompilerFlags.cmake
@@ -11,10 +11,14 @@ if (UNIX AND NOT WIN32)
 
         # add -Wconversion ?
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
+
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow 
-Wmissing-prototypes -Wdeclaration-after-statement")
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal 
-Wpointer-arith -Wwrite-strings -Wformat-security")
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
 
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=pointer-arith 
-Werror=declaration-after-statement")
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} 
-Werror=implicit-function-declaration")
+
         # with -fPIC
         check_c_compiler_flag("-fPIC" WITH_FPIC)
         if (WITH_FPIC)
@@ -33,6 +37,8 @@ if (UNIX AND NOT WIN32)
                 if (WITH_FORTIFY_SOURCE)
                     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} 
-Wp,-D_FORTIFY_SOURCE=2")
                 endif (WITH_FORTIFY_SOURCE)
+
+                set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=uninitialized")
             endif()
         endif()
     endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
diff --git a/config.h.cmake b/config.h.cmake
index 57a2f12..02c016e 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -22,6 +22,7 @@
 
 /**************************** STRUCTS ****************************/
 
+#cmakedefine HAVE_STRUCT_IN_PKTINFO 1
 #cmakedefine HAVE_STRUCT_IN6_PKTINFO 1
 
 /************************ STRUCT MEMBERS *************************/
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 01a498f..19ac184 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -125,6 +125,18 @@ enum swrap_dbglvl_e {
 # endif /* IPV6_RECVPKTINFO */
 #endif /* IPV6_PKTINFO */
 
+/*
+ * On BSD IP_PKTINFO has a different name because during
+ * the time when they implemented it, there was no RFC.
+ * The name for IPv6 is the same as on Linux.
+ */
+#ifndef IP_PKTINFO
+# ifdef IP_RECVDSTADDR
+#  define IP_PKTINFO IP_RECVDSTADDR
+# endif
+#endif
+
+
 #define SWRAP_DLIST_ADD(list,item) do { \
        if (!(list)) { \
                (item)->prev    = NULL; \
@@ -434,6 +446,8 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 #ifdef LIBC_SO
                if (handle == NULL) {
                        handle = dlopen(LIBC_SO, flags);
+
+                       swrap.libc_handle = handle;
                }
 #endif
                if (handle == NULL) {
@@ -2830,6 +2844,12 @@ int getsockname(int s, struct sockaddr *name, socklen_t 
*addrlen)
  *   GETSOCKOPT
  ***************************************************************************/
 
+#ifndef SO_PROTOCOL
+# ifdef SO_PROTOTYPE /* The Solaris name */
+#  define SO_PROTOCOL SO_PROTOTYPE
+# endif /* SO_PROTOTYPE */
+#endif /* SO_PROTOCOL */
+
 static int swrap_getsockopt(int s, int level, int optname,
                            void *optval, socklen_t *optlen)
 {
@@ -2844,11 +2864,46 @@ static int swrap_getsockopt(int s, int level, int 
optname,
        }
 
        if (level == SOL_SOCKET) {
-               return libc_getsockopt(s,
-                                      level,
-                                      optname,
-                                      optval,
-                                      optlen);
+               switch (optname) {
+#ifdef SO_DOMAIN
+               case SO_DOMAIN:
+                       if (optval == NULL || optlen == NULL ||
+                           *optlen < (socklen_t)sizeof(int)) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+
+                       *optlen = sizeof(int);
+                       *(int *)optval = si->family;
+                       return 0;
+#endif /* SO_DOMAIN */
+               case SO_PROTOCOL:
+                       if (optval == NULL || optlen == NULL ||
+                           *optlen < (socklen_t)sizeof(int)) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+
+                       *optlen = sizeof(int);
+                       *(int *)optval = si->protocol;
+                       return 0;
+               case SO_TYPE:
+                       if (optval == NULL || optlen == NULL ||
+                           *optlen < (socklen_t)sizeof(int)) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+
+                       *optlen = sizeof(int);
+                       *(int *)optval = si->type;
+                       return 0;
+               default:
+                       return libc_getsockopt(s,
+                                              level,
+                                              optname,
+                                              optval,
+                                              optlen);
+               }
        }
 
        errno = ENOPROTOOPT;
@@ -2981,6 +3036,15 @@ int ioctl(int s, unsigned long int r, ...)
  *****************/
 
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+
+#ifndef CMSG_ALIGN
+# ifdef _ALIGN /* BSD */
+#define CMSG_ALIGN _ALIGN
+# else
+#error NO_CMSG_ALIGN
+# endif /* _ALIGN */
+#endif /* CMSG_ALIGN */
+
 /**
  * @brief Add a cmsghdr to a msghdr.
  *
@@ -3051,10 +3115,15 @@ static int swrap_msghdr_add_pktinfo(struct socket_info 
*si,
 {
        /* Add packet info */
        switch (si->pktinfo) {
-#ifdef IP_PKTINFO
+#if defined(IP_PKTINFO)
+/* && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR)) */
        case AF_INET: {
                struct sockaddr_in *sin;
+#if defined(HAVE_STRUCT_IN_PKTINFO)
                struct in_pktinfo pkt;
+#elif defined(IP_RECVDSTADDR)
+               struct in_addr pkt;
+#endif
 
                if (si->bindname_len == sizeof(struct sockaddr_in)) {
                        sin = (struct sockaddr_in*)si->bindname;
@@ -3067,8 +3136,12 @@ static int swrap_msghdr_add_pktinfo(struct socket_info 
*si,
 
                ZERO_STRUCT(pkt);
 
+#if defined(HAVE_STRUCT_IN_PKTINFO)
                pkt.ipi_ifindex = socket_wrapper_default_iface();
                pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
+#elif defined(IP_RECVDSTADDR)
+               pkt = sin->sin_addr;
+#endif
 
                swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
                                         &pkt, sizeof(pkt));
@@ -3121,6 +3194,117 @@ static int swrap_msghdr_add_socket_info(struct 
socket_info *si,
 
        return rc;
 }
+
+static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
+                                  uint8_t *cm_data,
+                                  size_t *cm_data_space);
+static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
+                                           uint8_t *cm_data,
+                                           size_t *cm_data_space);
+
+static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
+                                       uint8_t *cm_data,
+                                       size_t *cm_data_space) {
+       struct cmsghdr *cmsg;
+       int rc = -1;
+
+       /* Nothing to do */
+       if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
+               return 0;
+       }
+
+       for (cmsg = CMSG_FIRSTHDR(msg);
+            cmsg != NULL;
+            cmsg = CMSG_NXTHDR(msg, cmsg)) {
+               switch (cmsg->cmsg_level) {
+               case IPPROTO_IP:
+                       rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
+                                                             cm_data,
+                                                             cm_data_space);
+                       break;
+               default:
+                       rc = swrap_sendmsg_copy_cmsg(cmsg,
+                                                    cm_data,
+                                                    cm_data_space);
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
+                                  uint8_t *cm_data,
+                                  size_t *cm_data_space)
+{
+       size_t cmspace;
+       uint8_t *p;
+
+       cmspace =
+               (*cm_data_space) +
+               CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)));
+
+       p = realloc(cm_data, cmspace);
+       if (p == NULL) {
+               return -1;
+       }
+       cm_data = p;
+
+       p = cm_data + (*cm_data_space);
+       *cm_data_space = cmspace;
+
+       memcpy(p, cmsg, cmsg->cmsg_len);
+
+       return 0;
+}
+
+static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
+                                           uint8_t *cm_data,
+                                           size_t *cm_data_space);
+
+
+static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
+                                           uint8_t *cm_data,
+                                           size_t *cm_data_space)
+{
+       int rc = -1;
+
+       switch(cmsg->cmsg_type) {
+#ifdef IP_PKTINFO
+       case IP_PKTINFO:
+               rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
+                                                      cm_data,
+                                                      cm_data_space);
+               break;
+#endif
+#ifdef IPV6_PKTINFO
+       case IPV6_PKTINFO:
+               rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
+                                                      cm_data,
+                                                      cm_data_space);
+               break;
+#endif
+       default:
+               break;
+       }
+
+       return rc;
+}
+
+static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
+                                            uint8_t *cm_data,
+                                            size_t *cm_data_space)
+{
+       (void)cmsg; /* unused */
+       (void)cm_data; /* unused */
+       (void)cm_data_space; /* unused */
+
+       /*
+        * Passing a IP pktinfo to a unix socket might be rejected by the
+        * Kernel, at least on FreeBSD. So skip this cmsg.
+        */
+       return 0;
+}
 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
 
 static ssize_t swrap_sendmsg_before(int fd,
@@ -3243,6 +3427,28 @@ static ssize_t swrap_sendmsg_before(int fd,
                return -1;
        }
 
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
+               uint8_t *cmbuf = NULL;
+               size_t cmlen = 0;
+
+               ret = swrap_sendmsg_filter_cmsghdr(msg, cmbuf, &cmlen);
+               if (ret < 0) {
+                       free(cmbuf);
+                       return -1;
+               }
+
+               if (cmlen == 0) {
+                       msg->msg_controllen = 0;
+                       msg->msg_control = NULL;
+               } else if (cmlen < msg->msg_controllen) {
+                       memcpy(msg->msg_control, cmbuf, cmlen);
+                       msg->msg_controllen = cmlen;
+               }
+               free(cmbuf);
+       }
+#endif
+
        return 0;
 }
 
@@ -3875,8 +4081,10 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, 
int flags)
        struct socket_info *si;
        struct msghdr msg;
        struct iovec tmp;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
        size_t msg_ctrllen_filled;
        size_t msg_ctrllen_left;
+#endif
 
        ssize_t ret;
        int rc;
@@ -3988,8 +4196,15 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr 
*omsg, int flags)
        msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
        msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
-       msg.msg_control = omsg->msg_control;       /* ancillary data, see below 
*/
-       msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len 
*/
+       if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
+               /* omsg is a const so use a local buffer for modifications */
+               uint8_t cmbuf[omsg->msg_controllen];
+
+               memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
+
+               msg.msg_control = cmbuf;       /* ancillary data, see below */
+               msg.msg_controllen = omsg->msg_controllen; /* ancillary data 
buffer len */
+       }
        msg.msg_flags = omsg->msg_flags;           /* flags on received message 
*/
 #endif
 
diff --git a/tests/echo_srv.c b/tests/echo_srv.c
index 33f2ebd..88d8170 100644
--- a/tests/echo_srv.c
+++ b/tests/echo_srv.c
@@ -55,14 +55,24 @@ struct echo_srv_opts {
     const char *pidfile;
 };
 
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+
+#if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_PKTINFO)
 union pktinfo {
 #ifdef HAVE_STRUCT_IN6_PKTINFO
        struct in6_pktinfo pkt6;
 #endif
+#ifdef HAVE_STRUCT_IN_PKTINFO
        struct in_pktinfo pkt4;
+#elif defined(IP_RECVDSTADDR)
+       struct in_addr pkt4;
+#endif
        char c;
 };
 
+#define HAVE_UNION_PKTINFO 1
+#endif /* IP_PKTINFO || IP_RECVDSTADDR || IPV6_PKTINFO */
+
 static const char *echo_server_address(int family)
 {
        switch (family) {
@@ -90,6 +100,7 @@ static const char *echo_server_address(int family)
 
        return NULL;
 }
+#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
 
 static void _assert_return_code(int rc,
                                int err,
@@ -216,12 +227,24 @@ static void set_sock_pktinfo(int sock, int family)
        switch(family) {
        case AF_INET:
                proto = IPPROTO_IP;
+#ifdef IP_PKTINFO
                option = IP_PKTINFO;
+#elif IP_RECVDSTADDR
+               option = IP_RECVDSTADDR;
+#else
+               return;
+#endif /* IP_PKTINFO */
                break;
+#ifdef HAVE_IPV6
+#ifdef IPV6_RECVPKTINFO
        case AF_INET6:
                proto = IPPROTO_IPV6;
                option = IPV6_RECVPKTINFO;
                break;
+#endif /* IPV6_RECVPKTINFO */
+#endif /* HAVE_IPV6 */
+       default:
+               return;
        }
 
        rc = setsockopt(sock, proto, option, &sockopt, sizeof(sockopt));
@@ -541,11 +564,15 @@ static ssize_t echo_udp_recv_from_to(int sock,
 {
        struct msghdr rmsg;
        struct iovec riov;
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       ssize_t ret;
+
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO)
        size_t cmlen = CMSG_LEN(sizeof(union pktinfo));
        char cmsg[cmlen];
-#endif
-       ssize_t ret;
+#else
+       (void)to; /* unused */
+       (void)tolen; /* unused */
+#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
 
        riov.iov_base = buf;
        riov.iov_len = buflen;
@@ -558,7 +585,7 @@ static ssize_t echo_udp_recv_from_to(int sock,
        rmsg.msg_iov = &riov;
        rmsg.msg_iovlen = 1;
 
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO)
        memset(cmsg, 0, cmlen);
 
        rmsg.msg_control = cmsg;
@@ -571,6 +598,7 @@ static ssize_t echo_udp_recv_from_to(int sock,
        }
        *fromlen = rmsg.msg_namelen;
 
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO)
        if (rmsg.msg_controllen > 0) {
                struct cmsghdr *cmsgptr;
 
@@ -578,11 +606,12 @@ static ssize_t echo_udp_recv_from_to(int sock,
                while (cmsgptr != NULL) {
                        const char *p;
 
+#if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO)
                        if (cmsgptr->cmsg_level == IPPROTO_IP &&
                                        cmsgptr->cmsg_type == IP_PKTINFO) {
                                char ip[INET_ADDRSTRLEN] = { 0 };
-                               struct in_pktinfo *pkt;
                                struct sockaddr_in *sinp = (struct sockaddr_in 
*)to;
+                               struct in_pktinfo *pkt;
 
                                pkt = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
 
@@ -601,7 +630,33 @@ static ssize_t echo_udp_recv_from_to(int sock,
                                        abort();
                                }
                        }
-#ifdef IPV6_PKTINFO
+#endif /* IP_PKTINFO */
+#ifdef IP_RECVDSTADDR
+                       if (cmsgptr->cmsg_level == IPPROTO_IP &&
+                           cmsgptr->cmsg_type == IP_RECVDSTADDR) {
+                               char ip[INET_ADDRSTRLEN] = { 0 };
+                               struct sockaddr_in *sinp = (struct sockaddr_in 
*)to;
+                               struct in_addr *addr;
+
+                               addr = (struct in_addr *)CMSG_DATA(cmsgptr);
+
+                               sinp->sin_family = AF_INET;
+                               sinp->sin_addr = *addr;


-- 
Socket Wrapper Repository

Reply via email to