[SCM] Socket Wrapper Repository - branch master updated

Andreas Schneider asn at samba.org
Mon May 26 08:52:34 MDT 2014


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 <asn at samba.org>
Date:   Thu May 22 11:32:22 2014 +0200

    tests: Add more tests for socket options.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

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

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

    echo_srv: Add support for IP_SENDSRCADDR.
    
    Pair-Programmed-With: Michael Adam <obnox at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 27be91da8fbb56826c361abd67ebb1e081540bfe
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    swrap: Add swrap_msghdr_filter_cmsg_pktinfo().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    swrap: Add swrap_sendmsg_filter_cmsg_socket().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    swrap: Add swrap_sendmsg_copy_cmsg().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    swrap: Add swrap_sendmsg_filter_cmsghdr().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 3c55e35cad90ef3c1126b390cf53b860c99fdd6e
Author: Andreas Schneider <asn at 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 <obnox at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

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

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

commit 75271e62121ba207076add1378d716adcf3ee47f
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 13ea22cdaac3b5855232f1f59d910b628847ffe2
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

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

commit d977b0ee9570757cb15014c18787d366956d7901
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit f60415a3ae411454551adc494e65fff7412e270e
Author: Andreas Schneider <asn at 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 <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 54d74cb22eb17107bdc8c36c24c43a1f2d16914e
Author: Pino Toscano <toscano.pino at 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 <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at 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


More information about the samba-cvs mailing list