--- /dev/null
+
+The "split" format is for a separating the gui from the main program.
+The main program can be installed setuid, and you don't want to link a
+gui-library with a setuid program.
+
+
+The split format is:
+
+<pos> <host> <loss%> <rcvd pckts> <sent pckts> <best> <avg> <worst>
+
+
+The "raw" format is:
+
+hostline|pingline|dnsline|timestampline
+
+hostline:
+h <pos> <host IP>
+
+pingline:
+p <pos> <pingtime (ms)>
+
+dnsline:
+d <pos> <hostname>
+
+timestampline:
+t <pos> <pingtime> <timestamp>
+
+
+Timestampline is not yet implemented. Need to find out how to do
+ICMP timestamping first. :-)
+
mtr_SOURCES = mtr.c \
net.c net.h \
dns.c dns.h \
+ raw.c raw.h \
+ split.c split.h \
display.c display.h \
report.c report.h \
getopt.c getopt1.c getopt.h \
WHAT'S NEW?
+
+ v0.25
+ Included two "raw" formats. One for separating GUI from
+ the setuid program, and one suitable for later parsing and
+ displaying. Volunteers wanted to separate the GTK
+ backend. Thanks to Bertrand Leconte for contributing
+ the format that's now called "split".
+
+ v0.24
+ Fixed number of probes. Accidentally was counted per
+ packet sent instead of per round of packets.
+
+ v0.23
+ Fixed Sparc alignment problem with statmalloc
+
v0.22
Roger has take over maintenance.
mtr now uses an "int" to pass options to the kernel.
SECURITY ISSUES RELATED TO MTR
+You can limit mtr usage to the root user by not putting a setuid bit
+on the mtr binary. In that case, the security implications are
+minimal.
+
+Or you can make mtr setuid-root, and the following applies to you....
+
Since mtr is installed as suid-root, some concern over security is
justified. Since version 0.21 of mtr, does the following two things
after it is launched:
- 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
+ slowly (relative to the RTT time to the end host), it can probe
+ all hosts in the first "round".
+
- Bugs to fix?
- ?
AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.24)
+AM_INIT_AUTOMAKE(mtr, 0.25)
AC_SUBST(GTK_OBJ)
AC_SUBST(CURSES_OBJ)
extern int DisplayMode;
+#ifdef NO_CURSES
+#define mtr_curses_open()
+#define mtr_curses_close()
+#define mtr_curses_redraw()
+#define mtr_curses_keyaction()
+#endif
+
+#ifdef NO_GTK
+#define gtk_open()
+#define gtk_close()
+#define gtk_redraw()
+#define gtk_keyaction()
+#define gtk_loop()
+#endif
+
void display_detect(int *argc, char ***argv) {
DisplayMode = DisplayReport;
report_open();
break;
-#ifndef NO_CURSES
case DisplayCurses:
mtr_curses_open();
break;
-#endif
-#ifndef NO_GTK
+ case DisplaySplit: /* BL */
+ split_open();
+ break;
+
case DisplayGTK:
gtk_open();
break;
-#endif
}
}
report_close();
break;
-#ifndef NO_CURSES
case DisplayCurses:
mtr_curses_close();
break;
-#endif
-#ifndef NO_GTK
+ case DisplaySplit: /* BL */
+ split_close();
+ break;
+
case DisplayGTK:
gtk_close();
break;
-#endif
}
}
void display_redraw() {
switch(DisplayMode) {
-#ifndef NO_CURSES
+
case DisplayCurses:
mtr_curses_redraw();
break;
-#endif
-#ifndef NO_GTK
+ case DisplaySplit: /* BL */
+ split_redraw();
+ break;
+
case DisplayGTK:
gtk_redraw();
break;
-#endif
}
}
int display_keyaction() {
switch(DisplayMode) {
-#ifndef NO_CURSES
case DisplayCurses:
return mtr_curses_keyaction();
-#endif
-#ifndef NO_GTK
+ case DisplaySplit: /* BL */
+ return split_keyaction();
+
case DisplayGTK:
return gtk_keyaction();
-#endif
}
return 0;
}
+
+void display_rawping(int host, int msec) {
+ switch(DisplayMode) {
+ case DisplayReport:
+ case DisplaySplit: /* BL */
+ case DisplayCurses:
+ case DisplayGTK:
+ break;
+ case DisplayRaw:
+ raw_rawping (host, msec);
+ break;
+ }
+}
+
+
+void display_rawhost(int host, int ip_addr) {
+ switch(DisplayMode) {
+ case DisplayReport:
+ case DisplaySplit: /* BL */
+ case DisplayCurses:
+ case DisplayGTK:
+ break;
+ case DisplayRaw:
+ raw_rawhost (host, ip_addr);
+ break;
+ }
+}
+
+
void display_loop() {
switch(DisplayMode) {
case DisplayCurses:
case DisplayReport:
+ case DisplaySplit: /* BL */
+ case DisplayRaw:
select_loop();
break;
-#ifndef NO_GTK
case DisplayGTK:
gtk_loop();
break;
-#endif
}
}
*/
enum { ActionNone, ActionQuit, ActionReset };
-enum { DisplayReport, DisplayCurses, DisplayGTK };
+enum { DisplayReport, DisplayCurses, DisplayGTK, DisplaySplit, DisplayRaw };
/* Prototypes for display.c */
void display_detect(int *argc, char ***argv);
void display_open();
void display_close();
void display_redraw();
+void display_rawping(int hostnum, int msec);
+void display_rawhost(int hostnum, int ip_addr);
int display_keyaction();
void display_loop();
(void)istime(expireresolves->expiretime,sinterval);
}
-char *dns_lookup(ip_t ip){
+char *dns_lookup2(ip_t ip){
struct resolve *rp;
ip = htonl(ip);
if ((rp = findip(ip))){
strlongip(ip));
restell(tempstring);
}
- return strlongip(ip);
+ return NULL;
}
}
- return strlongip(ip);
+ return NULL;
}
if (debug)
fprintf(stderr,"Resolver: Added to new record.\n");
rp->ip = ip;
linkresolveip(rp);
sendrequest(rp,T_PTR);
- return strlongip(ip);
+ return NULL;
+}
+
+
+char *dns_lookup(ip_t ip){
+ char *t;
+
+ t = dns_lookup2 (ip);
+ return t?t:strlongip(ip);
}
void dns_ack();
void dns_events(double *sinterval);
char *dns_lookup(int address);
+char *dns_lookup2(int address);
int dns_forward(char *name);
.B \-\-curses\c
]
[\c
+.B \-\-split\c
+]
+[\c
+.B \-\-raw\c
+]
+[\c
.B \-\-gtk\c
]
[\c
.B http://www.gimp.org/gtk/
for more information about GTK+.
+.TP
+.B \-s
+.TP
+.B \-\-split
+.br
+Use this option to set
+.B mtr
+to spit out a format that is suitable for a split-user interface.
+
+.TP
+.B \-l
+.TP
+.B \-\-raw
+.br
+Use this option to tell
+.B mtr
+to use the raw output format. This format is better suited for
+archival of the measurement results. It could be parsed to
+be presented into any of the other display methods.
+
.TP
.B \-i\ SECONDS
.TP
{ "curses", 0, 0, 't' },
{ "gtk", 0, 0, 'g' },
{ "interval", 1, 0, 'i' },
+ { "split", 0, 0, 's' }, /* BL */
+ { "raw", 0, 0, 'l' },
{ 0, 0, 0, 0 }
};
opt = 0;
while(1) {
- opt = getopt_long(argc, argv, "hvrc:tli:", long_options, NULL);
+ opt = getopt_long(argc, argv, "hvrc:tklsi:", long_options, NULL);
if(opt == -1)
break;
case 'g':
DisplayMode = DisplayGTK;
break;
+ case 's': /* BL */
+ DisplayMode = DisplaySplit;
+ break;
+ case 'l':
+ DisplayMode = DisplayRaw;
+ break;
case 'i':
WaitTime = atof(optarg);
if (WaitTime <= 0.0) {
}
if(Hostname == NULL || PrintHelp) {
- printf("usage: %s [-hvrctli] [--help] [--version] [--report]\n"
+ printf("usage: %s [-hvrctlis] [--help] [--version] [--report]\n"
"\t\t[--report-cycles=COUNT] [--curses] [--gtk]\n"
+ "\t\t[--raw] [--split]\n" /* BL */
"\t\t[--interval=SECONDS] HOSTNAME\n", argv[0]);
exit(0);
}
#include "net.h"
-#define MaxHost 256
#define MaxTransit 4
/* We can't rely on header files to provide this information, because
int at;
struct timeval now;
int totmsec;
- int msec;
if(data->index >= 0) {
gettimeofday(&now, NULL);
/* discard this data point, stats were reset after it was generated */
return;
- totmsec = (now.tv_sec - data->sec) * 1000;
- msec = now.tv_usec / 1000 - data->msec;
- if(msec >= 0)
- totmsec += msec;
- else
- totmsec = totmsec - 1000 + 1000 - data->msec + now.tv_usec / 1000;
+ totmsec = (now.tv_sec - data->sec) * 1000 +
+ ((now.tv_usec/1000) - data->msec);
if(host[data->index].returned <= 0) {
host[data->index].best = host[data->index].worst = totmsec;
if(totmsec > host[data->index].worst)
host[data->index].worst = totmsec;
+ display_rawping (data->index, totmsec);
+
host[data->index].total += totmsec;
host[data->index].returned++;
host[data->index].transit = 0;
return;
host[at].addr = addr->sin_addr.s_addr;
+ display_rawhost (at, host[at].addr);
}
}
return;
host[at].addr = fromaddr.sin_addr.s_addr;
+ display_rawhost (at, net_addr(at));
}
}
int net_transit(int at);
+#define MaxHost 256
--- /dev/null
+/*
+ mtr -- a network diagnostic tool
+ Copyright (C) 1998 R.E.Wolff@BitWizard.nl
+
+ raw.c -- raw output (for logging for later analysis)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+*/
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+#include "raw.h"
+#include "net.h"
+#include "dns.h"
+
+static int havename[MaxHost];
+
+static char *addr_to_str(int addr)
+{
+ static char buf[20];
+
+ sprintf (buf, "%d.%d.%d.%d",
+ (addr >> 0) & 0xff,
+ (addr >> 8) & 0xff,
+ (addr >> 16) & 0xff,
+ (addr >> 24) & 0xff);
+ return buf;
+}
+
+
+void raw_rawping (int host, int msec)
+{
+ char *name;
+
+ if (!havename[host]) {
+ name = dns_lookup2(net_addr(host));
+ if (name) {
+ havename[host]++;
+ printf ("d %d %s\n", host, name);
+ }
+ }
+ printf ("p %d %d\n", host, msec);
+}
+
+
+void raw_rawhost (int host, int ip_addr)
+{
+ printf ("h %d %s\n", host, addr_to_str (ip_addr));
+}
+
+
+
+
--- /dev/null
+/*
+ mtr -- a network diagnostic tool
+ Copyright (C) 1998 R.E.Wolff@BitWizard.nl
+
+ raw.h -- raw output (for logging for later analysis)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+*/
+
+/* Prototypes for raw.c */
+void raw_rawping(int host, int msec);
+void raw_rawhost(int host, int addr);
--- /dev/null
+/*
+ mtr -- a network diagnostic tool
+ Copyright (C) 1997 Matt Kimball
+
+ split.c -- raw output (for inclusion in KDE Network Utilities or others
+ GUI based tools)
+ Copyright (C) 1998 Bertrand Leconte <B.Leconte@mail.dotcom.fr>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+*/
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "display.h"
+#include "dns.h"
+/*
+#include "net.h"
+#include "split.h"
+*/
+
+
+extern char *Hostname;
+extern int WaitTime;
+
+/* There is 256 hops max in the IP header (coded with a byte) */
+#define MAX_LINE_COUNT 256
+#define MAX_LINE_SIZE 256
+
+char Lines[MAX_LINE_COUNT][MAX_LINE_SIZE];
+int LineCount;
+
+
+#define DEBUG 0
+
+void
+split_redraw() {
+ int max;
+ int at;
+ int addr;
+ char *name;
+ char newLine[MAX_LINE_SIZE];
+ int i;
+
+#if DEBUG
+ fprintf(stderr, "split_redraw()\n");
+#endif
+
+ /*
+ * If there is less lines than last time, we delete them
+ * TEST THIS PLEASE
+ */
+ max = net_max();
+ for (i=LineCount; i>max; i--) {
+ printf("-%d\n", i);
+ LineCount--;
+ }
+
+ /*
+ * For each line, we compute the new one and we compare it to the old one
+ */
+ for(at = 0; at < max; at++) {
+ addr = net_addr(at);
+
+ if(addr != 0) {
+ name = dns_lookup(addr);
+ 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));
+ } 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));
+ }
+ } else {
+ sprintf(newLine, "???");
+ }
+
+ if (strcmp(newLine, Lines[at]) == 0) {
+ /* The same, so do nothing */
+#if DEBUG
+ printf("SAME LINE\n");
+#endif
+ } else {
+ printf("%d %s\n", at+1, newLine);
+ fflush(stdout);
+ strcpy(Lines[at], newLine);
+ if (LineCount < (at+1)) {
+ LineCount = at+1;
+ }
+ }
+ }
+}
+
+void
+split_open() {
+ int i;
+#if DEBUG
+ printf("split_open()\n");
+#endif
+ LineCount = -1;
+ for (i=0; i<MAX_LINE_COUNT; i++) {
+ strcpy(Lines[i], "???");
+ }
+}
+
+void
+split_close() {
+#if DEBUG
+ printf("split_close()\n");
+#endif
+}
+
+int
+split_keyaction() {
+ char c = getch();
+
+#if DEBUG
+ printf("split_keyaction()\n");
+#endif
+ if(tolower(c) == 'q')
+ return ActionQuit;
+ if(c==3)
+ return ActionQuit;
+ if(tolower(c) == 'r')
+ return ActionReset;
+
+ return 0;
+}
--- /dev/null
+/*
+ mtr -- a network diagnostic tool
+
+ split.h -- raw output (for inclusion in KDE Network Utilities)
+ Copyright (C) 1998 Bertrand Leconte <B.Leconte@mail.dotcom.fr>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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.
+*/
+
+/* Prototypes for split.c */
+void split_open();
+void split_close();
+void split_redraw();
+int split_keyaction();