diff --git a/configure.ac b/configure.ac index b17f3bb9..d61df533 100644 --- a/configure.ac +++ b/configure.ac @@ -104,6 +104,32 @@ AC_ARG_ENABLE([debug], AS_IF([test "x$enable_debug" = "xyes"], [ AC_DEFINE([DEBUG], [1], [Define if debugging is enabled])]) +dnl Check for SOCK_DGRAM support +AC_CHECK_HEADERS([sys/socket.h]) +AC_CHECK_DECL([SOCK_DGRAM], + [have_sock_dgram=yes], + [have_sock_dgram=no], + [#include ]) + +if test "x$have_sock_dgram" = "xyes"; then + AC_ARG_ENABLE([raw-sockets], + AS_HELP_STRING([--disable-raw-sockets], [Disable use of raw sockets]), + [], [enable_raw_sockets=yes]) + AS_IF([test "x$enable_raw_sockets" = "xyes"], [ + AC_DEFINE([USE_RAWSOCKET], [1], [Enable use of raw sockets]) + ]) +else + AC_DEFINE([USE_RAWSOCKET], [1], [Enable use of raw sockets]) + AC_MSG_NOTICE([SOCK_DGRAM support missing; --disable-raw-sockets ignored]) +fi + +AC_ARG_ENABLE([fwmark], + AS_HELP_STRING([--disable-fwmark], [Disable use of SO_MARK / fwmark]), + [], [enable_fwmark=yes]) +AS_IF([test "x$enable_fwmark" = "xyes"], [ + AC_DEFINE([USE_SO_MARK], [1], [Enable use of fwmark (SO_MARK)]) +]) + AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_MAINTAINER_MODE diff --git a/src/fping.c b/src/fping.c index 83c806b9..11545d20 100644 --- a/src/fping.c +++ b/src/fping.c @@ -508,7 +508,7 @@ int main(int argc, char **argv) { "oiface", 0, OPTPARSE_REQUIRED }, { "json", 'J', OPTPARSE_NONE }, { "icmp-timestamp", 0, OPTPARSE_NONE }, -#ifdef SO_MARK +#if defined(SO_MARK) && defined(USE_SO_MARK) { "fwmark", 'k', OPTPARSE_REQUIRED }, #endif { "loop", 'l', OPTPARSE_NONE }, @@ -824,7 +824,7 @@ int main(int argc, char **argv) case 'f': filename = optparse_state.optarg; break; -#ifdef SO_MARK +#if defined(SO_MARK) && defined(USE_SO_MARK) case 'k': fwmark = (unsigned int)strtoul_strict(optparse_state.optarg, 10); if (!fwmark) @@ -3100,7 +3100,7 @@ void usage(int is_error) #ifdef IP_PKTINFO fprintf(out, " --oiface=IFACE send pings via a specific outgoing interface (receive from any)\n"); #endif -#ifdef SO_MARK +#if defined(SO_MARK) && defined(USE_SO_MARK) fprintf(out, " -k, --fwmark=FWMARK set the routing mark\n"); #endif fprintf(out, " -l, --loop loop mode: send pings forever\n"); diff --git a/src/socket4.c b/src/socket4.c index cb986e22..fe4229d0 100644 --- a/src/socket4.c +++ b/src/socket4.c @@ -60,23 +60,30 @@ static int outgoing_src_addr_set_ipv4 = 0; int open_ping_socket_ipv4(int *socktype) { struct protoent* proto; - int s; + int s = -1; /* confirm that ICMP is available on this machine */ if ((proto = getprotobyname("icmp")) == NULL) crash_and_burn("icmp: unknown protocol"); +#ifdef USE_RAWSOCKET /* create raw socket for ICMP calls (ping) */ *socktype = SOCK_RAW; s = socket(AF_INET, *socktype, proto->p_proto); +#endif + +#ifdef SOCK_DGRAM if (s < 0) { /* try non-privileged icmp (works on Mac OSX without privileges, for example) */ *socktype = SOCK_DGRAM; s = socket(AF_INET, *socktype, proto->p_proto); - if (s < 0) { - return -1; - } } +#endif + + if (s < 0) { + return -1; + } + /* Make sure that we use non-blocking IO */ { diff --git a/src/socket6.c b/src/socket6.c index ab6e199f..cc2e41bf 100644 --- a/src/socket6.c +++ b/src/socket6.c @@ -58,23 +58,17 @@ static int outgoing_src_addr_set_ipv6 = 0; int open_ping_socket_ipv6(int *socktype) { struct protoent* proto; - int s; + int s = -1; /* confirm that ICMP6 is available on this machine */ if ((proto = getprotobyname("ipv6-icmp")) == NULL) crash_and_burn("ipv6-icmp: unknown protocol"); +#ifdef USE_RAWSOCKET /* create raw socket for ICMP6 calls (ping) */ *socktype = SOCK_RAW; s = socket(AF_INET6, *socktype, proto->p_proto); - if (s < 0) { - /* try non-privileged icmp6 (works on Mac OSX without privileges, for example) */ - *socktype = SOCK_DGRAM; - s = socket(AF_INET6, *socktype, proto->p_proto); - if (s < 0) { - return -1; - } - } else { + if (s >= 0) { /* receive only ICMP6 messages relevant for fping on raw socket */ struct icmp6_filter recv_filter; @@ -89,6 +83,20 @@ int open_ping_socket_ipv6(int *socktype) errno_crash_and_burn("cannot set icmp6 message type filter"); } } +#endif + +#ifdef SOCK_DGRAM + if (s < 0) { + /* try non-privileged icmp6 (works on Mac OSX without privileges, for example) */ + *socktype = SOCK_DGRAM; + s = socket(AF_INET6, *socktype, proto->p_proto); + } +#endif + + if (s < 0) { + return -1; + } + /* Make sure that we use non-blocking IO */ {