mtr 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".

source: ftp://ftp.bitwizard.nl/mtr/mtr-0.25.tar.gz
This commit is contained in:
Roger Wolff 1998-10-28 00:00:00 +00:00 committed by Travis Cross
parent 4778673ae5
commit 4a16a7a858
18 changed files with 452 additions and 34 deletions

31
FORMATS Normal file
View File

@ -0,0 +1,31 @@
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. :-)

View File

@ -8,6 +8,8 @@ install-exec-am:
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 \

15
NEWS
View File

@ -1,5 +1,20 @@
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.

View File

@ -1,5 +1,11 @@
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:

9
TODO
View File

@ -17,6 +17,15 @@
- 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?
- ?

View File

@ -1,5 +1,5 @@
AC_INIT(mtr.c)
AM_INIT_AUTOMAKE(mtr, 0.24)
AM_INIT_AUTOMAKE(mtr, 0.25)
AC_SUBST(GTK_OBJ)
AC_SUBST(CURSES_OBJ)

View File

@ -26,6 +26,21 @@
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;
@ -46,17 +61,17 @@ void display_open() {
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
}
}
@ -66,63 +81,92 @@ void display_close() {
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
}
}

View File

@ -18,12 +18,14 @@
*/
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();

16
dns.c
View File

@ -1134,7 +1134,7 @@ void dns_events(double *sinterval){
(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))){
@ -1152,10 +1152,10 @@ char *dns_lookup(ip_t 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");
@ -1167,5 +1167,13 @@ char *dns_lookup(ip_t ip){
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);
}

1
dns.h
View File

@ -24,4 +24,5 @@ int dns_waitfd();
void dns_ack();
void dns_events(double *sinterval);
char *dns_lookup(int address);
char *dns_lookup2(int address);
int dns_forward(char *name);

26
mtr.8
View File

@ -26,6 +26,12 @@ mtr \- a network diagnostic tool
.B \-\-curses\c
]
[\c
.B \-\-split\c
]
[\c
.B \-\-raw\c
]
[\c
.B \-\-gtk\c
]
[\c
@ -131,6 +137,26 @@ was built for this to work. See the GTK+ web page at
.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

13
mtr.c
View File

@ -48,12 +48,14 @@ void parse_arg(int argc, char **argv) {
{ "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;
@ -76,6 +78,12 @@ void parse_arg(int argc, char **argv) {
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) {
@ -127,8 +135,9 @@ int main(int argc, char **argv) {
}
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);
}

14
net.c
View File

@ -32,7 +32,6 @@
#include "net.h"
#define MaxHost 256
#define MaxTransit 4
/* We can't rely on header files to provide this information, because
@ -200,7 +199,6 @@ void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
int at;
struct timeval now;
int totmsec;
int msec;
if(data->index >= 0) {
gettimeofday(&now, NULL);
@ -210,12 +208,8 @@ void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
/* 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;
@ -227,6 +221,8 @@ void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
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;
@ -236,6 +232,7 @@ void net_process_ping(struct packetdata *data, struct sockaddr_in *addr) {
return;
host[at].addr = addr->sin_addr.s_addr;
display_rawhost (at, host[at].addr);
}
}
@ -277,6 +274,7 @@ void net_process_return() {
return;
host[at].addr = fromaddr.sin_addr.s_addr;
display_rawhost (at, net_addr(at));
}
}

1
net.h
View File

@ -41,3 +41,4 @@ int net_xmit(int at);
int net_transit(int at);
#define MaxHost 256

68
raw.c Normal file
View File

@ -0,0 +1,68 @@
/*
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));
}

24
raw.h Normal file
View File

@ -0,0 +1,24 @@
/*
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);

148
split.c Normal file
View File

@ -0,0 +1,148 @@
/*
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;
}

26
split.h Normal file
View File

@ -0,0 +1,26 @@
/*
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();