]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
mtr v0.75 v0.75
authorRoger Wolff <r.e.wolff@bitwizard.nl>
Fri, 19 Sep 2008 00:00:00 +0000 (00:00 +0000)
committerTravis Cross <tc@traviscross.com>
Sun, 3 Feb 2013 20:45:38 +0000 (20:45 +0000)
 - Feelgood patch to move sprintf to snprintf. People might think that
   sprintf might cause a buffer overflow. Now it's clean.  cut-paste
   patches: you can now copy an intermediate host to the clipboard.

source: ftp://ftp.bitwizard.nl/mtr/mtr-0.75.tar.gz

12 files changed:
Makefile.am
Makefile.dist
NEWS
TODO
configure.in
dns.c
gtk.c
mtr.8
mtr.c
mtr.h
net.c
report.c

index d02920fdafa6e0928c9aec43962b2ab1069d6dc1..3e60cdb21359798c456f1701ef36e044072dd8d2 100644 (file)
@@ -23,7 +23,7 @@ mtr_LDFLAGS = $(GTK_OBJ) $(CURSES_OBJ)
 
 EXTRA_DIST = SECURITY mtr.8 Makefile Makefile.dist
 distclean-local:
-       cp Makefile.dist Makefile
+       (sleep 3; cp Makefile.dist Makefile) &
        rm -f *.orig
 
 DISTCLEANFILES = *~
index 99680ad1061dcf93df112eb5fe07145240c11288..a0ea2d1c57b08f9b36778222f6858469e3713a9d 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 firstrule: 
-       ./configure
+       ./configure 
        $(MAKE)
 
 clean: 
diff --git a/NEWS b/NEWS
index 58de1fb20b6a3e9f897de516af0e817e66414626..f4e92dd155c6aacb034d3ee40968e06534e52662 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,8 @@
 WHAT'S NEW?
+  v0.75 Feelgood patch to move sprintf to snprintf. People might think
+        that sprintf might cause a buffer overflow. Now it's clean. 
+        cut-paste patches: you can now copy an intermediate host to the
+        clipboard. 
   v0.74 Martin Pels' patch to allow UDP probes. 
         KES reported a build problem. Turns out I need to install gtk-1.2
         on my development sytem, otherwise my release script causes the 
diff --git a/TODO b/TODO
index ffc0ca349058d0548dca85845ce40d9ede5168c0..0673b24eba98979039c71a00c8ab8d053bc51e83 100644 (file)
--- a/TODO
+++ b/TODO
@@ -41,6 +41,14 @@ Oh, Feel free to provide suggestions for this list.
   - Keep all packets and make the "best" and "worst" columns show the
     xx-th percentile....
 
+  - Can the reports generated also include any secondary servers?  In 
+    the interactive mode, any new servers that are found in the 
+    traceroute are added to the list, but it seems to only include 
+    one set of servers when using the -r option.  
+
+  - Being able to expand the "column width" of the hosts listed would 
+    be nice, too.
+
 
 - Bugs to fix?
 
index b9b23f8b25b62d201047db18a3082a09383d2340..d73e9940f0cc4fec98d15535a84d5d9c33c15a4a 100644 (file)
@@ -1,5 +1,5 @@
 AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.74)
+AM_INIT_AUTOMAKE(mtr, 0.75)
 
 
 AC_SUBST(GTK_OBJ)
@@ -15,6 +15,9 @@ AC_CHECK_SIZEOF(unsigned short, 2)
 AC_CHECK_SIZEOF(unsigned int, 4)
 AC_CHECK_SIZEOF(unsigned long, 4)
 
+AC_CHECK_HEADERS(ncurses.h ncurses/curses.h curses.h cursesX.h sys/types.h fcntl.h)
+AC_CHECK_HEADERS(sys/xti.h)
+
 # Some doc I found somewhere. :-) -- REW
 # - Macro: AC_CHECK_FUNC (FUNCTION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
 # - Macro: AC_CHECK_LIB (LIBRARY, FUNCTION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
@@ -32,11 +35,7 @@ AC_CHECK_FUNC(initscr, ,
        AC_DEFINE(NO_CURSES, 1, Define if you don't have the curses libraries available.)
        CURSES_OBJ=))))
 
-AC_CHECK_FUNCS(attron)
-
-
-AC_CHECK_HEADERS(ncurses.h ncurses/curses.h curses.h cursesX.h sys/types.h)
-AC_CHECK_HEADERS(sys/xti.h)
+AC_CHECK_FUNCS(attron fcntl)
 
 AC_CHECK_LIB(m, floor, , AC_MSG_ERROR(No math library found))
 
diff --git a/dns.c b/dns.c
index 70ad17ff99f2d140658ed2be3153b82ca87a424a..d33df819ccf7d2d840a897c8919be5ed51023643 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -893,7 +893,7 @@ void resendrequest(struct resolve *rp,int type)
   if (type == T_A) {
     dorequest(rp->hostname,type,rp->id);
     if (debug) {
-      sprintf(tempstring,"Resolver: Sent reverse authentication request for \"%s\".",
+      snprintf(tempstring, sizeof(tempstring), "Resolver: Sent reverse authentication request for \"%s\".",
              rp->hostname);
       restell(tempstring);
     }
@@ -914,7 +914,7 @@ void resendrequest(struct resolve *rp,int type)
     }
     dorequest(tempstring,type,rp->id);
     if (debug) {
-      sprintf(tempstring,"Resolver: Sent domain lookup request for \"%s\".",
+      snprintf(tempstring, sizeof(tempstring), "Resolver: Sent domain lookup request for \"%s\".",
              strlongip( &(rp->ip) ));
       restell(tempstring);
     }
@@ -950,7 +950,7 @@ void passrp(struct resolve *rp,long ttl)
   rp->expiretime = sweeptime + (double)ttl;
   untieresolve(rp);
   if (debug) {
-    sprintf(tempstring,"Resolver: Lookup successful: %s\n",rp->hostname);
+    snprintf(tempstring, sizeof(tempstring), "Resolver: Lookup successful: %s\n",rp->hostname);
     restell(tempstring);
   }
 }
@@ -1007,7 +1007,7 @@ void parserespacket(byte *s, int l)
   case NOERROR:
     if (hp->ancount) {
       if (debug) {
-       sprintf(tempstring,"Resolver: Received nameserver reply. (qd:%u an:%u ns:%u ar:%u)",
+       snprintf(tempstring, sizeof(tempstring), "Resolver: Received nameserver reply. (qd:%u an:%u ns:%u ar:%u)",
                 hp->qdcount,hp->ancount,hp->nscount,hp->arcount);
        restell(tempstring);
       }
@@ -1047,14 +1047,14 @@ void parserespacket(byte *s, int l)
       namestring[strlen(stackstring)] = '\0';
       if (strcasecmp(stackstring,namestring)) {
        if (debug) {
-         sprintf(tempstring,"Resolver: Unknown query packet dropped. (\"%s\" does not match \"%s\")",
+         snprintf(tempstring, sizeof(tempstring), "Resolver: Unknown query packet dropped. (\"%s\" does not match \"%s\")",
                  stackstring,namestring);
          restell(tempstring);
        }
        return;
       }
       if (debug) {
-       sprintf(tempstring,"Resolver: Queried domain name: \"%s\"",namestring);
+       snprintf(tempstring, sizeof(tempstring), "Resolver: Queried domain name: \"%s\"",namestring);
        restell(tempstring);
       }
       c+= r;
@@ -1065,7 +1065,7 @@ void parserespacket(byte *s, int l)
       qdatatype = sucknetword(c);
       qclass = sucknetword(c);
       if (qclass != C_IN) {
-       sprintf(tempstring,"Resolver error: Received unsupported query class: %u (%s)",
+       snprintf(tempstring, sizeof(tempstring), "Resolver error: Received unsupported query class: %u (%s)",
                 qclass,qclass < ClasstypeCount ? classtypes[qclass] :
                classtypes[ClasstypeCount]);
        restell(tempstring);
@@ -1079,7 +1079,7 @@ void parserespacket(byte *s, int l)
          }
        break;
       default:
-       sprintf(tempstring,"Resolver error: Received unimplemented query type: %u (%s)",
+       snprintf(tempstring, sizeof(tempstring), "Resolver error: Received unimplemented query type: %u (%s)",
                qdatatype,qdatatype < ResourcetypeCount ?
                resourcetypes[qdatatype] : resourcetypes[ResourcetypeCount]);
        restell(tempstring);
@@ -1101,7 +1101,7 @@ void parserespacket(byte *s, int l)
        else
          usefulanswer = 1;
        if (debug) {
-         sprintf(tempstring,"Resolver: answered domain query: \"%s\"",namestring);
+         snprintf(tempstring, sizeof(tempstring), "Resolver: answered domain query: \"%s\"",namestring);
          restell(tempstring);
        }
        c+= r;
@@ -1114,10 +1114,10 @@ void parserespacket(byte *s, int l)
        ttl = sucknetlong(c);
        rdatalength = sucknetword(c);
        if (class != qclass) {
-         sprintf(tempstring,"query class: %u (%s)",qclass,qclass < ClasstypeCount ?
+         snprintf(tempstring, sizeof(tempstring), "query class: %u (%s)",qclass,qclass < ClasstypeCount ?
                  classtypes[qclass] : classtypes[ClasstypeCount]);
          restell(tempstring);
-         sprintf(tempstring,"rr class: %u (%s)",class,class < ClasstypeCount ?
+         snprintf(tempstring, sizeof(tempstring), "rr class: %u (%s)",class,class < ClasstypeCount ?
                  classtypes[class] : classtypes[ClasstypeCount]);
          restell(tempstring);
          restell("Resolver error: Answered class does not match queried class.");
@@ -1133,20 +1133,20 @@ void parserespacket(byte *s, int l)
        }
        if (datatype == qdatatype || datatype == T_CNAME) {
          if (debug) {
-           sprintf(tempstring,"Resolver: TTL: %s",strtdiff(sendstring,ttl));
+           snprintf(tempstring, sizeof(tempstring), "Resolver: TTL: %s",strtdiff(sendstring,ttl));
            restell(tempstring);
          }
          if (usefulanswer)
            switch (datatype) {
            case T_A:
              if (rdatalength != 4) {
-               sprintf(tempstring,"Resolver error: Unsupported rdata format for \"A\" type. (%u bytes)",
+               snprintf(tempstring, sizeof(tempstring), "Resolver error: Unsupported rdata format for \"A\" type. (%u bytes)",
                        rdatalength);
                restell(tempstring);
                return;
              }
              if ( addrcmp( (void *) &(rp->ip), (void *) c, af ) == 0 ) {
-               sprintf(tempstring,"Resolver: Reverse authentication failed: %s != ",
+               snprintf(tempstring, sizeof(tempstring), "Resolver: Reverse authentication failed: %s != ",
                        strlongip( &(rp->ip) ));
                addrcpy( (void *) &alignedip, (void *) c, af );
                strcat(tempstring,strlongip( &alignedip ));
@@ -1154,7 +1154,7 @@ void parserespacket(byte *s, int l)
                res_hostipmismatch++;
                failrp(rp);
              } else {
-               sprintf(tempstring,"Resolver: Reverse authentication complete: %s == \"%s\".",
+               snprintf(tempstring, sizeof(tempstring), "Resolver: Reverse authentication complete: %s == \"%s\".",
                        strlongip( &(rp->ip) ),nonull(rp->hostname));
                restell(tempstring);
                res_reversesuccess++;
@@ -1171,7 +1171,7 @@ void parserespacket(byte *s, int l)
                return;
              }
              if (debug) {
-               sprintf(tempstring,"Resolver: Answered domain: \"%s\"",namestring);
+               snprintf(tempstring, sizeof(tempstring), "Resolver: Answered domain: \"%s\"",namestring);
                restell(tempstring);
              }
              if (r > HostnameLength) {
@@ -1196,14 +1196,14 @@ void parserespacket(byte *s, int l)
              }
              break;
            default:
-             sprintf(tempstring,"Resolver error: Received unimplemented data type: %u (%s)",
+             snprintf(tempstring, sizeof(tempstring), "Resolver error: Received unimplemented data type: %u (%s)",
                      datatype,datatype < ResourcetypeCount ?
                      resourcetypes[datatype] : resourcetypes[ResourcetypeCount]);
              restell(tempstring);
            }
        } else {
          if (debug) {
-           sprintf(tempstring,"Resolver: Ignoring resource type %u. (%s)",
+           snprintf(tempstring, sizeof(tempstring), "Resolver: Ignoring resource type %u. (%s)",
                    datatype,datatype < ResourcetypeCount ?
                    resourcetypes[datatype] : resourcetypes[ResourcetypeCount]);
            restell(tempstring);
@@ -1221,7 +1221,7 @@ void parserespacket(byte *s, int l)
     failrp(rp);
     break;
   default:
-    sprintf(tempstring,"Resolver: Received error response %u. (%s)",
+    snprintf(tempstring, sizeof(tempstring), "Resolver: Received error response %u. (%s)",
            getheader_rcode(hp),getheader_rcode(hp) < ResponsecodeCount ?
            responsecodes[getheader_rcode(hp)] : responsecodes[ResponsecodeCount]);
     restell(tempstring);
@@ -1252,13 +1252,13 @@ void dns_ack(void)
                      (void *) &(from4->sin_addr), AF_INET ) == 0 )
          break;
     if (i == _res.nscount) {
-      sprintf(tempstring,"Resolver error: Received reply from unknown source: %s",
+      snprintf(tempstring, sizeof(tempstring), "Resolver error: Received reply from unknown source: %s",
              inet_ntoa(from4->sin_addr ));
       restell(tempstring);
     } else
       parserespacket((byte *)resrecvbuf,r);
   } else {
-    sprintf(tempstring,"Resolver: Socket error: %s",strerror(errno));
+    snprintf(tempstring, sizeof(tempstring), "Resolver: Socket error: %s",strerror(errno));
     restell(tempstring);
   }
 }
@@ -1287,7 +1287,7 @@ void dns_events(double *sinterval)
     case STATE_FINISHED:       /* TTL has expired */
     case STATE_FAILED: /* Fake TTL has expired */
       if (debug) {
-       sprintf(tempstring,"Resolver: Cache record for \"%s\" (%s) has expired. (state: %u)  Marked for expire at: %g, time: %g.",
+       snprintf(tempstring, sizeof(tempstring), "Resolver: Cache record for \"%s\" (%s) has expired. (state: %u)  Marked for expire at: %g, time: %g.",
                 nonull(rp->hostname), strlongip( &(rp->ip) ), 
                rp->state, rp->expiretime, sweeptime);
        restell(tempstring);
@@ -1331,14 +1331,14 @@ char *dns_lookup2(ip_t * ip)
     if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED)) {
       if ((rp->state == STATE_FINISHED) && (rp->hostname)) {
        if (debug) {
-         sprintf(tempstring,"Resolver: Used cached record: %s == \"%s\".\n",
+         snprintf(tempstring, sizeof(tempstring), "Resolver: Used cached record: %s == \"%s\".\n",
                  strlongip(ip),rp->hostname);
          restell(tempstring);
        }
        return rp->hostname;
       } else {
        if (debug) {
-         sprintf(tempstring,"Resolver: Used failed record: %s == ???\n",
+         snprintf(tempstring, sizeof(tempstring), "Resolver: Used failed record: %s == ???\n",
                  strlongip(ip));
          restell(tempstring);
        }
diff --git a/gtk.c b/gtk.c
index 6a4f8a9f42414418fb0915c15f56d205343b485a..f79aefd065f8c379fcf63d8d770279d86f0ebb32 100644 (file)
--- a/gtk.c
+++ b/gtk.c
 #endif
 
 gint gtk_ping(gpointer data);
+gint Copy_activate(GtkWidget *widget, gpointer data);
+gint NewDestination_activate(GtkWidget *widget, gpointer data);
+gboolean ReportTreeView_clicked(GtkWidget *Tree, GdkEventButton *event);
+gchar* getSelectedHost(GtkTreePath *path);
+
 
 
 extern char *Hostname;
@@ -49,7 +54,7 @@ extern float WaitTime;
 extern int af;
 static int tag;
 static GtkWidget *Pause_Button;
-
+static GtkWidget *Entry;
 
 void gtk_add_ping_timeout (void)
 {
@@ -170,7 +175,6 @@ void Toolbar_fill(GtkWidget *Toolbar)
 {
   GtkWidget *Button;
   GtkWidget *Label;
-  GtkWidget *Entry;
   GtkAdjustment *Adjustment;
 
   Button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
@@ -278,6 +282,9 @@ void TreeViewCreate(void)
     
   ReportTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ReportStore));
   
+  g_signal_connect(GTK_OBJECT(ReportTreeView), "button_press_event", 
+                   G_CALLBACK(ReportTreeView_clicked),NULL);
+  
   renderer = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes ("Hostname",
     renderer,
@@ -536,4 +543,91 @@ void gtk_loop(void)
   gtk_main();
 }
 
+gboolean NewDestination_activate(GtkWidget *widget, gpointer data)
+{
+  gchar *hostname;
+  GtkTreePath *path = (GtkTreePath*)data;
+       
+  hostname = getSelectedHost(path);
+  if (hostname) {
+    gtk_entry_set_text (GTK_ENTRY(Entry), hostname);
+    Host_activate(Entry, NULL);
+    g_free(hostname);
+  }
+  return TRUE;
+}
+
+
+gboolean Copy_activate(GtkWidget *widget, gpointer data)
+{
+  gchar *hostname;
+  GtkTreePath *path = (GtkTreePath*)data;
+       
+  hostname = getSelectedHost(path);
+  if (hostname != NULL) {
+    GtkClipboard *clipboard;
+
+    clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+    gtk_clipboard_set_text(clipboard, hostname, -1);
+
+    clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
+    gtk_clipboard_set_text(clipboard, hostname, -1);
+
+    g_free(hostname);
+  }
+
+  return TRUE;
+}
+
+gchar *getSelectedHost(GtkTreePath *path)
+{
+  GtkTreeIter iter;
+  gchar *name = NULL;
+
+  if (gtk_tree_model_get_iter(GTK_TREE_MODEL(ReportStore), &iter, path)) {
+    gtk_tree_model_get (GTK_TREE_MODEL(ReportStore), &iter, COL_HOSTNAME, &name, -1);
+  }
+  gtk_tree_path_free(path);
+  return name;
+}
+
+
+gboolean ReportTreeView_clicked(GtkWidget *Tree, GdkEventButton *event)
+{
+  GtkWidget* popup_menu; 
+  GtkWidget* copy_item; 
+  GtkWidget* newdestination_item;
+  GtkTreePath *path;
+
+  if (event->type != GDK_BUTTON_PRESS  || event->button != 3)
+    return FALSE;
+
+  if(!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(ReportTreeView),
+      event->x, event->y, &path, NULL, NULL, NULL))
+    return FALSE;
+  
+  gtk_tree_view_set_cursor(GTK_TREE_VIEW(ReportTreeView), path, NULL, FALSE);
+
+  // Single right click: prepare and show the popup menu
+  popup_menu = gtk_menu_new ();
+
+  copy_item = gtk_menu_item_new_with_label ("Copy to clipboard");
+  newdestination_item = gtk_menu_item_new_with_label ("Set as new destination"); 
+
+  gtk_menu_append (GTK_MENU (popup_menu), copy_item); 
+  gtk_menu_append (GTK_MENU (popup_menu), newdestination_item); 
+
+  g_signal_connect(GTK_OBJECT(copy_item),"activate",
+                   GTK_SIGNAL_FUNC(Copy_activate), path);
+
+  g_signal_connect(GTK_OBJECT(newdestination_item),"activate",
+                   GTK_SIGNAL_FUNC(NewDestination_activate), path);
+              
+  gtk_widget_show (copy_item); 
+  gtk_widget_show (newdestination_item); 
+
+  gtk_menu_popup (GTK_MENU(popup_menu), NULL, NULL, NULL, NULL,
+                   0, event->time);
+  return TRUE;
+}
 
diff --git a/mtr.8 b/mtr.8
index 30485b28609bcdc036c29eeffffc79db165ab9f2..7321bd9bc6788e4e63086f00d7fd71743fa65c63 100644 (file)
--- a/mtr.8
+++ b/mtr.8
@@ -20,6 +20,9 @@ mtr \- a network diagnostic tool
 .B \-\-report\c
 ]
 [\c
+.B \-\-report-wide\c
+]
+[\c
 .B \-\-report\-cycles\ COUNT\c
 ]
 [\c
@@ -115,6 +118,19 @@ generates a significant amount of network traffic.  Using
 to measure the quality of your network may result in decreased
 network performance.  
 
+.TP
+.B \-w
+.TP
+.B \-\-report-wide
+.br
+This option puts 
+.B mtr
+into 
+.B wide report
+mode.  When in this mode,
+.B mtr
+will not cut hostnames in the report. 
+
 .TP
 .B \-c\ COUNT
 .TP
diff --git a/mtr.c b/mtr.c
index 8849a1cb1ec9ea6db381cbfed3329d93deebcf1c..5ce68baca95f1c7df574c80076469f48c9ddd7e9 100644 (file)
--- a/mtr.c
+++ b/mtr.c
@@ -64,6 +64,7 @@ int   dns = 1;
 int   cpacketsize = 64;          /* default packet size */
 int   bitpattern = 0;
 int   tos = 0;
+int   reportwide = 0;
 int af = DEFAULT_AF;
 int mtrtype = IPPROTO_ICMP;     /* Use ICMP as default packet type */
 
@@ -125,6 +126,7 @@ void parse_arg (int argc, char **argv)
     { "help", 0, 0, 'h' },
 
     { "report", 0, 0, 'r' },
+    { "report-wide", 0, 0, 'w' },
     { "xml", 0, 0, 'x' },
     { "curses", 0, 0, 't' },
     { "gtk", 0, 0, 'g' },
@@ -154,7 +156,7 @@ void parse_arg (int argc, char **argv)
   while(1) {
     /* added f:m:o: byMin */
     opt = getopt_long(argc, argv,
-                     "vhrxtglpo:i:c:s:b:Q:na:f:m:u46", long_options, NULL);
+                     "vhrwxtglpo:i:c:s:b:Q:na:f:m:u46", long_options, NULL);
     if(opt == -1)
       break;
 
@@ -169,6 +171,9 @@ void parse_arg (int argc, char **argv)
     case 'r':
       DisplayMode = DisplayReport;
       break;
+    case 'w':
+      reportwide = 1;
+      break;
     case 't':
       DisplayMode = DisplayCurses;
       break;
@@ -371,8 +376,8 @@ int main(int argc, char **argv)
   }
 
   if (PrintHelp) {
-    printf("usage: %s [-hvrctglspniu46] [--help] [--version] [--report]\n"
-          "\t\t[--report-cycles=COUNT] [--curses] [--gtk]\n"
+    printf("usage: %s [-hvrwctglspniu46] [--help] [--version] [--report]\n"
+          "\t\t[--report-wide] [--report-cycles=COUNT] [--curses] [--gtk]\n"
            "\t\t[--raw] [--split] [--no-dns] [--address interface]\n" /* BL */
            "\t\t[--psize=bytes/-s bytes]\n"            /* ok */
           "\t\t[--interval=SECONDS] HOSTNAME [PACKETSIZE]\n", argv[0]);
@@ -395,7 +400,7 @@ int main(int argc, char **argv)
   bzero( &hints, sizeof hints );
   hints.ai_family = af;
   hints.ai_socktype = SOCK_DGRAM;
-  error = getaddrinfo( Hostname, "0", &hints, &res );
+  error = getaddrinfo( Hostname, NULL, &hints, &res );
   if ( error ) {
     perror( gai_strerror(error) );
     exit( EXIT_FAILURE );
diff --git a/mtr.h b/mtr.h
index e2efd323031d31b340f519d4f6346802cb8fe340..3239b0bf72b9cc1bc0192c5be17919e395c8f3c6 100644 (file)
--- a/mtr.h
+++ b/mtr.h
 
 /* Typedefs */
 
-#if 0
-
-// Neat trick! However, on my system, "config.h" already defines these types
-// so I get a compiler error if I leave this in.  -- REW
-
 /*  Find the proper type for 8 bits  */
 #if SIZEOF_UNSIGNED_CHAR == 1
 typedef unsigned char uint8;
@@ -54,8 +49,6 @@ typedef unsigned long uint32;
 #error No 32 bit type
 #endif
 
-#endif
-
 typedef unsigned char byte;
 typedef unsigned short word;
 typedef unsigned long dword;
diff --git a/net.c b/net.c
index ebd3edaba2d441d1be6c7dc72668bff7ce81ad0a..ea583d9ee29b3d597bec06bc1bfd606a564e6520 100644 (file)
--- a/net.c
+++ b/net.c
@@ -32,6 +32,9 @@
 #include <netinet/in.h>
 #include <memory.h>
 #include <unistd.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
@@ -895,6 +898,20 @@ int net_send_batch(void)
   return 0;
 }
 
+static void set_fd_flags(int fd)
+{
+#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
+  int oldflags;
+
+  oldflags = fcntl(fd, F_GETFD);
+  if (oldflags == -1) {
+    perror("Couldn't get fd's flags");
+    return;
+  }
+  if (fcntl(fd, F_SETFD, oldflags | FD_CLOEXEC))
+    perror("Couldn't set fd's flags");
+#endif
+}
 
 int net_preopen(void) 
 {
@@ -925,9 +942,11 @@ int net_preopen(void)
   recvsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
   if (recvsock4 < 0)
     return -1;
+  set_fd_flags(recvsock4);
 #ifdef ENABLE_IPV6
   recvsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
 #endif
+  set_fd_flags(recvsock6);
 
   return 0;
 }
@@ -956,7 +975,7 @@ int net_selectsocket(void)
     sendsock6 = sendsock6_udp;
     break;
   }
-  if (sendsock6 < 0)
+  if ((sendsock6 < 0) && (sendsock4 < 0))
     return -1;
 #endif
 
index 8b9fe60da9452be807b009a0b6307df9fd16b4e1..510ef4776902bea7913270e6acae7602ba8345db 100644 (file)
--- a/report.c
+++ b/report.c
@@ -41,6 +41,7 @@ extern int bitpattern;
 extern int tos;
 extern int MaxPing;
 extern int af;
+extern int reportwide;
 
 
 void report_open(void) 
@@ -56,15 +57,41 @@ void report_close(void)
   char buf[1024];
   char fmt[16];
   int len=0;
+  int len_hosts = 33;
   struct hostent *host;
 
-  sprintf(buf, "HOST: %-33s", LocalHostname);
+  if (reportwide)
+  {
+    // get the longest hostname
+    len_hosts = strlen(LocalHostname);
+    max = net_max();
+    at  = net_min();
+    for (; at < max; at++) {
+      addr = net_addr(at);
+      if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
+        host = dns ? addr2host( (void *) addr, af ) : NULL;
+        if (host != NULL) {
+          strncpy( name, host->h_name, (sizeof name) - 1 );
+          name[ (sizeof name) - 1 ] = '\0'; 
+        } else {
+          snprintf(name, sizeof(name), "%s", strlongip( addr ) );
+        }
+        if (len_hosts < strlen(name)) {
+          len_hosts = strlen(name);
+        }
+      }    
+    }
+  }
+  
+  snprintf( fmt, sizeof(fmt), "HOST: %%-%ds", len_hosts);
+  snprintf(buf, sizeof(buf), fmt, LocalHostname);
+  len = reportwide ? strlen(buf) : len_hosts;
   for( i=0; i<MAXFLD; i++ ) {
     j = fld_index[fld_active[i]];
     if (j < 0) continue;
 
-    sprintf( fmt, "%%%ds", data_fields[j].length );
-    sprintf( buf +33+ len, fmt, data_fields[j].title );
+    snprintf( fmt, sizeof(fmt), "%%%ds", data_fields[j].length );
+    snprintf( buf + len, sizeof(buf), fmt, data_fields[j].title );
     len +=  data_fields[j].length;
   }
   printf("%s\n",buf);
@@ -80,25 +107,26 @@ void report_close(void)
       host = dns ? addr2host( (void *) addr, af ) : NULL;
 
       if (host != NULL) {
-        strncpy( name, host->h_name, (sizeof name) - 1 );
-        name[ (sizeof name) - 1 ] = '\0'; 
+        strncpy( name, host->h_name, (sizeof name) - 1 );
+        name[ (sizeof name) - 1 ] = '\0'; 
       } else {
-       sprintf(name, "%s", strlongip( addr ) );
+        snprintf(name, sizeof(name), "%s", strlongip( addr ) );
       }
     }
 
-    len=0;
-    sprintf( buf, " %2d. %-33s", at+1, name);
+    snprintf( fmt, sizeof(fmt), " %%2d. %%-%ds", len_hosts);
+    snprintf(buf, sizeof(buf), fmt, at+1, name);
+    len = reportwide ? strlen(buf) : len_hosts;  
     for( i=0; i<MAXFLD; i++ ) {
       j = fld_index[fld_active [i]];
       if (j < 0) continue;
 
       /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
       if( index( data_fields[j].format, 'f' ) ) {
-       sprintf( buf +33+ len, data_fields[j].format,
+        snprintf( buf + len, sizeof(buf), data_fields[j].format,
                data_fields[j].net_xxx(at) /1000.0 );
       } else {
-       sprintf( buf +33+ len, data_fields[j].format,
+        snprintf( buf + len, sizeof(buf), data_fields[j].format,
                data_fields[j].net_xxx(at) );
       }
       len +=  data_fields[j].length;