]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
mtr v0.29 v0.29
authorRoger Wolff <r.e.wolff@bitwizard.nl>
Wed, 3 Mar 1999 00:00:00 +0000 (00:00 +0000)
committerTravis Cross <tc@traviscross.com>
Sun, 3 Feb 2013 20:45:36 +0000 (20:45 +0000)
 - Lots of stuff.
 - Neato overview display by David Sward.
 - FreeBSD does wrong in the kernel the same that Solaris/x86 (see
   note for 0.27 does right. It forces mtr to send bad packets....
 - Adjusted "not too much at once" algorithm. Now probing continues as
   long as not more than 5 hosts are unknown.  Returning packets
   usually allow us to do the first sweep in one go.

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

15 files changed:
AUTHORS
NEWS
README
TODO
configure.in
curses.c
display.c
display.h
gtk.c
mtr-curses.h
mtr.c
net.c
net.h
select.c
split.c

diff --git a/AUTHORS b/AUTHORS
index d8dd1ea0a836174783f2c681d73dac82b3118c31..531be363ed5356b2b2df356e7c24d0f3636f8fd0 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
   Thanks to everyone who has provided feedback on mtr.  
 
   Thanks especially to those of you who have sent code:
+  (Reverse alphabetical order)
+
+       Juha Takala, 
+       David Sward (sward@clark.net),
+        Andrew Stesin, 
+        Aaron Scarisbrick, 
+        Russell Nelson, 
+       Alexander V. Lukyanov, 
+        Charles Levert, 
+        Bertrand Leconte, 
+        Anand Kumria, 
+       Adam Kramer (l3zqc@qcunix1.acc.qc.edu), 
+        Simon Kirby, 
+        Christophe Kalt,
+        Mircea Damian, 
+        Brian Casey, 
 
-       Brian Casey, Mircea Damian, Christophe Kalt, Simon Kirby,
-        Anand Kumria, Bertrand Leconte, Charles Levert, Alexander 
-        V. Lukyanov, Russell Nelson, Aaron Scarisbrick, Andrew 
-        Stesin, Juha Takala.
         and anyone who has slipped through the cracks of my mail file.
+
+Authors: If you want your Email mentioned here, send it to me. 
+         If you don't want your Email mentioned here, tell me.  
+
+        -- REW
diff --git a/NEWS b/NEWS
index 60aa2aba52101ffb2eb7a81c80969ea6b4016121..3ed50aac2dccbc409c077887e7f152c766705ab9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,17 @@
 WHAT'S NEW?
 
+  v0.29 Lots of stuff. 
+        Neato overview display by David Sward. 
+        FreeBSD does wrong in the kernel the same that Solaris/x86 (see 
+            note for 0.27 does right. It forces mtr to send bad packets....
+        Adjusted "not too much at once" algorithm. Now probing
+           continues as long as not more than 5 hosts are unknown.
+           Returning packets usually allow us to do the first sweep 
+           in one go. 
+
+
+  v0.28 DNS lookups are now suppressed if you don't want them. 
+
   v0.27
        Fixed bug that showed up on Solaris/x86.
        Gimp mainloop now runs as it's supposed to.
diff --git a/README b/README
index 2cae3f6c8fddecbc902b80921c37bf6263224303..1f68dad41b7f8a18f7f8de389ae106f7fade72db 100644 (file)
--- a/README
+++ b/README
@@ -15,7 +15,10 @@ WHAT IS MTR?
 
 INSTALLING
 
-  To begin mtr, first use the included configure script:
+  Slightly more hints are in the file INSTALL. If this doesn't work
+  you could try reading that too.... 
+
+  To begin compiling mtr, first use the included configure script:
 
        ./configure
 
@@ -30,6 +33,18 @@ INSTALLING
   Note that mtr must be suid-root because it requires access to raw IP 
   sockets.  See SECURITY for security information.
 
+  If you want to build a version that doesn't use GTK, but if you
+  DO have GTK installed, you can use 
+
+       ./configure --with-gtk-prefix=/we_dont_want_gtk_so_we_use_a_name_that_certainly_doesnt_exist
+
+  It seems the --no_gtk (whatever) doesn't work. Feel free to submit 
+  a patch for this, I'm not that familiar with autoconf (it works for
+  me :-).
+
+  
+
+
 WHERE CAN I GET THE LATEST VERSION OR MORE INFORMATION?
 
   See the mtr web page at 
@@ -43,4 +58,3 @@ WHERE CAN I GET THE LATEST VERSION OR MORE INFORMATION?
 
   Bug reports and feature requests should be sent to the mtr 
   mailing list.
-
diff --git a/TODO b/TODO
index 0d406815cdd799a9b88ef0bf35dc436b876bb1b9..5ceb3cdb17b7d3cd54482bdea69291a1aaf376a9 100644 (file)
--- a/TODO
+++ b/TODO
 
 
 - Bugs to fix?
-  - ?
+
+  - Do something useful if host couldn't be resolved. 
+
+- Nice to have:
+
+  - stop sending packets when a new host is getting entered. 
+
+  - Show state ("looking up host") while doing the DNS lookup for a new
+    host.
+
+  - Check why it still tries to go for X11 display if DISPLAY is unset.
+    (I saw code to handle this)
+
+  - Revert to curses mode even if DISPLAY is set, but a problem
+    prevents us from running in X11 mode.
+       -->  The problem is that gtk_init simply calls exit for us if
+            it finds a problem. Tricky!
+
+  - Read environment variable "MTR_DEFAULTS" as a commandline before
+    parsing the commandline. 
 
index d9f5c5764e82fb51e19cf1dbbafd71602def4506..1dc26cb2292016937c27936e0fdf26963622c0f9 100644 (file)
@@ -1,5 +1,5 @@
 AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.28)
+AM_INIT_AUTOMAKE(mtr, 0.29)
 
 AC_SUBST(GTK_OBJ)
 AC_SUBST(CURSES_OBJ)
@@ -37,6 +37,9 @@ AC_CHECK_FUNC(socket, ,
 AC_CHECK_FUNC(gethostbyname, ,
   AC_CHECK_LIB(nsl, gethostbyname, , AC_MSG_ERROR(No nameservice library found)))
 
+AC_CHECK_FUNC(res_init, , 
+  AC_CHECK_LIB(bind, res_init, , AC_MSG_ERROR(No resolver library found)))
+
 AC_CHECK_FUNC(res_mkquery, , 
   AC_CHECK_LIB(resolv, res_mkquery, , AC_MSG_ERROR(No resolver library found)))
 
index 4932e6f48a7ef26b4ab2eb20224177c3c51299fe..930c66a68d696bf80d4a64b77932beeb17dd0230 100644 (file)
--- a/curses.c
+++ b/curses.c
@@ -61,8 +61,12 @@ int mtr_curses_keyaction() {
     return ActionQuit;
   if(c==3)
      return ActionQuit;
+  if (c==12)
+     return ActionClear;
   if(tolower(c) == 'r')
     return ActionReset;
+  if (tolower(c) == 'd')
+    return ActionDisplay;
 
   return 0;
 }
@@ -92,7 +96,7 @@ void mtr_curses_hosts(int startstat) {
       getyx(stdscr, y, x);
       move(y, startstat);
 
-      printw("  %3d%% %3d %3d %4d %4d %6d", 
+      printw("  %3d%% %4d %4d  %4d %4d %6d", 
              net_percent(at),
              net_returned(at), net_xmit(at),
              net_best(at), net_avg(at), net_worst(at));
@@ -106,17 +110,120 @@ void mtr_curses_hosts(int startstat) {
   }
 }
 
+static double factors[] = { 0.02, 0.05, 0.08, 0.15, 0.33, 0.50, 0.80, 1.00 };
+static int scale[8];
+static int low_ms, high_ms;
+
+void mtr_gen_scale(void) {
+       int *saved, i, max, at;
+       int range;
+
+       low_ms = 1000000;
+       high_ms = -1;
+
+       for (i = 0; i < 8; i++) {
+               scale[i] = 0;
+       }
+       max = net_max();
+       for (at = 0; at < max; at++) {
+               saved = net_saved_pings(at);
+               for (i = 0; i < SAVED_PINGS; i++) {
+                       if (saved[i] < 0) continue;
+                       if (saved[i] < low_ms) {
+                               low_ms = saved[i];
+                       }
+                       if (saved[i] > high_ms) {
+                               high_ms = saved[i];
+                       }
+               }
+       }
+       range = high_ms - low_ms;
+       for (i = 0; i < 8; i++) {
+               scale[i] = low_ms + ((double)range * factors[i]);
+       }
+}
+
+static const char* block_map = ".123abc>";
+
+void mtr_print_scaled(int ms) {
+       int i;
+
+       for (i = 0; i < 8; i++) {
+               if (ms <= scale[i]) {
+                       printw("%c", block_map[i]);
+                       return;
+               }
+       }
+       printw(">");
+}
+
+void mtr_fill_graph(int at) {
+       int* saved;
+       int i;
+       int val;
+
+       saved = net_saved_pings(at);
+       for (i = 0; i < SAVED_PINGS; i++) {
+               if (saved[i] == -2) {
+                       printw(" ");
+               } else if (saved[i] == -1) {
+                       attron(A_BOLD);
+                       printw("?");
+                       attroff(A_BOLD);
+               } else {
+                       if (display_mode == 1) {
+                               if (saved[i] > scale[6]) {
+                                       printw("%c", block_map[7]);
+                               } else {
+                                       printw(".");
+                               }
+                       } else {
+                               mtr_print_scaled(saved[i]);
+                       }
+               }
+       }
+}
+
+void mtr_curses_graph(int startstat) {
+       int max, at, addr, y, x;
+       char* name;
+       char blocks[50];
+
+       max = net_max();
+       for (at = 0; at < max; at++) {
+               printw("%2d. ", at+1);
+
+               addr = net_addr(at);
+               if (!addr) {
+                       printw("???\n");
+                       continue;
+               }
+
+               name = dns_lookup(addr);
+               if (name) {
+                       printw("%s", name);
+               } else {
+                       printw("%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) && 0xff, (addr >> 8) & 0xff, addr & 0xff);
+               }
+
+               getyx(stdscr, y, x);
+               move(y, startstat);
+
+               printw(" ");
+               mtr_fill_graph(at);
+               printw("\n");
+       }
+}
+
 void mtr_curses_redraw() {
   int maxx, maxy;
   int startstat;
   int rowstat;
+  int i;
 
   erase();
   getmaxyx(stdscr, maxy, maxx);
 
-  /* Modified by Brian Casey December 1997 bcasey@imagiware.com */
-  startstat = maxx - 40;
-
   rowstat = 5;
 
   attron(A_BOLD);
@@ -126,6 +233,8 @@ void mtr_curses_redraw() {
   attroff(A_BOLD);
 
   printw("Keys:  ");
+  attron(A_BOLD);  printw("D");  attroff(A_BOLD);
+  printw(" - Display mode    ");
   attron(A_BOLD);  printw("R");  attroff(A_BOLD);
   printw(" - Restart statistics    ");
   attron(A_BOLD);  printw("Q");  attroff(A_BOLD);
@@ -134,14 +243,38 @@ void mtr_curses_redraw() {
   attron(A_BOLD);
   mvprintw(rowstat - 1, 0, "Hostname");
 
-  /* Modified by Brian Casey December 1997 bcasey@imagiware.com */
-  mvprintw(rowstat - 2, startstat, "    Packets            Pings");
-  mvprintw(rowstat - 1, startstat, " %%Loss  Rcv Snt  Best  Avg  Worst");
+  if (display_mode == 0) {
+    startstat = maxx - 40;
 
-  attroff(A_BOLD);
-  move(rowstat, 0);
+    /* Modified by Brian Casey December 1997 bcasey@imagiware.com */
+    mvprintw(rowstat - 2, startstat, "    Packets            Pings");
+    mvprintw(rowstat - 1, startstat, " %%Loss  Rcv  Snt  Best  Avg  Worst");
+
+    attroff(A_BOLD);
+    move(rowstat, 0);
+
+    mtr_curses_hosts(startstat);
+  } else {
+    /* David Sward, Jan 1999 */
+    startstat = maxx - 52;
 
-  mtr_curses_hosts(startstat);
+    mvprintw(rowstat - 1, startstat, " Last 50 pings");
+
+    attroff(A_BOLD);
+    move(rowstat, 0);
+
+    mtr_gen_scale();
+    mtr_curses_graph(startstat);
+
+    printw("\n");
+    attron(A_BOLD);
+    printw("Scale:");
+    attroff(A_BOLD);
+    
+    for (i = 0; i < 7; i++) {
+      printw("  %c:%d ms", block_map[i], scale[i]);
+    }
+  }
 
   refresh();
 }
@@ -158,3 +291,8 @@ void mtr_curses_close() {
   printw("\n");
   endwin();
 }
+
+void mtr_curses_clear() {
+  mtr_curses_close();
+  mtr_curses_open();
+}
index 22006635745af64f7aa99ba6f4d1d203d0a8624d..9f18b4e918a0b571bc10849f5b7d66edd76c215b 100644 (file)
--- a/display.c
+++ b/display.c
@@ -170,3 +170,18 @@ void display_loop() {
   }
 }
 
+
+void display_clear() {
+  switch(DisplayMode) {
+  case DisplayCurses:
+    mtr_curses_clear();
+    break;
+  case DisplayReport:
+  case DisplaySplit:            /* BL */
+  case DisplayRaw:
+    break;
+
+  case DisplayGTK:
+    break;
+  }
+}
index 7919bbf56041e5e7761d887c58e50d541a98eeef..3bd27f22ea54d0b6b08fd4e6488202574a59a3d1 100644 (file)
--- a/display.h
+++ b/display.h
@@ -17,7 +17,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-enum { ActionNone, ActionQuit, ActionReset };
+enum { ActionNone, ActionQuit, ActionReset, ActionDisplay, ActionClear };
 enum { DisplayReport, DisplayCurses, DisplayGTK, DisplaySplit, DisplayRaw };
 
 /*  Prototypes for display.c  */
@@ -29,3 +29,6 @@ void display_rawping(int hostnum, int msec);
 void display_rawhost(int hostnum, int ip_addr);
 int display_keyaction();
 void display_loop();
+void display_clear();
+
+int display_mode;
diff --git a/gtk.c b/gtk.c
index 8f0d88d4d0e082c6b98a3b730fee3644c0ad25cd..20c55207d6d6ea0c297c725ea3395df3f8b08451 100644 (file)
--- a/gtk.c
+++ b/gtk.c
@@ -147,12 +147,14 @@ GtkWidget *GetRow(int index) {
 
 GtkWidget *Scrollarea_create() {
   GtkWidget *List;
+  GtkWidget *scroll;
   int count;
 
   for(count = 0; Report_Positions[count]; count++);
 
   List = GTK_WIDGET(gtk_clist_new_with_titles(count, Report_Text));
-  gtk_clist_set_policy(GTK_CLIST(List), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  scroll = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
   for(count = 0; Report_Positions[count + 1]; count++) {
     gtk_clist_set_column_width(GTK_CLIST(List), count, 
                               Report_Positions[count + 1] - 
@@ -162,9 +164,11 @@ GtkWidget *Scrollarea_create() {
   for(count = 1; Report_Positions[count]; count++) {
     gtk_clist_set_column_justification(GTK_CLIST(List), count, GTK_JUSTIFY_RIGHT);
   }
+  gtk_container_add(GTK_CONTAINER(scroll), List);
+  gtk_widget_show(List);
 
   ReportBody = List;
-  return List;
+  return scroll;
 }
 
 void gtk_add_row(GtkWidget *List) {
index c94880f347be4419d0230d9f00c7a08c669ab46f..d12d878c1c168ac7b73567a19b6915ebac7bc4f2 100644 (file)
@@ -22,3 +22,4 @@ void mtr_curses_open();
 void mtr_curses_close();
 void mtr_curses_redraw();
 int mtr_curses_keyaction();
+void mtr_curses_clear();
diff --git a/mtr.c b/mtr.c
index 8c1bb9f2be8a5ff913c91341e704aa67cb6d7792..e80a8f90c02f5a9825a5d40d7f2d02dc40c7e22d 100644 (file)
--- a/mtr.c
+++ b/mtr.c
@@ -173,6 +173,7 @@ int main(int argc, char **argv) {
   display_open();
   dns_open();
 
+  display_mode = 0;
   display_loop();
 
   net_end_transit();
diff --git a/net.c b/net.c
index e1797f60a411150c368dccda4d60c378d9263fa3..994fa489d234de8331aa240c9336270dde4db95c 100644 (file)
--- a/net.c
+++ b/net.c
 #include <unistd.h>
 #include <stdio.h>
 #include <math.h>
+#include <errno.h>
 
 #include "net.h"
 
 
 extern float WaitTime, DeltaTime;
+int timestamp;
 
 #define MaxTransit 4
 
@@ -66,8 +68,12 @@ struct IPHeader {
   
 #define ICMP_ECHO              8
 #define ICMP_ECHOREPLY         0
+
+#define ICMP_TSTAMP            13
+#define ICMP_TSTAMPREPLY       14
+
 #define ICMP_TIME_EXCEEDED     11
-  
+
 #ifndef SOL_IP
 #define SOL_IP 0
 #endif
@@ -77,6 +83,7 @@ struct packetdata {
     int ttl;
     int sec;
     int msec;
+    int seq;
 };
 
 struct nethost {
@@ -87,6 +94,7 @@ struct nethost {
   int best;
   int worst;
   int transit;
+  int saved[SAVED_PINGS];
 };
 
 static struct nethost host[MaxHost];
@@ -112,6 +120,9 @@ int checksum(void *data, int sz) {
   return (~sum & 0xffff);  
 }
 
+
+static int BSDfix = 0;
+
 void net_send_ping(int index) {
   char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader) 
             + sizeof(struct packetdata)];
@@ -127,6 +138,7 @@ void net_send_ping(int index) {
   addr.sin_addr.s_addr = host[index].addr;
   host[index].xmit++;
   host[index].transit = 1;
+  net_save_xmit(index);
 
   memset(packet, 0, packetsize);
 
@@ -136,7 +148,7 @@ void net_send_ping(int index) {
 
   ip->version = 0x45;
   ip->tos = 0;
-  ip->len = htons (packetsize);
+  ip->len = BSDfix? packetsize: htons (packetsize);
   ip->id = 0;
   ip->frag = 0;
   ip->ttl = 127;
@@ -144,12 +156,13 @@ void net_send_ping(int index) {
   ip->saddr = 0;
   ip->daddr = host[index].addr;
   
-  icmp->type = ICMP_ECHO;
+  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;
@@ -169,6 +182,8 @@ void net_send_query(int hops) {
   struct ICMPHeader *icmp;
   struct packetdata *data;
   int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + sizeof(struct packetdata);
+  int rv;
+  static int first=1;
 
   memset(packet, 0, packetsize);
 
@@ -178,7 +193,7 @@ void net_send_query(int hops) {
 
   ip->version = 0x45;
   ip->tos = 0;
-  ip->len = htons (packetsize);
+  ip->len = BSDfix ? packetsize: htons (packetsize);
   ip->id = 0;
   ip->frag = 0;
   ip->ttl = hops;
@@ -196,8 +211,19 @@ void net_send_query(int hops) {
   icmp->checksum = checksum(icmp, packetsize - sizeof(struct IPHeader));
   ip->check = checksum(ip, packetsize);
 
-  sendto(sendsock, packet, packetsize, 0, 
+  
+  rv = sendto(sendsock, packet, packetsize, 0, 
         (struct sockaddr *)&remoteaddress, sizeof(remoteaddress));
+  if (first && (rv == EINVAL)) {
+    first = 0;
+    ip->len = packetsize;
+    rv = sendto(sendsock, packet, packetsize, 0, 
+               (struct sockaddr *)&remoteaddress, sizeof(remoteaddress));
+    if (rv >= 0) {
+      fprintf (stderr, "You've got a broken (FreeBSD?) system\n");
+      BSDfix = 1;
+    }
+  }
 }
 
 void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
@@ -212,6 +238,10 @@ void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
        || (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);
@@ -231,6 +261,7 @@ void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
     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)
@@ -288,10 +319,10 @@ int net_addr(int at) {
 }
 
 int net_percent(int at) {
-  if(host[at].xmit == 0) 
+  if((host[at].xmit - host[at].transit) == 0) 
     return 0;
 
-  return 100 - (100 * (host[at].returned + host[at].transit) / host[at].xmit);
+  return 100 - (100 * host[at].returned / (host[at].xmit - host[at].transit));
 }
 
 int net_best(int at) {
@@ -348,21 +379,28 @@ void net_end_transit() {
 
 
 int net_send_batch() {
-  static int n_unknown = 10;
   static int at;
+  int n_unknown, i;
 
   if(host[at].addr == 0) {
     net_send_query(at + 1);
-    n_unknown--;
   } else {
     net_send_ping(at);
   }
-  
+
+  n_unknown = 0;
+
+  for (i=0;i<at;i++) {
+    if (host[i].addr == 0)
+      n_unknown++;
+    if (host[i].addr == remoteaddress.sin_addr.s_addr)
+      n_unknown = 100; /* Make sure we drop into "we should restart" */
+  }
+
   if ((host[at].addr == remoteaddress.sin_addr.s_addr) ||
-      (n_unknown == 0)) {
+      (n_unknown > 5)) {
     DeltaTime = WaitTime / (float) (at+1);
     at = 0;
-    n_unknown = 10;
     return 1;
   }
 
@@ -396,6 +434,8 @@ int net_preopen() {
 }
  
 int net_open(int addr) {
+  net_reset();
+
   remoteaddress.sin_family = AF_INET;
   remoteaddress.sin_addr.s_addr = addr;
 
@@ -420,6 +460,7 @@ void net_reopen(int addr) {
 
 void net_reset() {
   int at;
+  int i;
 
   for(at = 0; at < MaxHost; at++) {
     host[at].xmit = host[at].transit;
@@ -427,6 +468,9 @@ void net_reset() {
     host[at].total = 0;
     host[at].best = 0;
     host[at].worst = 0;
+    for (i=0; i<SAVED_PINGS; i++) {
+      host[at].saved[i] = -2;  /* unsent */
+    }
   }
   gettimeofday(&reset, NULL);
 }
@@ -440,4 +484,44 @@ int net_waitfd() {
   return recvsock;
 }
 
+int* net_saved_pings(int at) {
+       return host[at].saved;
+}
+
+void net_save_xmit(int at) {
+       int tmp[SAVED_PINGS];
+       memcpy(tmp, &host[at].saved[1], (SAVED_PINGS-1)*sizeof(int));
+       memcpy(host[at].saved, tmp, (SAVED_PINGS-1)*sizeof(int));
+       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;
+       if (idx < 0) {
+               return;
+       }
+       host[at].saved[idx] = ms;
+}
diff --git a/net.h b/net.h
index fd786700d099ab315b7443186b3ce9929d20d4c0..a9fdecc6e20b6830eb2aa6101f81e4fad954ecbb 100644 (file)
--- a/net.h
+++ b/net.h
@@ -40,5 +40,10 @@ int net_returned(int at);
 int net_xmit(int at);
 int net_transit(int at);
 
+#define SAVED_PINGS 50
+int* net_saved_pings(int at);
+void net_save_xmit(int at);
+void net_save_return(int at, int seq, int ms);
+int net_duplicate(int at, int seq);
 
 #define MaxHost 256
index 193ecd602f028c260a76cc14d0f2f2653d8146e9..2f184a8dd7539a7a12b17ddfc0dce0e5dda7eb5e 100644 (file)
--- a/select.c
+++ b/select.c
@@ -134,6 +134,12 @@ void select_loop() {
       if(action == ActionReset) 
        net_reset();
 
+      if (action == ActionDisplay) 
+        display_mode = (display_mode+1) % 3;
+
+      if (action == ActionClear) 
+       display_clear();
+
       anyset = 1;
     }
 
diff --git a/split.c b/split.c
index a9bc2ff285a7bceca0750557328b7176c316a630..5f685f9839f7c15f95a657d2b6a2bf3331bab2a0 100644 (file)
--- a/split.c
+++ b/split.c
 #include "split.h"
 */
 
+#include <config.h>
+
+#if defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#else
+#  error No curses header file available
+#endif
+
+
 
 extern char *Hostname;
 extern int WaitTime;