]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
build: Fix Solaris build issues
authorMatt Kimball <matt.kimball@gmail.com>
Fri, 30 Dec 2016 19:44:32 +0000 (11:44 -0800)
committerMatt Kimball <matt.kimball@gmail.com>
Fri, 30 Dec 2016 21:10:23 +0000 (13:10 -0800)
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.

README
configure.ac
packet/construct_unix.c
portability/queue.h

diff --git a/README b/README
index b2d63197843940f30fb7f63ca7d8082f3e536b17..1ff5c0fe6dc3d363239019b8919d9173a24c57d2 100644 (file)
--- 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
index 5d6f4ab62eb2460b985a17d3d44571a9537a8f0c..a08ce6722e7152a8a63f0ca889f92f968bae26bd 100644 (file)
@@ -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], [],
index 6fe368486690327b0ead3e5804aecd600d9e7a67..6895879f6376fd1f6fe01e1ea9163e0e35f3b048 100644 (file)
@@ -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 *)&current_sockaddr,
+            &current_sockaddr_len) == 0) {
+
+        if (memcmp(&current_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  */
index 00156dd52a802ec86111ff4a13ff9b011585b41a..d19a425d4b30ca0958af6f377b4e7844c38e2900 100644 (file)
 #ifndef _SYS_QUEUE_H_
 #define        _SYS_QUEUE_H_
 
+#include "config.h"
+
+#ifdef HAVE_SYS_CDEFS_H
 #include <sys/cdefs.h>
+#endif
 
 /*
  * This file defines four types of data structures: singly-linked lists,