From a30e8dc12157a1c20a92d6dac38fc0ab49a72c17 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 17 Oct 2015 18:02:15 +0000 Subject: [PATCH] native: Check if in_pktinfo exists. If it does not exist, `typedef in_addr in_pktinfo`. --- src/Native/Common/pal_config.h.in | 1 + src/Native/System.Native/pal_networking.cpp | 19 +++++++++++++++++++ src/Native/configure.cmake | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/Native/Common/pal_config.h.in b/src/Native/Common/pal_config.h.in index 4ca23d988c63..00aeb70732d6 100644 --- a/src/Native/Common/pal_config.h.in +++ b/src/Native/Common/pal_config.h.in @@ -32,6 +32,7 @@ #cmakedefine01 HAVE_ECHO #cmakedefine01 HAVE_ICANON #cmakedefine01 HAVE_TCSANOW +#cmakedefine01 HAVE_IN_PKTINFO // Mac OS X has stat64, but it is deprecated since plain stat now // provides the same 64-bit aware struct when targeting OS X > 10.5 diff --git a/src/Native/System.Native/pal_networking.cpp b/src/Native/System.Native/pal_networking.cpp index a56f2bedc6f5..ab9abe5b5abd 100644 --- a/src/Native/System.Native/pal_networking.cpp +++ b/src/Native/System.Native/pal_networking.cpp @@ -27,6 +27,17 @@ #include #include +#if !HAVE_IN_PKTINFO +// On platforms, such as FreeBSD, where in_pktinfo +// is not available, fallback to custom definition +// with required members. +struct in_pktinfo +{ + in_addr ipi_addr; +}; +#define IP_PKTINFO IP_RECVDSTADDR +#endif + #if !defined(IPV6_ADD_MEMBERSHIP) && defined(IPV6_JOIN_GROUP) #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP #endif @@ -1055,7 +1066,15 @@ static int32_t GetIPv4PacketInformation(cmsghdr* controlMessage, IPPacketInforma auto* pktinfo = reinterpret_cast(CMSG_DATA(controlMessage)); ConvertInAddrToByteArray(&packetInfo->Address.Address[0], NUM_BYTES_IN_IPV4_ADDRESS, pktinfo->ipi_addr); +#if HAVE_IN_PKTINFO packetInfo->InterfaceIndex = static_cast(pktinfo->ipi_ifindex); +#else + // TODO: Figure out how to get interface index with in_addr. + // One option is http://www.unix.com/man-page/freebsd/3/if_nametoindex + // which requires interface name to be known. + // Meanwhile: + packetInfo->InterfaceIndex = 0; +#endif return 1; } diff --git a/src/Native/configure.cmake b/src/Native/configure.cmake index 6fe0db30d5ad..49ad5195297f 100644 --- a/src/Native/configure.cmake +++ b/src/Native/configure.cmake @@ -5,11 +5,31 @@ include(CheckIncludeFiles) include(CheckPrototypeDefinition) include(CheckStructHasMember) include(CheckSymbolExists) +include(CheckTypeSize) #CMake does not include /usr/local/include into the include search path #thus add it manually. This is required on FreeBSD. include_directories(SYSTEM /usr/local/include) +# in_pktinfo: Find whether this struct exists +check_include_files( + linux/in.h + HAVE_LINUX_IN_H) + +if (HAVE_LINUX_IN_H) + set (SOCKET_INCLUDES ${SOCKET_INCLUDES} linux/in.h) +else () + set (SOCKET_INCLUDES ${SOCKET_INCLUDES} netinet/in.h) +endif () + +set(CMAKE_EXTRA_INCLUDE_FILES ${SOCKET_INCLUDES}) +check_type_size( + "struct in_pktinfo" + HAVE_IN_PKTINFO + BUILTIN_TYPES_ONLY) +set(CMAKE_EXTRA_INCLUDE_FILES) # reset CMAKE_EXTRA_INCLUDE_FILES +# /in_pktinfo + check_include_files( alloca.h HAVE_ALLOCA_H)