From: Roger Wolff Date: Fri, 13 Aug 1999 00:00:00 +0000 (+0000) Subject: mtr v0.40 X-Git-Tag: v0.40^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0fb88ef4a427a6f66b6ee5bfdcfbd946849eacec;p=thirdparty%2Fmtr.git mtr v0.40 - Fixed some problems with HPUX and SunOS. - Included Olav Kvittem's patch to do packetsize option. - Made the timekeeping in micro seconds. source: ftp://ftp.bitwizard.nl/mtr/mtr-0.40.tar.gz --- diff --git a/AUTHORS b/AUTHORS index f1daf1d..7288c16 100644 --- a/AUTHORS +++ b/AUTHORS @@ -23,6 +23,7 @@ Charles Levert (charles@comm.polymtl.ca), Bertrand Leconte (B.Leconte@mail.dotcom.fr), Anand Kumria, + Olav Kvittem (Olav.Kvittem@uninett.no), Adam Kramer (l3zqc@qcunix1.acc.qc.edu), Philip Kizer (pckizer@nostrum.com), Simon Kirby, diff --git a/NEWS b/NEWS index 95d4e72..a555962 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,13 @@ WHAT'S NEW? + v0.40 Fixed some problems with HPUX and SunOS. + Included Olav Kvittem's patch to do packetsize option. + Made the timekeeping in micro seconds. + + v0.39 Forgot the parentheses around the previous fix... :-( + + v0.38 fixed some dubious code in dns.c (noted by someone's lint) + v0.37 Added Bill Bogstad's "show the local host & time" patch. Added R. Sparks' show-last-ping patch, submitted by Philip Kizer. diff --git a/TODO b/TODO index ef55752..2090d2b 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,33 @@ +Hi everyone, + +This is the "todo" file for mtr. I just realized that some people +might think that this is all in MY queue to implement. That is not +true: This is the "for everybody" todo list. Feel free to pick a +"project" and implement something off this list. + +Students: Feel free to take up one of these as a programming exercise +for one of your courses. + +Everybody: If you want to start on something, contact me first, so +that the effort isn't wasted by someone who finishes just a tad +earlier. I'll happily provide "coaching" to anyone who wants to +implement something on this list. That way we get the design of +these things the way I like them. This should result in a better +maintainable mtr. + +Oh, Feel free to provide suggestions for this list. + + +-- REW + +---------------------------------------------------------------------- + + - Stuff to implement: - Allow mtr to log the return packets, for later analysis. - Done: 0.25 . Todo: allow the userinterface(s) to work while + Done: 0.25 . Todo: allow the user interface(s) to work while still logging to a file. Write a "logfile displaying" mode to mtr. @@ -11,20 +36,6 @@ convert these measurements into one-way measurements, not just round-trip. - - Allow mtr to also send larger packets. - This will enable us to get a feel for the speed of the links - we're traversing. (Van Jacobson was working on this His tool - was slow, mtr will rock with this feature.... :-) - (Anybody have the statistics experience to tell me how - to do the data analysis?) - - - 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 - slowly (relative to the RTT time to the end host), it can probe - all hosts in the first "round". - -- DONE. - - allow "keyboard navigation" in the GTK version. @@ -62,6 +73,28 @@ - Allow a toggle between hostname/IP number display. (for example a click on the hostname could revert to ip number display in gtk version. - curses: "n" key toggles hostnames/ipnumbers? + curses: "n" key toggles hostnames/ipnumbers?) + + - Implement rfc2317 mechanism to do reverse lookups for networks that + have DNS delegations on non-octet boundaries. -- Daniel Bergstrom + (noa@melody.se) + +------------------------------------------------------------------------ +Things that shouldn't be on the TODO list because they're done. ;-) + + - Allow mtr to also send larger packets. + This will enable us to get a feel for the speed of the links + we're traversing. (Van Jacobson was working on this His tool + was slow, mtr will rock with this feature.... :-) + (Anybody have the statistics experience to tell me how + to do the data analysis?) + -- DONE. Thanks to Olav Kvittem ... + + - 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 + slowly (relative to the RTT time to the end host), it can probe + all hosts in the first "round". + -- DONE. diff --git a/configure.in b/configure.in index d326fed..b4ec4e6 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_INIT(mtr.c) -AM_INIT_AUTOMAKE(mtr, 0.39) +AM_INIT_AUTOMAKE(mtr, 0.40) AC_SUBST(GTK_OBJ) AC_SUBST(CURSES_OBJ) @@ -18,14 +18,23 @@ AC_CHECK_SIZEOF(unsigned long, 4) # - 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]]]) +# We don't refer to any symbols in termcap, but -lcurses on SunOS does. +# We have to trust the linker not to mess things up... (It should not +# pull in anything if we don't refer to anything in the lib). +AC_CHECK_LIB(termcap, tgetent) + AC_CHECK_FUNC(initscr, , AC_CHECK_LIB(ncurses, initscr, , AC_CHECK_LIB(curses, initscr, , + AC_CHECK_LIB(cursesX, initscr, , AC_MSG_WARN(Building without curses display support) AC_DEFINE(NO_CURSES) - CURSES_OBJ=))) + CURSES_OBJ=)))) + +AC_CHECK_FUNCS(attron) -AC_CHECK_HEADERS(ncurses.h ncurses/curses.h curses.h) + +AC_CHECK_HEADERS(ncurses.h ncurses/curses.h curses.h cursesX.h sys/types.h) AC_CHECK_HEADERS(sys/xti.h) AC_CHECK_LIB(m, floor, , AC_MSG_ERROR(No math library found)) @@ -46,6 +55,9 @@ AC_CHECK_FUNC(res_init, , AC_CHECK_LIB(bind, res_init, , AC_CHECK_LIB(resolv, res_init, , AC_MSG_ERROR(No resolver library found)))) +AC_CHECK_FUNCS(seteuid) +# AC_CHECK_FUNC(setuid, , AC_MSG_ERROR (I Need either seteuid or setuid)) + AC_CHECK_FUNC(res_mkquery, , AC_CHECK_LIB(bind, res_init, , AC_CHECK_LIB(resolv, res_init, , AC_MSG_ERROR(No resolver library found)))) diff --git a/curses.c b/curses.c index 82c6628..c914305 100644 --- a/curses.c +++ b/curses.c @@ -29,10 +29,24 @@ # include #elif defined(HAVE_CURSES_H) # include +#elif defined(HAVE_CURSESX_H) +# include #else # error No curses header file available #endif +#if defined(HAVE_SYS_TYPES_H) +#include +#else +/* If a system doesn't have sys/types.h, lets hope that time_t is an int */ +#define time_t int +#endif + +#ifndef HAVE_ATTRON +#define attron(x) +#define attroff(x) +#endif + #ifndef getmaxyx # define getmaxyx(win,y,x) (y = (win)->_maxy + 1, x = (win)->_maxx + 1) #endif @@ -44,7 +58,7 @@ #endif #include -extern LocalHostname[]; +extern char LocalHostname[]; void pwcenter(char *str) { int maxx, maxy; @@ -66,9 +80,9 @@ int mtr_curses_keyaction() { return ActionQuit; if (c==12) return ActionClear; - if (c==19) + if ((c==19) || (tolower (c) == 'p')) return ActionPause; - if (c==17) + if ((c==17) || (c == ' ')) return ActionResume; if(tolower(c) == 'r') return ActionReset; @@ -103,10 +117,12 @@ void mtr_curses_hosts(int startstat) { getyx(stdscr, y, x); move(y, startstat); + /* net_xxx returns times in usecs. Just display millisecs */ printw(" %3d%% %4d %4d %4d %4d %4d %6d", net_percent(at), - net_returned(at), net_xmit(at), - net_last(at),net_best(at), net_avg(at), net_worst(at)); + net_returned(at), net_xmit(at), + net_last(at)/1000, net_best(at)/1000, + net_avg(at)/1000, net_worst(at)/1000); } else { @@ -234,12 +250,12 @@ void mtr_curses_redraw() { rowstat = 5; - attron(A_BOLD); move(0, 0); + attron(A_BOLD); pwcenter("Matt's traceroute [v" VERSION "]"); - printw("\n"); attroff(A_BOLD); - printw(LocalHostname); + + mvprintw(1,0, LocalHostname); time(&t); mvprintw(1, maxx-25, ctime(&t)); @@ -255,7 +271,7 @@ void mtr_curses_redraw() { mvprintw(rowstat - 1, 0, "Hostname"); if (display_mode == 0) { - startstat = maxx - 40; + startstat = maxx - 41; /* Modified by Brian Casey December 1997 bcasey@imagiware.com */ mvprintw(rowstat - 2, startstat, " Packets Pings"); @@ -283,7 +299,7 @@ void mtr_curses_redraw() { attroff(A_BOLD); for (i = 0; i < 7; i++) { - printw(" %c:%d ms", block_map[i], scale[i]); + printw(" %c:%d ms", block_map[i], scale[i]/1000); } } diff --git a/dns.c b/dns.c index 3945fed..87d3c1f 100644 --- a/dns.c +++ b/dns.c @@ -92,8 +92,8 @@ struct resolve { struct resolve *previousip; struct resolve *nexthost; struct resolve *previoushost; + float expiretime; /* Fucking HPUX has a problem with "double" here. */ char *hostname; - double expiretime; ip_t ip; word id; byte state; diff --git a/gtk.c b/gtk.c index 925b025..a5189f2 100644 --- a/gtk.c +++ b/gtk.c @@ -300,9 +300,9 @@ void gtk_update_row(GtkCList *List, int row) { gtk_set_field_num(List, row, 2, "%d", net_returned(row)); gtk_set_field_num(List, row, 3, "%d", net_xmit(row)); - gtk_set_field_num(List, row, 4, "%d", net_best(row)); - gtk_set_field_num(List, row, 5, "%d", net_avg(row)); - gtk_set_field_num(List, row, 6, "%d", net_worst(row)); + gtk_set_field_num(List, row, 4, "%d", net_best(row)/1000); + gtk_set_field_num(List, row, 5, "%d", net_avg(row)/1000); + gtk_set_field_num(List, row, 6, "%d", net_worst(row)/1000); } diff --git a/mtr.8 b/mtr.8 index 626298d..d9f416c 100644 --- a/mtr.8 +++ b/mtr.8 @@ -40,7 +40,10 @@ mtr \- a network diagnostic tool [\c .B \-\-interval\ SECONDS\c ] -.B HOSTNAME +[\c +.B \-\-psize\ BYTES | -p BYTES\c +] +.B HOSTNAME [PACKETSIZE] .SH DESCRIPTION @@ -116,6 +119,15 @@ is only useful with the .B -r option. +.TP +.B \-p\ BYTES +.TP +.B \-\-psize\ BYTES +.TP +.B PACKETSIZE +These options or a trailing PACKETSIZE on the commandline sets +the packet size used for probing. +It is in bytes inclusive IP and ICMP headers .TP .B \-t .TP diff --git a/mtr.c b/mtr.c index 9335e2c..10df43e 100644 --- a/mtr.c +++ b/mtr.c @@ -30,6 +30,12 @@ #include "report.h" #include "net.h" + +#ifndef HAVE_SETEUID +/* HPUX doesn't have seteuid, but setuid works fine in that case for us */ +#define seteuid setuid +#endif + int DisplayMode; int Interactive = 1; int PrintVersion = 0; @@ -39,6 +45,7 @@ float WaitTime = 1.0; char *Hostname = NULL; char LocalHostname[128]; int dns = 1; +int packetsize = 64; void parse_arg(int argc, char **argv) { int opt; @@ -50,6 +57,7 @@ void parse_arg(int argc, char **argv) { { "curses", 0, 0, 't' }, { "gtk", 0, 0, 'g' }, { "interval", 1, 0, 'i' }, + { "psize", 1, 0, 'p' }, { "no-dns", 0, 0, 'n' }, { "split", 0, 0, 's' }, /* BL */ { "raw", 0, 0, 'l' }, @@ -58,7 +66,7 @@ void parse_arg(int argc, char **argv) { opt = 0; while(1) { - opt = getopt_long(argc, argv, "hvrc:tklnsi:", long_options, NULL); + opt = getopt_long(argc, argv, "hvrc:tklnsi:p:", long_options, NULL); if(opt == -1) break; @@ -73,7 +81,10 @@ void parse_arg(int argc, char **argv) { DisplayMode = DisplayReport; break; case 'c': - MaxPing = atoi(optarg); + MaxPing = atoi (optarg); + break; + case 'p': + packetsize = atoi (optarg); break; case 't': DisplayMode = DisplayCurses; @@ -91,7 +102,7 @@ void parse_arg(int argc, char **argv) { dns = 0; break; case 'i': - WaitTime = atof(optarg); + WaitTime = atof (optarg); if (WaitTime <= 0.0) { fprintf (stderr, "mtr: wait time must be positive\n"); exit (1); @@ -133,6 +144,7 @@ void parse_mtr_options (char *string) } + int main(int argc, char **argv) { int traddr; struct hostent *host; diff --git a/net.c b/net.c index b4f35a0..46f4bb1 100644 --- a/net.c +++ b/net.c @@ -15,6 +15,9 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + 1999-08-13 ok Olav@okvittem.priv.no added -psize + */ #include @@ -75,12 +78,14 @@ struct IPHeader { #ifndef SOL_IP #define SOL_IP 0 #endif - + + + struct nethost { uint32 addr; int xmit; int returned; - int total; + long long total; int last; int best; int worst; @@ -113,7 +118,7 @@ struct sockaddr_in remoteaddress; static int batch_at = 0; - +extern int packetsize; static int numhosts = 10; /* return the number of microseconds to wait before sending the next @@ -167,13 +172,17 @@ int new_sequence(int index) { /* Attempt to find the host at a particular number of hops away */ void net_send_query(int index) { - char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader)]; + /*ok char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader)];*/ + char packet[MAXPACKET]; struct IPHeader *ip; struct ICMPHeader *icmp; - int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader); + + /*ok int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + datasize;*/ int rv; static int first=1; + if ( packetsize < MINPACKET ) packetsize = MINPACKET; + if ( packetsize > MAXPACKET ) packetsize = MAXPACKET; memset(packet, 0, packetsize); ip = (struct IPHeader *)packet; @@ -215,7 +224,7 @@ void net_send_query(int index) { time. */ void net_process_ping(int seq, uint32 addr, struct timeval now) { int index; - int totmsec; + int totusec; if(seq < 0 || seq >= MaxSequence) return; @@ -226,28 +235,28 @@ void net_process_ping(int seq, uint32 addr, struct timeval now) { index = sequence[seq].index; - totmsec = (now.tv_sec - sequence[seq].time.tv_sec) * 1000 + - ((now.tv_usec/1000) - (sequence[seq].time.tv_usec/1000)); + totusec = (now.tv_sec - sequence[seq].time.tv_sec ) * 1000000 + + (now.tv_usec - sequence[seq].time.tv_usec); 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; + host[index].best = host[index].worst = totusec; } - host[index].last = totmsec; - if(totmsec < host[index].best) - host[index].best = totmsec; - if(totmsec > host[index].worst) - host[index].worst = totmsec; + host[index].last = totusec; + if(totusec < host[index].best) + host[index].best = totusec; + if(totusec > host[index].worst) + host[index].worst = totusec; - host[index].total += totmsec; + host[index].total += totusec; host[index].returned++; host[index].transit = 0; - net_save_return(index, sequence[seq].saved_seq, totmsec); - display_rawping(index, totmsec); + net_save_return(index, sequence[seq].saved_seq, totusec); + display_rawping(index, totusec); } /* We know a packet has come in, because the main select loop has called us, diff --git a/net.h b/net.h index 2038ab4..041e22d 100644 --- a/net.h +++ b/net.h @@ -51,3 +51,6 @@ int net_duplicate(int at, int seq); #define MaxHost 256 #define MaxSequence 65536 + +#define MAXPACKET 4096 +#define MINPACKET 64 diff --git a/report.c b/report.c index 9f2fe3c..b6953a9 100644 --- a/report.c +++ b/report.c @@ -65,7 +65,7 @@ void report_close() { printf("%-40s%5d%%%6d%5d%6d%6d%6d\n", name, net_percent(at), net_returned(at), net_xmit(at), - net_best(at), net_avg(at), net_worst(at)); + net_best(at)/1000, net_avg(at)/1000, net_worst(at)/1000); } } diff --git a/split.c b/split.c index 5f685f9..97fe5ae 100644 --- a/split.c +++ b/split.c @@ -34,6 +34,13 @@ #include +#ifdef NO_CURSES +#include +#include +#include +#else +/* Use the curses variant */ + #if defined(HAVE_NCURSES_H) # include #elif defined(HAVE_NCURSES_CURSES_H) @@ -44,6 +51,7 @@ # error No curses header file available #endif +#endif extern char *Hostname; @@ -93,16 +101,18 @@ split_redraw() { if(name != NULL) { /* May be we should test name's length */ sprintf(newLine, "%s %d %d %d %d %d %d", name, - net_percent(at), - net_returned(at), net_xmit(at), - net_best(at), net_avg(at), net_worst(at)); + net_percent(at), + net_returned(at), net_xmit(at), + net_best(at) /1000, net_avg(at)/1000, + net_worst(at)/1000); } else { sprintf(newLine, "%d.%d.%d.%d %d %d %d %d %d %d", - (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff, - net_percent(at), - net_returned(at), net_xmit(at), - net_best(at), net_avg(at), net_worst(at)); + (addr >> 24) & 0xff, (addr >> 16) & 0xff, + (addr >> 8) & 0xff, addr & 0xff, + net_percent(at), + net_returned(at), net_xmit(at), + net_best(at) /1000, net_avg(at)/1000, + net_worst(at)/1000); } } else { sprintf(newLine, "???"); @@ -145,7 +155,23 @@ split_close() { int split_keyaction() { +#ifdef NO_CURSES + fd_set readfds; + struct timeval tv; + char c; + + FD_ZERO (&readfds); + FD_SET (0, &readfds); + tv.tv_sec = 0; + tv.tv_usec = 0; + + if (select (1, &readfds, NULL, NULL, &tv) > 0) { + read (0, &c, 1); + } else + return 0; +#else char c = getch(); +#endif #if DEBUG printf("split_keyaction()\n");