]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
mtr v0.34 v0.34
authorRoger Wolff <r.e.wolff@bitwizard.nl>
Sat, 3 Apr 1999 00:00:00 +0000 (00:00 +0000)
committerTravis Cross <tc@traviscross.com>
Sun, 3 Feb 2013 20:45:37 +0000 (20:45 +0000)
 - Added Matt's nifty "use the icmp unreachables to do the timing"
   patch.
 - Added Steve Kann's pause/resume patch.

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

12 files changed:
AUTHORS
Makefile.am
NEWS
TODO
configure.in
curses.c
display.c
display.h
gtk.c
net.c
net.h
select.c

diff --git a/AUTHORS b/AUTHORS
index 531be363ed5356b2b2df356e7c24d0f3636f8fd0..f771b619d613261b9d239df4534040a663bb0941 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -24,6 +24,7 @@
        Adam Kramer (l3zqc@qcunix1.acc.qc.edu), 
         Simon Kirby, 
         Christophe Kalt,
+       Steve Kann (stevek@spheara.horizonlive.com), 
         Mircea Damian, 
         Brian Casey, 
 
index b6b3032cb132dc548b509708082ab5e7ed4c065d..59cd0318700a788bb13e0c9c83ac1190d157a1b6 100644 (file)
@@ -24,6 +24,7 @@ mtr_LDFLAGS = $(GTK_OBJ) $(CURSES_OBJ)
 EXTRA_DIST = SECURITY mtr.8 Makefile Makefile.dist
 distclean-local:
        cp Makefile.dist Makefile
+       rm -f *.orig
 
 DISTCLEANFILES = *~
 
diff --git a/NEWS b/NEWS
index c8150be6311b910d9aa3155efd8610b7d8f6b15a..a357c7ab3fb74f665aabb76d121464a9afdd3c0e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
 WHAT'S NEW?
 
+  v0.34 Added Matt's nifty "use the icmp unreachables to do the timing" patch.
+        Added Steve Kann's pause/resume patch. 
+
   v0.33 Fixed the Linux glibc resolver problems.
         Fixed the off-by-one problem with -c option. 
 
diff --git a/TODO b/TODO
index e95455ee38297b2b4951edd6dfbaa55097c8359d..e7374f6b486d30ca7f2d52b3a430a90962cce19d 100644 (file)
--- a/TODO
+++ b/TODO
        (Anybody have the statistics experience to tell me how
        to do the data analysis?)
 
-  - Allow MTR to keep on getting the icmp host unreachables, and
-    work through that. Some hosts don't answer PINGs.
-      - Auto-switch to that strategy if "host is known, but 10/10 
-        pings got lost"
-
   - The "don't probe all hosts at once" strategy can be improved a bit.
     It should not probe more than 10 unknown hosts, but the counter need
     not be reset at the start of the "round". This way if you probe
index 8b369a2458bb49e3fbca37d185dee4bab1d103b8..fe8e20833dc8536bca9376e87b49e9920a7f43b6 100644 (file)
@@ -1,5 +1,5 @@
 AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.33)
+AM_INIT_AUTOMAKE(mtr, 0.34)
 
 AC_SUBST(GTK_OBJ)
 AC_SUBST(CURSES_OBJ)
@@ -14,12 +14,17 @@ AC_CHECK_SIZEOF(unsigned short, 2)
 AC_CHECK_SIZEOF(unsigned int, 4)
 AC_CHECK_SIZEOF(unsigned long, 4)
 
+# 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]]])
+
 AC_CHECK_FUNC(initscr, , 
   AC_CHECK_LIB(ncurses, initscr, , 
     AC_CHECK_LIB(curses, initscr, , 
        AC_MSG_WARN(Building without curses display support)
        AC_DEFINE(NO_CURSES)
        CURSES_OBJ=)))
+
 AC_CHECK_HEADERS(ncurses.h ncurses/curses.h curses.h)
 AC_CHECK_HEADERS(sys/xti.h)
 
index 930c66a68d696bf80d4a64b77932beeb17dd0230..beb26201380b3077769669cd61a11ab90e536d35 100644 (file)
--- a/curses.c
+++ b/curses.c
@@ -63,6 +63,10 @@ int mtr_curses_keyaction() {
      return ActionQuit;
   if (c==12)
      return ActionClear;
+  if (c==19)
+     return ActionPause;
+  if (c==17)
+     return ActionResume;
   if(tolower(c) == 'r')
     return ActionReset;
   if (tolower(c) == 'd')
index 9f18b4e918a0b571bc10849f5b7d66edd76c215b..eea326999172b6162f79720cfd0f1300d60eae89 100644 (file)
--- a/display.c
+++ b/display.c
@@ -31,6 +31,7 @@ extern int DisplayMode;
 #define mtr_curses_close()
 #define mtr_curses_redraw()
 #define mtr_curses_keyaction()
+#define mtr_curses_clear()
 #endif
 
 #ifdef NO_GTK
@@ -41,6 +42,13 @@ extern int DisplayMode;
 #define gtk_loop()
 #endif
 
+#ifdef NO_SPLIT
+#define split_open()
+#define split_close()
+#define split_redraw()
+#define split_keyaction() 0
+#endif
+
 void display_detect(int *argc, char ***argv) {
   DisplayMode = DisplayReport;
 
index 3bd27f22ea54d0b6b08fd4e6488202574a59a3d1..6b091d76222f6ff1d2f5f1f718f5142f38e83b7b 100644 (file)
--- a/display.h
+++ b/display.h
@@ -17,7 +17,8 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-enum { ActionNone, ActionQuit, ActionReset, ActionDisplay, ActionClear };
+enum { ActionNone, ActionQuit, ActionReset, ActionDisplay, ActionClear,
+       ActionPause, ActionResume };
 enum { DisplayReport, DisplayCurses, DisplayGTK, DisplaySplit, DisplayRaw };
 
 /*  Prototypes for display.c  */
diff --git a/gtk.c b/gtk.c
index 3835395e0f4162cb1cdb92224eb613d091d89dd4..f7cce58267c0943d4cf9da09186cff147a982d61 100644 (file)
--- a/gtk.c
+++ b/gtk.c
@@ -258,6 +258,7 @@ void Window_fill(GtkWidget *Window) {
   GtkWidget *List;
 
   gtk_window_set_title(GTK_WINDOW(Window), "My traceroute  [v" VERSION "]");
+  gtk_window_set_wmclass(GTK_WINDOW(Window), "mtr", "Mtr");
   gtk_widget_set_usize(Window, 540, 400); 
   gtk_container_border_width(GTK_CONTAINER(Window), 10);
   VBox = gtk_vbox_new(FALSE, 10);
diff --git a/net.c b/net.c
index 52358dc656fe82291b4ea0d0c7e5098d530085d7..75c0c0d2cf950e964d6fb166249d6aa377b9bc31 100644 (file)
--- a/net.c
+++ b/net.c
@@ -78,16 +78,8 @@ struct IPHeader {
 #define SOL_IP 0
 #endif
   
-struct packetdata {
-    int index;
-    int ttl;
-    int sec;
-    int msec;
-    int seq;
-};
-
 struct nethost {
-  int addr;
+  uint32 addr;
   int xmit;
   int returned;
   int total;
@@ -97,7 +89,15 @@ struct nethost {
   int saved[SAVED_PINGS];
 };
 
+struct sequence {
+    int index;
+    int transit;
+    int saved_seq;
+    struct timeval time;
+};
+
 static struct nethost host[MaxHost];
+static struct sequence sequence[MaxSequence];
 static struct timeval reset = { 0, 0 };
 
 int sendsock;
@@ -123,65 +123,31 @@ int checksum(void *data, int sz) {
 
 static int BSDfix = 0;
 
-void net_send_ping(int index) {
-  char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader) 
-            + sizeof(struct packetdata)];
-  struct IPHeader *ip;
-  struct ICMPHeader *icmp;
-  struct packetdata *data;
-  int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + sizeof(struct packetdata);
-  struct sockaddr_in addr;
-  struct timeval now;
+int new_sequence(int index) {
+  static int next_sequence = 0;
+  int seq;
 
-  memset(&addr, 0, sizeof(struct sockaddr_in));
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = host[index].addr;
-  host[index].xmit++;
+  seq = next_sequence++;
+  if(next_sequence >= MaxSequence)
+    next_sequence = 0;
+
+  sequence[seq].index = index;
+  sequence[seq].transit = 1;
+  sequence[seq].saved_seq = ++host[index].xmit;
+  memset(&sequence[seq].time, 0, sizeof(sequence[seq].time));
+  
   host[index].transit = 1;
   net_save_xmit(index);
-
-  memset(packet, 0, packetsize);
-
-  ip = (struct IPHeader *)packet;
-  icmp = (struct ICMPHeader *)(packet + sizeof(struct IPHeader));
-  data = (struct packetdata *)(packet + sizeof(struct IPHeader) + sizeof(struct ICMPHeader));
-
-  ip->version = 0x45;
-  ip->tos = 0;
-  ip->len = BSDfix? packetsize: htons (packetsize);
-  ip->id = 0;
-  ip->frag = 0;
-  ip->ttl = 127;
-  ip->protocol = IPPROTO_ICMP;
-  ip->saddr = 0;
-  ip->daddr = host[index].addr;
   
-  icmp->type = timestamp?ICMP_TSTAMP:ICMP_ECHO;
-  icmp->id = getpid();
-  icmp->sequence = 0;
-
-  data->ttl = 0;
-  data->index = index;
-  data->seq = host[index].xmit;
-
-  gettimeofday(&now, NULL);
-  data->sec = now.tv_sec;
-  data->msec = now.tv_usec / 1000;
-
-  icmp->checksum = checksum(icmp, packetsize - sizeof(struct IPHeader));
-  ip->check = checksum(ip, packetsize);
-
-  sendto(sendsock, packet, packetsize, 0, 
-        (struct sockaddr *)&addr, sizeof(addr));
+  return seq;
 }
 
 /*  Attempt to find the host at a particular number of hops away  */
-void net_send_query(int hops) {
-  char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + sizeof(struct packetdata)];
+void net_send_query(int index) {
+  char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader)];
   struct IPHeader *ip;
   struct ICMPHeader *icmp;
-  struct packetdata *data;
-  int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + sizeof(struct packetdata);
+  int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader);
   int rv;
   static int first=1;
 
@@ -189,33 +155,28 @@ void net_send_query(int hops) {
 
   ip = (struct IPHeader *)packet;
   icmp = (struct ICMPHeader *)(packet + sizeof(struct IPHeader));
-  data = (struct packetdata *)(packet + sizeof(struct IPHeader) + sizeof(struct ICMPHeader));
 
   ip->version = 0x45;
   ip->tos = 0;
   ip->len = BSDfix ? packetsize: htons (packetsize);
   ip->id = 0;
   ip->frag = 0;
-  ip->ttl = hops;
+  ip->ttl = index + 1;
   ip->protocol = IPPROTO_ICMP;
   ip->saddr = 0;
   ip->daddr = remoteaddress.sin_addr.s_addr;
 
   icmp->type = ICMP_ECHO;
   icmp->id = getpid();
-  icmp->sequence = hops;
-
-  data->ttl = hops;
-  data->index = -1;
+  icmp->sequence = new_sequence(index);
 
   icmp->checksum = checksum(icmp, packetsize - sizeof(struct IPHeader));
   ip->check = checksum(ip, packetsize);
 
-  
+  gettimeofday(&sequence[icmp->sequence].time, NULL);
   rv = sendto(sendsock, packet, packetsize, 0, 
         (struct sockaddr *)&remoteaddress, sizeof(remoteaddress));
   if (first && (rv < 0) && (errno == EINVAL)) {
-    first = 0;
     ip->len = packetsize;
     rv = sendto(sendsock, packet, packetsize, 0, 
                (struct sockaddr *)&remoteaddress, sizeof(remoteaddress));
@@ -224,54 +185,50 @@ void net_send_query(int hops) {
       BSDfix = 1;
     }
   }
+  first = 0;
 }
 
-void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
-  int at;
-  struct timeval now;
+/*   We got a return on something we sent out.  Record the address and
+     time.  */
+void net_process_ping(int seq, uint32 addr, struct timeval now) {
+  int index;
   int totmsec;
 
-  if(data->index >= 0) {
-    gettimeofday(&now, NULL);
-
-    if(data->sec < reset.tv_sec
-       || (data->sec == reset.tv_sec && (1000*data->msec) < reset.tv_usec))
-      /* discard this data point, stats were reset after it was generated */
-      return;
-
-    if (net_duplicate(data->index, data->seq)) {
-       return;
-    }
-    
-    totmsec = (now.tv_sec - data->sec) * 1000 +
-              ((now.tv_usec/1000) - data->msec);
+  if(seq < 0 || seq >= MaxSequence)
+    return;
 
-    if(host[data->index].returned <= 0) {
-      host[data->index].best = host[data->index].worst = totmsec;
-    }
+  if(!sequence[seq].transit)
+    return;
+  sequence[seq].transit = 0;
 
-    if(totmsec < host[data->index].best)
-      host[data->index].best = totmsec;
+  index = sequence[seq].index;
 
-    if(totmsec > host[data->index].worst)
-      host[data->index].worst = totmsec;
+  totmsec = (now.tv_sec - sequence[seq].time.tv_sec) * 1000 +
+            ((now.tv_usec/1000) - (sequence[seq].time.tv_usec/1000));
 
-    display_rawping (data->index, totmsec);
+  if(host[index].addr == 0) {
+    host[index].addr = addr;
+    display_rawhost(index, host[index].addr);
+  }
+  if(host[index].returned <= 0) {
+    host[index].best = host[index].worst = totmsec;
+  }
+  if(totmsec < host[index].best)
+    host[index].best = totmsec;
+  if(totmsec > host[index].worst)
+    host[index].worst = totmsec;
 
-    host[data->index].total += totmsec;
-    host[data->index].returned++;
-    host[data->index].transit = 0;
-    net_save_return(data->index, data->seq, totmsec);
-  } else {
-    at = data->ttl - 1;
-    if(at < 0 || at > MaxHost)
-      return;
+  host[index].total += totmsec;
+  host[index].returned++;
+  host[index].transit = 0;
 
-    host[at].addr = addr->sin_addr.s_addr;
-    display_rawhost (at, host[at].addr);
-  }
+  net_save_return(index, sequence[seq].saved_seq, totmsec);
+  display_rawping(index, totmsec);
 }
 
+/*  We know a packet has come in, because the main select loop has called us,
+    now we just need to read it, see if it is for us, and if it is a reply 
+    to something we sent, then call net_process_ping()  */
 void net_process_return() {
   char packet[2048];
   struct sockaddr_in fromaddr;
@@ -279,12 +236,15 @@ void net_process_return() {
   int num;
   int at;
   struct ICMPHeader *header;
+  struct timeval now;
+
+  gettimeofday(&now, NULL);
 
   fromaddrsize = sizeof(fromaddr);
   num = recvfrom(recvsock, packet, 2048, 0, 
                 (struct sockaddr *)&fromaddr, &fromaddrsize);
 
-  if(num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + sizeof(struct packetdata))
+  if(num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader))
     return;
 
   header = (struct ICMPHeader *)(packet + sizeof(struct IPHeader));
@@ -292,9 +252,7 @@ void net_process_return() {
     if(header->id != getpid())
       return;
 
-    net_process_ping((struct packetdata *)(packet + sizeof(struct IPHeader) + 
-                                          sizeof(struct ICMPHeader)),
-                    &fromaddr);
+    net_process_ping(header->sequence, fromaddr.sin_addr.s_addr, now);
   } else if(header->type == ICMP_TIME_EXCEEDED) {
     if(num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + 
              sizeof(struct IPHeader) + sizeof(struct ICMPHeader))
@@ -304,13 +262,8 @@ void net_process_return() {
                                sizeof(struct ICMPHeader) + sizeof(struct IPHeader));
     if(header->id != getpid())
       return;
-    
-    at = header->sequence - 1;
-    if(at < 0 || at > MaxHost)
-      return;
 
-    host[at].addr = fromaddr.sin_addr.s_addr;
-    display_rawhost (at, net_addr(at));
+    net_process_ping(header->sequence, fromaddr.sin_addr.s_addr, now);
   }
 }
 
@@ -382,11 +335,7 @@ int net_send_batch() {
   static int at;
   int n_unknown, i;
 
-  if(host[at].addr == 0) {
-    net_send_query(at + 1);
-  } else {
-    net_send_ping(at);
-  }
+  net_send_query(at);
 
   n_unknown = 0;
 
@@ -463,7 +412,8 @@ void net_reset() {
   int i;
 
   for(at = 0; at < MaxHost; at++) {
-    host[at].xmit = host[at].transit;
+    host[at].xmit = 0;
+    host[at].transit = 0;
     host[at].returned = 0;
     host[at].total = 0;
     host[at].best = 0;
@@ -472,6 +422,11 @@ void net_reset() {
       host[at].saved[i] = -2;  /* unsent */
     }
   }
+  
+  for(at = 0; at < MaxSequence; at++) {
+    sequence[at].transit = 0;
+  }
+
   gettimeofday(&reset, NULL);
 }
 
@@ -484,6 +439,7 @@ int net_waitfd() {
   return recvsock;
 }
 
+
 int* net_saved_pings(int at) {
        return host[at].saved;
 }
@@ -495,28 +451,6 @@ void net_save_xmit(int at) {
        host[at].saved[SAVED_PINGS-1] = -1;
 }
 
-int net_duplicate(int at, int seq) {
-       int idx;
-       idx = SAVED_PINGS - (host[at].xmit - seq) - 1;
-       if (idx < 0) {
-               /* long in the past - assume received */
-               return 2;
-       }
-       if (idx >= SAVED_PINGS) {
-               /* ehhhh - back to the future? */
-               return 3;
-       }
-       if (host[at].saved[idx] == -2) {
-               /* say what?  must be an old ping */
-               return 4;
-       }
-       if (host[at].saved[idx] != -1) {
-               /* it's a dup */
-               return 5;
-       }
-       return 0;
-}
-
 void net_save_return(int at, int seq, int ms) {
        int idx;
        idx = SAVED_PINGS - (host[at].xmit - seq) - 1;
diff --git a/net.h b/net.h
index a9fdecc6e20b6830eb2aa6101f81e4fad954ecbb..929a7a667f21456c5df1dcc5fbfe3758df886a71 100644 (file)
--- a/net.h
+++ b/net.h
@@ -47,3 +47,4 @@ void net_save_return(int at, int seq, int ms);
 int net_duplicate(int at, int seq);
 
 #define MaxHost 256
+#define MaxSequence 65536
index 17d7601671daffd2857b7dae5d5c15d4dbef9f79..39eaa3a144d6d2388be1a3768ac3382d5ec23820 100644 (file)
--- a/select.c
+++ b/select.c
@@ -43,15 +43,15 @@ void select_loop() {
   int action, maxfd;
   int dnsfd, netfd;
   int NumPing;
+  int paused;
   struct timeval lasttime, thistime, selecttime;
   float wt;
 
-  /* This starts at -1, because the first packet sent is not counted
-     as a ping. That confuses people.  */
-  NumPing = -1; 
+  NumPing = 0; 
   anyset = 0;
   gettimeofday(&lasttime, NULL);
   DeltaTime = WaitTime/10;
+  paused=0;
 
   while(1) {
     intervaltime.tv_sec = DeltaTime;
@@ -76,7 +76,7 @@ void select_loop() {
     if(netfd >= maxfd)
       maxfd = netfd + 1;
 
-    if(anyset) {
+    if(anyset || paused) {
       selecttime.tv_sec = 0;
       selecttime.tv_usec = 0;
       
@@ -142,6 +142,12 @@ void select_loop() {
       if (action == ActionClear) 
        display_clear();
 
+      if (action == ActionPause) 
+       paused=1;
+
+      if (action == ActionResume) 
+       paused=0;
+
       anyset = 1;
     }