- Added "-n" flag for numeric output.
- Fixed IP numbers displaying backwards.
- GTK mainloop now runs at 10 packets per second.
-- That's too much if there are only 3 hosts
-- that's too little if there are 20 hosts.
-- Someone tell me how to change the "ping-timeout" callback time in
gtk. Can't find it in the docs.
- The default for "hostname" is now "localhost" so that you can start
mtr without any arguments and later fill in the host you want to
trace to.
source: ftp://ftp.bitwizard.nl/mtr/mtr-0.26.tar.gz
Thanks to everyone who has provided feedback on mtr.
- Thanks especially to those of you who have sent me code:
+ Thanks especially to those of you who have sent code:
Brian Casey, Mircea Damian, Christophe Kalt, Simon Kirby,
- Anand Kumria, Charles Levert, Russell Nelson,
- Aaron Scarisbrick, Andrew Stesin, Juha Takala, Rogier Wolff
+ 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.
WHAT'S NEW?
+ v0.26
+ Added "-n" flag for numeric output.
+ fixed IP numbers displaying backwards.
+ GTK mainloop now runs at 10 packets per second.
+ - That's too much if there are only 3 hosts
+ - that's too little if there are 20 hosts.
+ -> Someone tell me how to change the "ping-timeout"
+ callback time in gtk. Can't find it in the docs.
+ The default for "hostname" is now "localhost" so that
+ you can start mtr without any arguments and later
+ fill in the host you want to trace to.
v0.25
Included two "raw" formats. One for separating GUI from
- Stuff to implement:
- Allow mtr to log the return packets, for later analysis.
+ Done: 0.25 . Todo: allow the userinterface(s) to work while
+ still logging to a file.
- Request timestamping at the remote site.
Andreas Fasbender has an algorithm that will allow us to
AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.25)
+AM_INIT_AUTOMAKE(mtr, 0.26)
AC_SUBST(GTK_OBJ)
AC_SUBST(CURSES_OBJ)
/* Hmm, it seems Irix requires this */
extern int errno;
+/* Defined in mtr.c */
+extern int dns;
+
/* Defines */
#undef Debug
char *strlongip(ip_t ip){
struct in_addr a;
- a.s_addr = ip;
+ a.s_addr = htonl(ip);
return inet_ntoa(a);
}
char *dns_lookup(ip_t ip){
char *t;
+ if (!dns) return strlongip (ip);
t = dns_lookup2 (ip);
return t?t:strlongip(ip);
}
char *dns_lookup(int address);
char *dns_lookup2(int address);
int dns_forward(char *name);
+char *strlongip (int address);
/*
mtr -- a network diagnostic tool
Copyright (C) 1997,1998 Matt Kimball
+ Changes/additions Copyright (C) 1998 R.E.Wolff@BitWizard.nl
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
*/
#include <config.h>
+#include <sys/time.h>
#ifndef NO_GTK
#include <stdlib.h>
extern char *Hostname;
extern float WaitTime;
+extern float DeltaTime;
void gtk_do_init(int *argc, char ***argv) {
static int done = 0;
if(addr != 0) {
name = dns_lookup(addr);
if(!name) {
- sprintf(str, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
- (addr >> 8) & 0xff, addr & 0xff);
- name = str;
+ /* Actually this is not neccesary:
+ dns_lookup always returns a printable string */
+ name = strlongip (addr);
}
}
GtkWidget *Toolbar;
GtkWidget *List;
- gtk_window_set_title(GTK_WINDOW(Window), "Matt's traceroute [v" VERSION "]");
+ gtk_window_set_title(GTK_WINDOW(Window), "My traceroute [v" VERSION "]");
gtk_widget_set_usize(Window, 540, 400);
gtk_container_border_width(GTK_CONTAINER(Window), 10);
VBox = gtk_vbox_new(FALSE, 10);
gint gtk_ping(gpointer data) {
gtk_redraw();
net_send_batch();
-
return TRUE;
}
gtk_redraw();
}
+
void gtk_loop() {
- gtk_timeout_add((int)(1000.0 * WaitTime), gtk_ping, NULL);
+ DeltaTime = WaitTime/10;
+ gtk_timeout_add(DeltaTime*1000, gtk_ping, NULL);
gdk_input_add(net_waitfd(), GDK_INPUT_READ, gtk_net_data, NULL);
gdk_input_add(dns_waitfd(), GDK_INPUT_READ, gtk_dns_data, NULL);
.B \-\-raw\c
]
[\c
+.B \-\-no-dns\c
+]
+[\c
.B \-\-gtk\c
]
[\c
to use the curses based terminal
interface (if available).
+.TP
+.B \-n
+.TP
+.B \-\-no-dns
+.br
+Use this option to force
+.B mtr
+to display numeric IP numbers and not try to resolve the
+host names.
+
.TP
.B \-g
.TP
int MaxPing = 16;
float WaitTime = 1.0;
char *Hostname = NULL;
+int dns = 1;
void parse_arg(int argc, char **argv) {
int opt;
{ "curses", 0, 0, 't' },
{ "gtk", 0, 0, 'g' },
{ "interval", 1, 0, 'i' },
+ { "no-dns", 0, 0, 'n' },
{ "split", 0, 0, 's' }, /* BL */
{ "raw", 0, 0, 'l' },
{ 0, 0, 0, 0 }
opt = 0;
while(1) {
- opt = getopt_long(argc, argv, "hvrc:tklsi:", long_options, NULL);
+ opt = getopt_long(argc, argv, "hvrc:tklnsi:", long_options, NULL);
if(opt == -1)
break;
case 'l':
DisplayMode = DisplayRaw;
break;
+ case 'n':
+ dns = 0;
+ break;
case 'i':
WaitTime = atof(optarg);
if (WaitTime <= 0.0) {
fprintf (stderr, "mtr: wait time must be positive\n");
- exit (-1);
+ exit (1);
}
break;
}
int main(int argc, char **argv) {
int traddr;
struct hostent *host;
+ int net_preopen_result;
/* Get the raw sockets first thing, so we can drop to user euid immediately */
- if(net_preopen() != 0) {
- printf("mtr: Unable to get raw socket. (Executable not suid?)\n");
- exit(0);
- }
+
+ net_preopen_result = net_preopen ();
/* Now drop to user permissions */
if(seteuid(getuid())) {
printf("mtr: Unable to drop permissions.\n");
- exit(0);
+ exit(1);
}
/* Double check, just in case */
if(geteuid() != getuid()) {
printf("mtr: Unable to drop permissions.\n");
- exit(0);
+ exit(1);
}
display_detect(&argc, &argv);
exit(0);
}
- if(Hostname == NULL || PrintHelp) {
+ if(PrintHelp) {
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);
}
+ if (Hostname == NULL) Hostname = "localhost";
+
+ if(net_preopen_result != 0) {
+ printf("mtr: Unable to get raw socket. (Executable not suid?)\n");
+ exit(1);
+ }
+
host = gethostbyname(Hostname);
if(host == NULL) {
#else
printf("mtr: error looking up \"%s\"\n", Hostname);
#endif
- exit(0);
+ exit(1);
}
traddr = *(int *)host->h_addr;
if(net_open(traddr) != 0) {
printf("mtr: Unable to get raw socket. (Executable not suid?)\n");
- exit(0);
+ exit(1);
}
display_open();
#include <netinet/in.h>
#include <memory.h>
#include <unistd.h>
+#include <stdio.h>
+#include <math.h>
#include "net.h"
+
+extern float WaitTime, DeltaTime;
+
#define MaxTransit 4
/* We can't rely on header files to provide this information, because
}
-extern float WaitTime;
-extern struct timeval intervaltime;
-#include <stdio.h>
-#include <math.h>
int net_send_batch() {
static int n_unknown = 10;
if ((host[at].addr == remoteaddress.sin_addr.s_addr) ||
(n_unknown == 0)) {
- float wt = WaitTime / (float) at;
-
- intervaltime.tv_sec = (int)(wt);
- intervaltime.tv_usec = 1000000.0 * (wt - floor(wt));
+ DeltaTime = WaitTime / (float) (at+1);
at = 0;
n_unknown = 10;
return 1;
int trueopt = 1;
sendsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- if(sendsock == -1)
+ if(sendsock < 0)
return -1;
#ifdef IP_HDRINCL
#endif
recvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- if(recvsock == -1)
- return -1;
+ if(recvsock < 0)
+ return -1;
return 0;
}
remoteaddress.sin_family = AF_INET;
remoteaddress.sin_addr.s_addr = addr;
+ net_reset ();
net_send_batch();
}
extern int Interactive;
extern int MaxPing;
extern float WaitTime;
+float DeltaTime;
double dnsinterval;
-struct timeval intervaltime;
+static struct timeval intervaltime;
void select_loop() {
fd_set readfd;
NumPing = 0;
anyset = 0;
gettimeofday(&lasttime, NULL);
- wt = WaitTime/10;
- intervaltime.tv_sec = (int)wt;
- intervaltime.tv_usec = 1000000.0 * (wt - floor(wt));
+ DeltaTime = WaitTime/10;
while(1) {
+ intervaltime.tv_sec = DeltaTime;
+ intervaltime.tv_usec = 1000000 *( DeltaTime - floor (DeltaTime));
+
FD_ZERO(&readfd);
maxfd = 0;