From: Matt Kimball Date: Fri, 30 Dec 2016 19:44:32 +0000 (-0800) Subject: build: Fix Solaris build issues X-Git-Tag: v0.88~12^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f19df41bba10b570b06383e5cd6e00b85d9bc3bc;p=thirdparty%2Fmtr.git build: Fix Solaris build issues Prefer ncurses over curses, since curses on Solaris is lacking wattr_on and wattr_off, but ncurses has them. Check if sys/ctypes.h exists, since Solaris lacks it. When sending an IPv6 probe, check if the send socket is already bound to the intended source address, and if so, avoid rebinding. Rebinding return an error on Solaris. --- diff --git a/README b/README index b2d6319..1ff5c0f 100644 --- a/README +++ b/README @@ -31,14 +31,17 @@ INSTALLING make install - Note that mtr must be suid-root because it requires access to raw IP - sockets. See SECURITY for security information. + Note that mtr-packet must be suid-root because it requires access to + raw IP sockets. See SECURITY for security information. Older versions used to require a non-existent path to GTK for a correct build of a non-gtk version while GTK was installed. This is no longer necessary. ./configure --without-gtk should now work. If it doesn't, try "make WITHOUT_X11=YES" as the make step. + On Solaris, you'll need to use GNU make to build. + (Use 'gmake' rather than 'make'.) + On Solaris (and possibly other systems) the "gtk" library may be installed in a directory where the dynamic linker refuses to look when a binary is setuid. Roman Shterenzon reports that adding @@ -51,12 +54,6 @@ INSTALLING in a setuid program, then there is something to say for moving them to the "trusted" directory.) - On Solaris, linking usually fails to find "wattr" or something like that. - Somehow, I can't seem to be able to automate "configure" finding the right - libs on Solaris. So, the solution is that you cut-and-paste the line - doing the linking into a terminal window, and add "-lcurses" by hand. - Then it will link. Help on how to catch this in autoconf appreciated. - Building on MacOS should not require any special steps. BUILDING FOR WINDOWS diff --git a/configure.ac b/configure.ac index 5d6f4ab..a08ce67 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,7 @@ AC_CHECK_HEADERS([ \ ncurses/curses.h \ netinet/in.h \ socket.h \ + sys/cdefs.h \ sys/limits.h \ sys/socket.h \ stdio_ext.h \ @@ -95,6 +96,9 @@ AC_ARG_WITH([ncurses], [AS_HELP_STRING([--without-ncurses], [Build without the ncurses interface])], [], [with_ncurses=yes]) AS_IF([test "x$with_ncurses" = "xyes"], + + # Prefer ncurses over curses, if both are available. + # (On Solaris 11.3, ncurses builds and links for us, but curses does not.) [AC_SEARCH_LIBS( [initscr], [ncurses curses], [AC_DEFINE([HAVE_CURSES], [1], [Define if a curses library available])], @@ -119,12 +123,9 @@ AC_ARG_ENABLE([ipv6], [AS_HELP_STRING([--disable-ipv6], [Do not enable IPv6])], [WANTS_IPV6=$enableval], [WANTS_IPV6=yes]) -USES_IPV6= -AC_CHECK_FUNC([getaddrinfo], [ - AS_IF([test "x$WANTS_IPV6" = "xyes"], [ - AC_DEFINE([ENABLE_IPV6], [1], [Define to enable IPv6]) - USES_IPV6=yes - ]) +AS_IF([test "x$WANTS_IPV6" = "xyes"], [ + AC_DEFINE([ENABLE_IPV6], [1], [Define to enable IPv6]) + USES_IPV6=yes ]) AC_CHECK_FUNC([socket], [], diff --git a/packet/construct_unix.c b/packet/construct_unix.c index 6fe3684..6895879 100644 --- a/packet/construct_unix.c +++ b/packet/construct_unix.c @@ -573,6 +573,9 @@ int construct_ip6_packet( { int send_socket; bool is_stream_protocol = false; + bool bind_send_socket = true; + struct sockaddr_storage current_sockaddr; + int current_sockaddr_len; if (param->protocol == IPPROTO_TCP) { is_stream_protocol = true; @@ -612,9 +615,29 @@ int construct_ip6_packet( return 0; } - if (bind(send_socket, - (struct sockaddr *)src_sockaddr, sizeof(struct sockaddr_in6))) { - return -1; + /* + Check the current socket address, and if it is the same + as the source address we intend, we will skip the bind. + This is to accomodate Solaris, which, as of Solaris 11.3, + will return an EINVAL error on bind if the socket is already + bound, even if the same address is used. + */ + current_sockaddr_len = sizeof(struct sockaddr_in6); + if (getsockname(send_socket, (struct sockaddr *)¤t_sockaddr, + ¤t_sockaddr_len) == 0) { + + if (memcmp(¤t_sockaddr, + src_sockaddr, sizeof(struct sockaddr_in6)) == 0) { + bind_send_socket = false; + } + } + + /* Bind to our local address */ + if (bind_send_socket) { + if (bind(send_socket, (struct sockaddr *)src_sockaddr, + sizeof(struct sockaddr_in6))) { + return -1; + } } /* The traffic class in IPv6 is analagous to ToS in IPv4 */ diff --git a/portability/queue.h b/portability/queue.h index 00156dd..d19a425 100644 --- a/portability/queue.h +++ b/portability/queue.h @@ -33,7 +33,11 @@ #ifndef _SYS_QUEUE_H_ #define _SYS_QUEUE_H_ +#include "config.h" + +#ifdef HAVE_SYS_CDEFS_H #include +#endif /* * This file defines four types of data structures: singly-linked lists,