int ipinfo_max = -1;
static int iihash = 0;
char fmtinfo[32];
-extern int af; /* address family of remote target */
// items width: ASN, Route, Country, Registry, Allocated
int iiwidth[] = { 7, 19, 4, 8, 11}; // item len + space
}
#endif
-static char *get_ipinfo(ip_t *addr) {
+static char *get_ipinfo(struct mtr_ctl *ctl, ip_t *addr){
if (!addr)
return NULL;
char key[NAMELEN];
char lookup_key[NAMELEN];
- if (af == AF_INET6) {
+ if (ctl->af == AF_INET6) {
#ifdef ENABLE_IPV6
reverse_host6(addr, key);
if (snprintf(lookup_key, NAMELEN, "%s.origin6.asn.cymru.com", key) >= NAMELEN)
return (ipinfo_no < iiwidth_len) ? iiwidth[ipinfo_no] : iiwidth[ipinfo_no % iiwidth_len];
}
-extern char *fmt_ipinfo(ip_t *addr) {
- char *ipinfo = get_ipinfo(addr);
+extern char *fmt_ipinfo(struct mtr_ctl *ctl, ip_t *addr){
+ char *ipinfo = get_ipinfo(ctl, addr);
char fmt[8];
snprintf(fmt, sizeof(fmt), "%s%%-%ds", ipinfo_no?"":"AS", get_iiwidth());
snprintf(fmtinfo, sizeof(fmtinfo), fmt, ipinfo?ipinfo:UNKN);
extern int iiwidth_len;
extern void asn_open();
extern void asn_close();
-extern char *fmt_ipinfo(ip_t *addr);
+extern char *fmt_ipinfo(struct mtr_ctl *ctl, ip_t *addr);
extern int get_iiwidth(void);
extern int is_printii(void);
#include <time.h>
-extern char LocalHostname[];
-extern int fstTTL;
-extern int maxTTL;
-extern int cpacketsize;
-extern int bitpattern;
-extern int tos;
-extern float WaitTime;
-extern int af;
-extern int mtrtype;
-
static void pwcenter(char *str)
{
}
-extern int mtr_curses_keyaction(void)
+extern int mtr_curses_keyaction(struct mtr_ctl *ctl)
{
int c = getch();
int i=0;
return ActionScrollUp;
if (tolower(c) == 's') {
- mvprintw(2, 0, "Change Packet Size: %d\n", cpacketsize );
+ mvprintw(2, 0, "Change Packet Size: %d\n", ctl->cpacketsize);
mvprintw(3, 0, "Size Range: %d-%d, < 0:random.\n", MINPACKET, MAXPACKET);
move(2,20);
refresh();
buf[i++] = c; /* need more checking on 'c' */
}
buf[i] = '\0';
- cpacketsize = atoi ( buf );
+ ctl->cpacketsize = atoi ( buf );
return ActionNone;
}
if (tolower(c) == 'b') {
- mvprintw(2, 0, "Ping Bit Pattern: %d\n", bitpattern );
+ mvprintw(2, 0, "Ping Bit Pattern: %d\n", ctl->bitpattern );
mvprintw(3, 0, "Pattern Range: 0(0x00)-255(0xff), <0 random.\n");
move(2,18);
refresh();
buf[i++] = c; /* need more checking on 'c' */
}
buf[i] = '\0';
- bitpattern = atoi ( buf );
- if( bitpattern > 255 ) { bitpattern = -1; }
+ ctl->bitpattern = atoi ( buf );
+ if( ctl->bitpattern > 255 ) { ctl->bitpattern = -1; }
return ActionNone;
}
if ( c == 'Q') { /* can not be tolower(c) */
- mvprintw(2, 0, "Type of Service(tos): %d\n", tos );
+ mvprintw(2, 0, "Type of Service(tos): %d\n", ctl->tos);
mvprintw(3, 0, "default 0x00, min cost 0x02, rel 0x04,, thr 0x08, low del 0x10...\n");
move(2,22);
refresh();
buf[i++] = c; /* need more checking on 'c' */
}
buf[i] = '\0';
- tos = atoi ( buf );
- if( tos > 255 || tos <0 ) {
- tos = 0;
+ ctl->tos = atoi ( buf );
+ if (ctl->tos > 255 || ctl->tos < 0) {
+ ctl->tos = 0;
}
return ActionNone;
}
if (tolower(c) == 'i') {
- mvprintw(2, 0, "Interval : %0.0f\n\n", WaitTime );
+ mvprintw(2, 0, "Interval : %0.0f\n\n", ctl->WaitTime);
move(2,11);
refresh();
while ( (c=getch ()) != '\n' && i < MAXFLD ) {
if (f <= 0.0) return ActionNone;
if (getuid() != 0 && f < 1.0)
return ActionNone;
- WaitTime = f;
+ ctl->WaitTime = f;
return ActionNone;
}
if (tolower(c) == 'f') {
- mvprintw(2, 0, "First TTL: %d\n\n", fstTTL );
+ mvprintw(2, 0, "First TTL: %d\n\n", ctl->fstTTL);
move(2,11);
refresh();
while ( (c=getch ()) != '\n' && i < MAXFLD ) {
buf[i] = '\0';
i = atoi( buf );
- if ( i < 1 || i> maxTTL ) return ActionNone;
- fstTTL = i;
+ if (i < 1 || i > ctl->maxTTL)
+ return ActionNone;
+ ctl->fstTTL = i;
return ActionNone;
}
if (tolower(c) == 'm') {
- mvprintw(2, 0, "Max TTL: %d\n\n", maxTTL );
+ mvprintw(2, 0, "Max TTL: %d\n\n", ctl->maxTTL);
move(2,9);
refresh();
while ( (c=getch ()) != '\n' && i < MAXFLD ) {
buf[i] = '\0';
i = atoi( buf );
- if ( i < fstTTL || i>(MaxHost-1) ) return ActionNone;
- maxTTL = i;
+ if (i < ctl->fstTTL || i > (MaxHost - 1))
+ return ActionNone;
+ ctl->maxTTL = i;
return ActionNone;
}
/* fields to display & their ordering */
if (tolower(c) == 'o') {
- mvprintw(2, 0, "Fields: %s\n\n", fld_active );
+ mvprintw(2, 0, "Fields: %s\n\n", ctl->fld_active );
for( i=0; i<MAXFLD; i++ ){
if( data_fields[i].descr != NULL )
i = 0;
while ( (c=getch ()) != '\n' && i < MAXFLD ) {
- if( strchr(available_options, c) ) {
+ if( strchr(ctl->available_options, c) ) {
attron(A_BOLD); printw("%c", c); attroff(A_BOLD); refresh();
buf[i++] = c; /* Only permit values in "available_options" be entered */
} else {
}
}
buf[i] = '\0';
- if ( strlen( buf ) > 0 ) strcpy( fld_active, buf );
+ if ( strlen( buf ) > 0 ) strcpy( ctl->fld_active, buf );
return ActionNone;
}
if (tolower(c) == 'j') {
- if( strchr(fld_active, 'N') ) {
- strcpy(fld_active, "DR AGJMXI"); /* GeoMean and jitter */
+ if( strchr(ctl->fld_active, 'N') ) {
+ strcpy(ctl->fld_active, "DR AGJMXI"); /* GeoMean and jitter */
} else {
- strcpy(fld_active, "LS NABWV"); /* default */
+ strcpy(ctl->fld_active, "LS NABWV"); /* default */
}
return ActionNone;
}
if (tolower(c) == 'u') {
- switch ( mtrtype ) {
+ switch (ctl->mtrtype) {
case IPPROTO_ICMP:
case IPPROTO_TCP:
- mtrtype = IPPROTO_UDP;
+ ctl->mtrtype = IPPROTO_UDP;
break;
case IPPROTO_UDP:
- mtrtype = IPPROTO_ICMP;
+ ctl->mtrtype = IPPROTO_ICMP;
break;
}
return ActionNone;
}
if (tolower(c) == 't') {
- switch ( mtrtype ) {
+ switch (ctl->mtrtype) {
case IPPROTO_ICMP:
case IPPROTO_UDP:
- mtrtype = IPPROTO_TCP;
+ ctl->mtrtype = IPPROTO_TCP;
break;
case IPPROTO_TCP:
- mtrtype = IPPROTO_ICMP;
+ ctl->mtrtype = IPPROTO_ICMP;
break;
}
return ActionNone;
}
}
-static void mtr_curses_hosts(int startstat)
+static void mtr_curses_hosts(struct mtr_ctl *ctl, int startstat)
{
int max;
int at;
char buf[1024];
int __unused_int UNUSED;
- max = net_max();
+ max = net_max(ctl);
- for(at = net_min () + display_offset; at < max; at++) {
+ for(at = net_min(ctl) + display_offset; at < max; at++) {
printw("%2d. ", at + 1);
addr = net_addr(at);
mpls = net_mpls(at);
- if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
- name = dns_lookup(addr);
+ if( addrcmp( (void *) addr, (void *) &unspec_addr, ctl->af ) != 0 ) {
+ name = dns_lookup(ctl, addr);
if (! net_up(at))
attron(A_BOLD);
#ifdef HAVE_IPINFO
if (is_printii())
- printw(fmt_ipinfo(addr));
+ printw(fmt_ipinfo(ctl, addr));
#endif
if(name != NULL) {
- if (show_ips) printw("%s (%s)", name, strlongip(addr));
+ if (ctl->show_ips) printw("%s (%s)", name, strlongip(ctl, addr));
else printw("%s", name);
} else {
- printw("%s", strlongip( addr ) );
+ printw("%s", strlongip(ctl, addr ) );
}
attroff(A_BOLD);
/* Ignore options that don't exist */
/* On the other hand, we now check the input side. Shouldn't happen,
can't be careful enough. */
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j == -1) continue;
format_field (buf+hd_len, data_fields[j].format, data_fields[j].net_xxx(at));
hd_len += data_fields[j].length;
buf[hd_len] = 0;
printw("%s", buf);
- for (k=0; k < mpls->labels && enablempls; k++) {
+ for (k=0; k < mpls->labels && ctl->enablempls; k++) {
if((k+1 < mpls->labels) || (mpls->labels == 1)) {
/* if we have more labels */
printw("\n [MPLS: Lbl %lu Exp %u S %u TTL %u]", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
for (i=0; i < MAXPATH; i++ ) {
addrs = net_addrs(at, i);
mplss = net_mplss(at, i);
- if ( addrcmp( (void *) addrs, (void *) addr, af ) == 0 ) continue;
- if ( addrcmp( (void *) addrs, (void *) &unspec_addr, af ) == 0 ) break;
+ if ( addrcmp( (void *) addrs, (void *) addr, ctl->af ) == 0 ) continue;
+ if ( addrcmp( (void *) addrs, (void *) &unspec_addr, ctl->af ) == 0 ) break;
- name = dns_lookup(addrs);
+ name = dns_lookup(ctl, addrs);
if (! net_up(at)) attron(A_BOLD);
printw("\n ");
#ifdef HAVE_IPINFO
if (is_printii())
- printw(fmt_ipinfo(addrs));
+ printw(fmt_ipinfo(ctl, addrs));
#endif
if (name != NULL) {
- if (show_ips) printw("%s (%s)", name, strlongip(addrs));
+ if (ctl->show_ips) printw("%s (%s)", name, strlongip(ctl, addrs));
else printw("%s", name);
} else {
- printw("%s", strlongip( addrs ) );
+ printw("%s", strlongip(ctl, addrs ) );
}
- for (k=0; k < mplss->labels && enablempls; k++) {
+ for (k=0; k < mplss->labels && ctl->enablempls; k++) {
printw("\n [MPLS: Lbl %lu Exp %u S %u TTL %u]", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
}
attroff(A_BOLD);
static double factors[NUM_FACTORS];
static int scale[NUM_FACTORS];
-static void mtr_gen_scale(void)
+static void mtr_gen_scale(struct mtr_ctl *ctl)
{
int *saved, i, max, at;
int range;
for (i = 0; i < NUM_FACTORS; i++) {
scale[i] = 0;
}
- max = net_max();
+ max = net_max(ctl);
for (at = display_offset; at < max; at++) {
saved = net_saved_pings(at);
for (i = 0; i < SAVED_PINGS; i++) {
}
-static void mtr_fill_graph(int at, int cols)
+static void mtr_fill_graph(struct mtr_ctl *ctl, int at, int cols)
{
int* saved;
int i;
printw("%c", '?');
attrset(A_NORMAL);
} else {
- if (display_mode == DisplayModeBlockmap) {
+ if (ctl->display_mode == DisplayModeBlockmap) {
if (saved[i] > scale[6]) {
printw("%c", block_map[NUM_FACTORS-1]);
} else {
}
-static void mtr_curses_graph(int startstat, int cols)
+static void mtr_curses_graph(struct mtr_ctl *ctl, int startstat, int cols)
{
int max, at, y;
ip_t * addr;
char* name;
int __unused_int UNUSED;
- max = net_max();
+ max = net_max(ctl);
for (at = display_offset; at < max; at++) {
printw("%2d. ", at+1);
if (! net_up(at))
attron(A_BOLD);
- if (addrcmp((void *) addr, (void *) &unspec_addr, af)) {
+ if (addrcmp((void *) addr, (void *) &unspec_addr, ctl->af)) {
#ifdef HAVE_IPINFO
if (is_printii())
- printw(fmt_ipinfo(addr));
+ printw(fmt_ipinfo(ctl, addr));
#endif
- name = dns_lookup(addr);
- printw("%s", name?name:strlongip(addr));
+ name = dns_lookup(ctl, addr);
+ printw("%s", name?name:strlongip(ctl, addr));
} else
printw("???");
attroff(A_BOLD);
move(y, startstat);
printw(" ");
- mtr_fill_graph(at, cols);
+ mtr_fill_graph(ctl, at, cols);
printw("\n");
}
}
-extern void mtr_curses_redraw(void)
+extern void mtr_curses_redraw(struct mtr_ctl *ctl)
{
int maxx;
int startstat;
pwcenter("My traceroute [v" PACKAGE_VERSION "]");
attroff(A_BOLD);
- mvprintw(1, 0, "%s (%s)", LocalHostname, net_localaddr());
+ mvprintw(1, 0, "%s (%s)", ctl->LocalHostname, net_localaddr());
/*
printw("(tos=0x%X ", tos);
printw("psize=%d ", packetsize );
- printw("bitpattern=0x%02X)", (unsigned char)(abs(bitpattern)));
+ printw("bitpattern=0x%02X)", (unsigned char)(abs(ctl->bitpattern)));
if( cpacketsize > 0 ){
printw("psize=%d ", cpacketsize);
} else {
printw("psize=rand(%d,%d) ",MINPACKET, -cpacketsize);
}
- if( bitpattern>=0 ){
- printw("bitpattern=0x%02X)", (unsigned char)(bitpattern));
+ if( ctl->bitpattern>=0 ){
+ printw("bitpattern=0x%02X)", (unsigned char)(ctl->bitpattern));
} else {
printw("bitpattern=rand(0x00-FF))");
}
attron(A_BOLD); printw("O"); attroff(A_BOLD); printw("rder of fields ");
attron(A_BOLD); printw("q"); attroff(A_BOLD); printw("uit\n");
- if (display_mode == DisplayModeDefault) {
+ if (ctl->display_mode == DisplayModeDefault) {
for (i=0; i < MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j < 0) continue;
sprintf( fmt, "%%%ds", data_fields[j].length );
attroff(A_BOLD);
move(rowstat, 0);
- mtr_curses_hosts(maxx-hd_len-1);
+ mtr_curses_hosts(ctl, maxx-hd_len-1);
} else {
char msg[80];
attroff(A_BOLD);
move(rowstat, 0);
- mtr_gen_scale();
- mtr_curses_graph(startstat, max_cols);
+ mtr_gen_scale(ctl);
+ mtr_curses_graph(ctl, startstat, max_cols);
printw("\n");
attron(A_BOLD);
}
-extern void mtr_curses_open(void)
+extern void mtr_curses_open(struct mtr_ctl *ctl)
{
initscr();
raw();
init_pair(i+1, i, bg_col);
mtr_curses_init();
- mtr_curses_redraw();
+ mtr_curses_redraw(ctl);
}
}
-extern void mtr_curses_clear(void)
+extern void mtr_curses_clear(struct mtr_ctl *ctl)
{
mtr_curses_close();
- mtr_curses_open();
+ mtr_curses_open(ctl);
}
#include "dns.h"
#include "asn.h"
-extern int DisplayMode;
-
#ifdef HAVE_NCURSES
#include "mtr-curses.h"
#endif
#define UNUSED_IF_NO_GTK UNUSED
#endif
-extern void display_detect(int *argc UNUSED_IF_NO_GTK, char ***argv UNUSED_IF_NO_GTK)
+extern void display_detect(struct mtr_ctl *ctl, int *argc UNUSED_IF_NO_GTK,
+ char ***argv UNUSED_IF_NO_GTK)
{
- DisplayMode = DEFAULT_DISPLAY;
+ ctl->DisplayMode = DEFAULT_DISPLAY;
#ifdef HAVE_GTK
if(gtk_detect(argc, argv)) {
- DisplayMode = DisplayGTK;
+ ctl->DisplayMode = DisplayGTK;
}
#endif
}
-extern void display_open(void)
+extern void display_open(struct mtr_ctl *ctl)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
case DisplayReport:
report_open();
break;
#ifdef HAVE_NCURSES
case DisplayCurses:
- mtr_curses_open();
+ mtr_curses_open(ctl);
#ifdef HAVE_IPINFO
asn_open();
#endif
break;
#ifdef HAVE_GTK
case DisplayGTK:
- gtk_open();
+ gtk_open(ctl);
#ifdef HAVE_IPINFO
asn_open();
#endif
}
-extern void display_close(time_t now)
+extern void display_close(struct mtr_ctl *ctl, time_t now)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
case DisplayReport:
- report_close();
+ report_close(ctl);
break;
case DisplayTXT:
- txt_close();
+ txt_close(ctl);
break;
case DisplayJSON:
- json_close();
+ json_close(ctl);
break;
case DisplayXML:
- xml_close();
+ xml_close(ctl);
break;
case DisplayCSV:
- csv_close(now);
+ csv_close(ctl, now);
break;
#ifdef HAVE_NCURSES
case DisplayCurses:
}
-extern void display_redraw(void)
+extern void display_redraw(struct mtr_ctl *ctl)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
#ifdef HAVE_NCURSES
case DisplayCurses:
- mtr_curses_redraw();
+ mtr_curses_redraw(ctl);
break;
#endif
case DisplaySplit:
- split_redraw();
+ split_redraw(ctl);
break;
#ifdef HAVE_GTK
case DisplayGTK:
- gtk_redraw();
+ gtk_redraw(ctl);
break;
#endif
}
}
-extern int display_keyaction(void)
+extern int display_keyaction(struct mtr_ctl *ctl)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
#ifdef HAVE_NCURSES
case DisplayCurses:
- return mtr_curses_keyaction();
+ return mtr_curses_keyaction(ctl);
#endif
case DisplaySplit:
}
-extern void display_rawxmit(int host, int seq)
+extern void display_rawxmit(struct mtr_ctl *ctl, int host, int seq)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
case DisplayRaw:
raw_rawxmit (host, seq);
break;
}
-extern void display_rawping(int host, int msec, int seq)
+extern void display_rawping(struct mtr_ctl *ctl, int host, int msec, int seq)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
case DisplayReport:
case DisplayTXT:
case DisplayJSON:
#endif
break;
case DisplayRaw:
- raw_rawping (host, msec, seq);
+ raw_rawping (ctl, host, msec, seq);
break;
}
}
-extern void display_rawhost(int host, ip_t *ip_addr)
+extern void display_rawhost(struct mtr_ctl *ctl, int host, ip_t *ip_addr)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
case DisplayReport:
case DisplayTXT:
case DisplayJSON:
#endif
break;
case DisplayRaw:
- raw_rawhost (host, ip_addr);
+ raw_rawhost (ctl, host, ip_addr);
break;
}
}
-extern void display_loop(void)
+extern void display_loop(struct mtr_ctl *ctl)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
case DisplayReport:
case DisplayTXT:
case DisplayJSON:
case DisplayCurses:
#endif
case DisplayRaw:
- select_loop();
+ select_loop(ctl);
break;
#ifdef HAVE_GTK
case DisplayGTK:
- gtk_loop();
+ gtk_loop(ctl);
break;
#endif
}
}
-extern void display_clear(void)
+extern void display_clear(struct mtr_ctl *ctl)
{
- switch(DisplayMode) {
+ switch(ctl->DisplayMode) {
#ifdef HAVE_NCURSES
case DisplayCurses:
- mtr_curses_clear();
+ mtr_curses_clear(ctl);
break;
#endif
case DisplayReport:
};
/* Prototypes for display.c */
-extern void display_detect(int *argc, char ***argv);
-extern void display_open(void);
-extern void display_close(time_t now);
-extern void display_redraw(void);
-extern void display_rawxmit(int hostnum, int seq);
-extern void display_rawping(int hostnum, int msec, int seq);
-extern void display_rawhost(int hostnum, ip_t *ip_addr);
-extern int display_keyaction(void);
-extern void display_loop(void);
-extern void display_clear(void);
+extern void display_detect(struct mtr_ctl *ctl, int *argc, char ***argv);
+extern void display_open(struct mtr_ctl *ctl);
+extern void display_close(struct mtr_ctl *ctl, time_t now);
+extern void display_redraw(struct mtr_ctl *ctl);
+extern void display_rawxmit(struct mtr_ctl *ctl, int hostnum, int seq);
+extern void display_rawping(struct mtr_ctl *ctl, int hostnum, int msec, int seq);
+extern void display_rawhost(struct mtr_ctl *ctl, int hostnum, ip_t *ip_addr);
+extern int display_keyaction(struct mtr_ctl *ctl);
+extern void display_loop(struct mtr_ctl *ctl);
+extern void display_clear(struct mtr_ctl *ctl);
-extern int display_mode;
extern int display_offset; /* only used in text mode */
#include "dns.h"
#include "net.h"
-extern int af;
-
-
-int use_dns = 1;
-
-
struct dns_results {
ip_t ip;
char *name;
struct dns_results *results;
-extern char *strlongip(ip_t * ip)
+extern char *strlongip(struct mtr_ctl *ctl, ip_t * ip)
{
#ifdef ENABLE_IPV6
static char addrstr[INET6_ADDRSTRLEN];
- return (char *) inet_ntop( af, ip, addrstr, sizeof addrstr );
+ return (char *) inet_ntop( ctl->af, ip, addrstr, sizeof addrstr );
#else
return inet_ntoa( *ip );
#endif
}
-static struct dns_results *findip (ip_t *ip)
+static struct dns_results *findip (struct mtr_ctl *ctl, ip_t *ip)
{
struct dns_results *t;
- //printf ("Looking for: %s\n", strlongip (ip));
+ //printf ("Looking for: %s\n", strlongip (ctl, ip));
for (t=results;t;t=t->next) {
- //printf ("comparing: %s\n", strlongip (&t->ip));
- if (addrcmp ( (void *)ip, (void*) &t->ip, af) == 0)
+ //printf ("comparing: %s\n", strlongip (ctl, &t->ip));
+ if (addrcmp ( (void *)ip, (void*) &t->ip, ctl->af) == 0)
return t;
}
return NULL;
}
-static void set_sockaddr_ip (struct sockaddr_storage *sa, ip_t *ip)
+static void set_sockaddr_ip (struct mtr_ctl *ctl, struct sockaddr_storage *sa, ip_t *ip)
{
struct sockaddr_in *sa_in;
struct sockaddr_in6 *sa_in6;
memset (sa, 0, sizeof (struct sockaddr_storage));
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
sa_in = (struct sockaddr_in *) sa;
- sa_in->sin_family = af;
- addrcpy ((void *) &sa_in->sin_addr, (void*) ip, af);
+ sa_in->sin_family = ctl->af;
+ addrcpy ((void *) &sa_in->sin_addr, (void*) ip, ctl->af);
break;
case AF_INET6:
sa_in6 = (struct sockaddr_in6 *) sa;
- sa_in6->sin6_family = af;
- addrcpy ((void *) &sa_in6->sin6_addr, (void*)ip, af);
+ sa_in6->sin6_family = ctl->af;
+ addrcpy ((void *) &sa_in6->sin6_addr, (void*)ip, ctl->af);
break;
}
}
}
#endif
-extern void dns_open(void)
+extern void dns_open(struct mtr_ctl *ctl)
{
int pid;
buf[strlen(buf)-1] = 0; // chomp newline.
- longipstr (buf, &host, af);
- //printf ("resolving %s (%d)\n", strlongip (&host), af);
- set_sockaddr_ip (&sa, &host);
- salen = (af == AF_INET)?sizeof(struct sockaddr_in):
+ longipstr (buf, &host, ctl->af);
+ //printf ("resolving %s (%d)\n", strlongip (ctl, &host), ctl->af);
+ set_sockaddr_ip (ctl, &sa, &host);
+ salen = (ctl->af == AF_INET)?sizeof(struct sockaddr_in):
sizeof(struct sockaddr_in6);
rv = getnameinfo ((struct sockaddr *) &sa, salen,
hostname, sizeof (hostname), NULL, 0, 0);
if (rv == 0) {
- sprintf (result, "%s %s\n", strlongip (&host), hostname);
- //printf ("resolved: %s -> %s (%d)\n", strlongip (&host), hostname, rv);
+ sprintf (result, "%s %s\n", strlongip (ctl, &host), hostname);
+ //printf ("resolved: %s -> %s (%d)\n", strlongip (ctl, &host), hostname, rv);
rv = write (fromdns[1], result, strlen (result));
if (rv < 0)
error (0, errno, "write DNS lookup result");
}
-extern void dns_ack(void)
+extern void dns_ack(struct mtr_ctl *ctl)
{
char buf[2048], host[NI_MAXHOST], name[NI_MAXHOST];
ip_t hostip;
while ( fgets (buf, sizeof (buf), fromdnsfp )) {
sscanf (buf, "%s %s", host, name);
- longipstr (host, &hostip, af);
- r = findip (&hostip);
+ longipstr (host, &hostip, ctl->af);
+ r = findip (ctl, &hostip);
if (r)
r->name = strdup (name);
else
#endif
-extern char *dns_lookup2(ip_t * ip)
+extern char *dns_lookup2(struct mtr_ctl *ctl, ip_t * ip)
{
struct dns_results *r;
char buf[INET6_ADDRSTRLEN + 1];
int rv;
- r = findip (ip);
+ r = findip (ctl, ip);
if (r) {
// we've got a result.
if (r->name)
return r->name;
else
- return strlongip (ip);
+ return strlongip (ctl, ip);
} else {
r = malloc (sizeof (struct dns_results));
//r->ip = *ip;
r->next = results;
results = r;
- //printf ("lookup: %s\n", strlongip (ip));
+ //printf ("lookup: %s\n", strlongip (ctl, ip));
- sprintf (buf, "%s\n", strlongip (ip));
+ sprintf (buf, "%s\n", strlongip (ctl, ip));
rv = write (todns[1], buf, strlen (buf));
if (rv < 0)
error (0, errno, "couldn't write to resolver process");
}
- return strlongip (ip);
+ return strlongip (ctl, ip);
}
-extern char *dns_lookup(ip_t * ip)
+extern char *dns_lookup(struct mtr_ctl *ctl, ip_t * ip)
{
char *t;
- if (!dns) return NULL;
- t = dns_lookup2(ip);
- return (t && use_dns) ? t : NULL;
+ if (!ctl->dns)
+ return NULL;
+ t = dns_lookup2(ctl, ip);
+ return t;
}
#if 0
-extern char *strlongip(ip_t * ip)
+extern char *strlongip(struct mtr_ctl *ctl, ip_t * ip)
{
#ifdef ENABLE_IPV6
static char addrstr[INET6_ADDRSTRLEN];
- return (char *) inet_ntop( af, ip, addrstr, sizeof addrstr );
+ return (char *) inet_ntop( ctl->af, ip, addrstr, sizeof addrstr );
#else
return inet_ntoa( *ip );
#endif
/* Prototypes for dns.c */
-extern void dns_open(void);
+extern void dns_open(struct mtr_ctl *ctl);
extern int dns_waitfd(void);
-extern void dns_ack(void);
+extern void dns_ack(struct mtr_ctl *ctl);
#ifdef ENABLE_IPV6
extern int dns_waitfd6(void);
extern void dns_ack6(void);
#endif
#endif
-extern char *dns_lookup(ip_t * address);
-extern char *dns_lookup2(ip_t * address);
+extern char *dns_lookup(struct mtr_ctl *ctl, ip_t * address);
+extern char *dns_lookup2(struct mtr_ctl *ctl, ip_t * address);
extern struct hostent * dns_forward(const char *name);
-extern char *strlongip(ip_t * ip);
+extern char *strlongip(struct mtr_ctl *ctl, ip_t * ip);
extern void addr2ip6arpa( ip_t * ip, char * buf );
extern struct hostent *addr2host( const char *addr, int type );
static gint gtk_ping(gpointer data);
static gint Copy_activate(GtkWidget *widget, gpointer data);
static gint NewDestination_activate(GtkWidget *widget, gpointer data);
-static gboolean ReportTreeView_clicked(GtkWidget *Tree, GdkEventButton *event);
+static gboolean ReportTreeView_clicked(GtkWidget *Tree, GdkEventButton *event, gpointer data);
static gchar* getSelectedHost(GtkTreePath *path);
-
-
-extern char *Hostname;
-extern float WaitTime;
-extern int af;
static int ping_timeout_timer;
static GtkWidget *Pause_Button;
static GtkWidget *Entry;
static GtkWidget *main_window;
-static void gtk_add_ping_timeout (void)
+static void gtk_add_ping_timeout (struct mtr_ctl *ctl)
{
if(gtk_toggle_button_get_active((GtkToggleButton *)Pause_Button)){
return;
}
int dt;
- dt = calc_deltatime (WaitTime);
- ping_timeout_timer = g_timeout_add(dt / 1000, gtk_ping, NULL);
+ dt = calc_deltatime (ctl->WaitTime);
+ gtk_redraw(ctl);
+ ping_timeout_timer = g_timeout_add(dt / 1000, gtk_ping, ctl);
}
-static void gtk_do_init(int *argc, char ***argv)
+static void gtk_do_init(int *argc, char ***argv)
{
static int done = 0;
}
-extern int gtk_detect(UNUSED int *argc, UNUSED char ***argv)
+extern int gtk_detect(UNUSED int *argc, UNUSED char ***argv)
{
if(getenv("DISPLAY") != NULL) {
/* If we do this here, gtk_init exits on an error. This happens
}
-static gint Window_destroy(UNUSED GtkWidget *Window, UNUSED gpointer data)
+static gint Window_destroy(UNUSED GtkWidget *Window, UNUSED gpointer data)
{
gtk_main_quit();
}
-static gint Restart_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
+static gint Restart_clicked(UNUSED GtkWidget *Button, gpointer data)
{
- net_reset();
- gtk_redraw();
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+
+ net_reset(ctl);
+ gtk_redraw(ctl);
return FALSE;
}
-static gint Pause_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
+static gint Pause_clicked(UNUSED GtkWidget *Button, gpointer data)
{
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+
static int paused = 0;
if (paused) {
- gtk_add_ping_timeout ();
+ gtk_add_ping_timeout (ctl);
} else {
g_source_remove (ping_timeout_timer);
}
paused = ! paused;
- gtk_redraw();
+ gtk_redraw(ctl);
return FALSE;
}
-static gint About_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
+static gint About_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
{
static const gchar *authors[] = {
"Matt Kimball <mkimball@xmission.com>",
* What's the problem with this? (-> "I don't think so)
*/
-static gint WaitTime_changed(UNUSED GtkAdjustment *Adj, UNUSED GtkWidget *Button)
+static gint WaitTime_changed(UNUSED GtkAdjustment *Adj,
+ GtkWidget *data)
{
- WaitTime = gtk_spin_button_get_value(GTK_SPIN_BUTTON(Button));
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+ GtkWidget *Button = (GtkWidget *)ctl->gtk_data;
+
+ ctl->WaitTime = gtk_spin_button_get_value(GTK_SPIN_BUTTON(Button));
g_source_remove (ping_timeout_timer);
- gtk_add_ping_timeout ();
- gtk_redraw();
+ gtk_add_ping_timeout (ctl);
+ gtk_redraw(ctl);
return FALSE;
}
-static gint Host_activate(GtkWidget *entry, UNUSED gpointer data)
+static gint Host_activate(GtkWidget *entry, gpointer data)
{
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
struct hostent * addr;
addr = dns_forward(gtk_entry_get_text(GTK_ENTRY(entry)));
if(addr) {
- net_reopen(addr);
+ net_reopen(ctl, addr);
/* If we are "Paused" at this point it is usually because someone
entered a non-existing host. Therefore do the go-ahead... */
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( Pause_Button ) , 0);
-static void Toolbar_fill(GtkWidget *Toolbar)
+static void Toolbar_fill(struct mtr_ctl *ctl, GtkWidget *Toolbar)
{
GtkWidget *Button;
GtkWidget *Label;
Button = gtk_button_new_with_mnemonic("_Restart");
gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
g_signal_connect(GTK_OBJECT(Button), "clicked",
- GTK_SIGNAL_FUNC(Restart_clicked), NULL);
+ GTK_SIGNAL_FUNC(Restart_clicked), ctl);
Pause_Button = gtk_toggle_button_new_with_mnemonic("_Pause");
gtk_box_pack_end(GTK_BOX(Toolbar), Pause_Button, FALSE, FALSE, 0);
GTK_SIGNAL_FUNC(Pause_clicked), NULL);
/* allow root only to set zero delay */
- Adjustment = (GtkAdjustment *)gtk_adjustment_new(WaitTime,
+ Adjustment = (GtkAdjustment *)gtk_adjustment_new(ctl->WaitTime,
getuid()==0 ? 0.01:1.00,
999.99,
1.0, 10.0,
/* gtk_spin_button_set_set_update_policy(GTK_SPIN_BUTTON(Button),
GTK_UPDATE_IF_VALID); */
gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
+ ctl->gtk_data = Button;
g_signal_connect(GTK_OBJECT(Adjustment), "value_changed",
- GTK_SIGNAL_FUNC(WaitTime_changed), Button);
+ GTK_SIGNAL_FUNC(WaitTime_changed), ctl);
Label = gtk_label_new_with_mnemonic("_Hostname:");
gtk_box_pack_start(GTK_BOX(Toolbar), Label, FALSE, FALSE, 0);
Entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(Entry), Hostname);
+ gtk_entry_set_text(GTK_ENTRY(Entry), ctl->Hostname);
g_signal_connect(GTK_OBJECT(Entry), "activate",
- GTK_SIGNAL_FUNC(Host_activate), NULL);
+ GTK_SIGNAL_FUNC(Host_activate), ctl);
gtk_box_pack_start(GTK_BOX(Toolbar), Entry, TRUE, TRUE, 0);
gtk_label_set_mnemonic_widget(GTK_LABEL(Label), Entry);
g_object_set(cell, "text", text, NULL);
}
-static void TreeViewCreate(void)
+static void TreeViewCreate(struct mtr_ctl *ctl)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
ReportTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ReportStore));
g_signal_connect(GTK_OBJECT(ReportTreeView), "button_press_event",
- G_CALLBACK(ReportTreeView_clicked),NULL);
+ G_CALLBACK(ReportTreeView_clicked), ctl);
#ifdef HAVE_IPINFO
if (is_printii()) {
}
-static void update_tree_row(int row, GtkTreeIter *iter)
+static void update_tree_row(struct mtr_ctl *ctl, int row, GtkTreeIter *iter)
{
ip_t *addr;
char str[256]="???", *name=str;
addr = net_addr(row);
- if (addrcmp( (void *) addr, (void *) &unspec_addr, af)) {
- if ((name = dns_lookup(addr))) {
- if (show_ips) {
- snprintf(str, sizeof(str), "%s (%s)", name, strlongip(addr));
+ if (addrcmp( (void *) addr, (void *) &unspec_addr, ctl->af)) {
+ if ((name = dns_lookup(ctl, addr))) {
+ if (ctl->show_ips) {
+ snprintf(str, sizeof(str), "%s (%s)", name, strlongip(ctl, addr));
name = str;
}
- } else name = strlongip(addr);
+ } else name = strlongip(ctl, addr);
}
gtk_list_store_set(ReportStore, iter,
-1);
#ifdef HAVE_IPINFO
if (is_printii())
- gtk_list_store_set(ReportStore, iter, COL_ASN, fmt_ipinfo(addr), -1);
+ gtk_list_store_set(ReportStore, iter, COL_ASN, fmt_ipinfo(ctl, addr), -1);
#endif
}
-extern void gtk_redraw(void)
+extern void gtk_redraw(struct mtr_ctl *ctl)
{
- int max = net_max();
+ int max = net_max(ctl);
GtkTreeIter iter;
- int row = net_min();
+ int row = net_min(ctl);
gboolean valid;
valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ReportStore), &iter);
while(valid) {
if(row < max) {
- update_tree_row(row++, &iter);
+ update_tree_row(ctl, row++, &iter);
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(ReportStore), &iter);
} else {
valid = gtk_list_store_remove(ReportStore, &iter);
}
while(row < max) {
gtk_list_store_append(ReportStore, &iter);
- update_tree_row(row++, &iter);
+ update_tree_row(ctl, row++, &iter);
}
}
-static void Window_fill(GtkWidget *Window)
+static void Window_fill(struct mtr_ctl *ctl, GtkWidget *Window)
{
GtkWidget *VBox;
GtkWidget *Toolbar;
VBox = gtk_vbox_new(FALSE, 10);
Toolbar = gtk_hbox_new(FALSE, 10);
- Toolbar_fill(Toolbar);
+ Toolbar_fill(ctl, Toolbar);
gtk_box_pack_start(GTK_BOX(VBox), Toolbar, FALSE, FALSE, 0);
- TreeViewCreate();
+ TreeViewCreate(ctl);
scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN);
}
-extern void gtk_open(void)
+extern void gtk_open(struct mtr_ctl *ctl)
{
GdkPixbuf *icon;
g_set_application_name("My traceroute");
- Window_fill(main_window);
+ Window_fill(ctl, main_window);
g_signal_connect(GTK_OBJECT(main_window), "delete_event",
GTK_SIGNAL_FUNC(Window_destroy), NULL);
}
-static gint gtk_ping(UNUSED gpointer data)
+static gint gtk_ping(gpointer data)
{
- gtk_redraw();
- net_send_batch();
- net_harvest_fds();
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+
+ gtk_redraw(ctl);
+ net_send_batch(ctl);
+ net_harvest_fds(ctl);
g_source_remove (ping_timeout_timer);
- gtk_add_ping_timeout ();
+ gtk_add_ping_timeout (ctl);
return TRUE;
}
-static gboolean gtk_net_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
+static gboolean gtk_net_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, gpointer data)
{
- net_process_return();
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+
+ net_process_return(ctl);
return TRUE;
}
-static gboolean gtk_dns_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
+static gboolean gtk_dns_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, gpointer data)
{
- dns_ack();
- gtk_redraw();
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+
+ dns_ack(ctl);
+ gtk_redraw(ctl);
return TRUE;
}
#ifdef ENABLE_IPV6
-static gboolean gtk_dns_data6(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
+static gboolean gtk_dns_data6(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, gpointer data)
{
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+
dns_ack6();
- gtk_redraw();
+ gtk_redraw(ctl);
return TRUE;
}
#endif
-extern void gtk_loop(void)
+extern void gtk_loop(struct mtr_ctl *ctl)
{
GIOChannel *net_iochannel, *dns_iochannel;
- gtk_add_ping_timeout ();
+ gtk_add_ping_timeout (ctl);
net_iochannel = g_io_channel_unix_new(net_waitfd());
- g_io_add_watch(net_iochannel, G_IO_IN, gtk_net_data, NULL);
+ g_io_add_watch(net_iochannel, G_IO_IN, gtk_net_data, ctl);
#ifdef ENABLE_IPV6
if (dns_waitfd6() > 0) {
dns_iochannel = g_io_channel_unix_new(dns_waitfd6());
- g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data6, NULL);
+ g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data6, ctl);
}
#endif
dns_iochannel = g_io_channel_unix_new(dns_waitfd());
- g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data, NULL);
+ g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data, ctl);
gtk_main();
}
static gboolean NewDestination_activate(GtkWidget *widget UNUSED, gpointer data)
{
gchar *hostname;
- GtkTreePath *path = (GtkTreePath*)data;
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
+ GtkTreePath *path = (GtkTreePath *)ctl->gtk_data;
hostname = getSelectedHost(path);
if (hostname) {
+ ctl->gtk_data = hostname;
gtk_entry_set_text (GTK_ENTRY(Entry), hostname);
- Host_activate(Entry, NULL);
+ Host_activate(Entry, ctl);
g_free(hostname);
}
return TRUE;
}
-static gboolean ReportTreeView_clicked(GtkWidget *Tree UNUSED, GdkEventButton *event)
+static gboolean ReportTreeView_clicked(GtkWidget *Tree UNUSED, GdkEventButton *event, gpointer data)
{
GtkWidget* popup_menu;
GtkWidget* copy_item;
GtkWidget* newdestination_item;
GtkTreePath *path;
+ struct mtr_ctl *ctl = (struct mtr_ctl *)data;
if (event->type != GDK_BUTTON_PRESS || event->button != 3)
return FALSE;
g_signal_connect(GTK_OBJECT(copy_item),"activate",
GTK_SIGNAL_FUNC(Copy_activate), path);
+ ctl->gtk_data = path;
g_signal_connect(GTK_OBJECT(newdestination_item),"activate",
- GTK_SIGNAL_FUNC(NewDestination_activate), path);
+ GTK_SIGNAL_FUNC(NewDestination_activate), ctl);
gtk_widget_show (copy_item);
gtk_widget_show (newdestination_item);
*/
/* Prototypes for curses.c */
-extern void mtr_curses_open(void);
+extern void mtr_curses_open(struct mtr_ctl *ctl);
extern void mtr_curses_close(void);
-extern void mtr_curses_redraw(void);
-extern int mtr_curses_keyaction(void);
-extern void mtr_curses_clear(void);
+extern void mtr_curses_redraw(struct mtr_ctl *ctl);
+extern int mtr_curses_keyaction(struct mtr_ctl *ctl);
+extern void mtr_curses_clear(struct mtr_ctl *ctl);
/* Prototypes for gtk.c */
extern int gtk_detect(int *argc, char ***argv);
-extern void gtk_open(void);
+extern void gtk_open(struct mtr_ctl *ctl);
extern void gtk_close(void);
-extern void gtk_redraw(void);
+extern void gtk_redraw(struct mtr_ctl *ctl);
extern int gtk_keyaction(void);
-extern void gtk_loop(void);
+extern void gtk_loop(struct mtr_ctl *ctl);
#endif
-int DisplayMode;
-int display_mode;
-int Interactive = 1;
-int MaxPing = 10;
-int ForceMaxPing = 0;
-float WaitTime = 1.0;
-float GraceTime = 5.0;
-char *Hostname = NULL;
-char *InterfaceAddress = NULL;
-char LocalHostname[128];
-int dns = 1;
-int show_ips = 0;
-int enablempls = 0;
-int cpacketsize = 64; /* default packet size */
-int bitpattern = 0;
-int tos = 0;
-#ifdef SO_MARK
-uint32_t mark = 0;
-#endif
-int reportwide = 0;
-int af = DEFAULT_AF;
-int mtrtype = IPPROTO_ICMP; /* Use ICMP as default packet type */
-
- /* begin ttl windows addByMin */
-int fstTTL = 1; /* default start at first hop */
-/*int maxTTL = MaxHost-1; */ /* max you can go is 255 hops */
-int maxTTL = 30; /* inline with traceroute */
- /* end ttl window stuff. */
-int maxUnknown = 12; /* stop send package */
- /*when larger than this count */
-int remoteport = 0; /* for TCP tracing */
-int localport = 0; /* for UDP tracing */
-int tcp_timeout = 10 * 1000000; /* for TCP tracing */
-
-
-/* default display field(defined by key in net.h) and order */
-unsigned char fld_active[2*MAXFLD] = "LS NABWV";
-int fld_index[256];
-char available_options[MAXFLD];
-
-
struct fields data_fields[MAXFLD] = {
/* key, Remark, Header, Format, Width, CallBackFunc */
{' ', "<sp>: Space between fields", " ", " ", 1, &net_drop },
}
-static void init_fld_options (void)
+static void init_fld_options (struct mtr_ctl *ctl)
{
int i;
for (i=0;i < 256;i++)
- fld_index[i] = -1;
+ ctl->fld_index[i] = -1;
for (i=0;data_fields[i].key != 0;i++) {
- available_options[i] = data_fields[i].key;
- fld_index[data_fields[i].key] = i;
+ ctl->available_options[i] = data_fields[i].key;
+ ctl->fld_index[data_fields[i].key] = i;
}
- available_options[i] = 0;
+ ctl->available_options[i] = 0;
}
-static void parse_arg (int argc, char **argv)
+static void parse_arg (struct mtr_ctl *ctl, int argc, char **argv)
{
int opt;
int i;
break;
case 'r':
- DisplayMode = DisplayReport;
+ ctl->DisplayMode = DisplayReport;
break;
case 'w':
- reportwide = 1;
- DisplayMode = DisplayReport;
+ ctl->reportwide = 1;
+ ctl->DisplayMode = DisplayReport;
break;
#ifdef HAVE_NCURSES
case 't':
- DisplayMode = DisplayCurses;
+ ctl->DisplayMode = DisplayCurses;
break;
#endif
#ifdef HAVE_GTK
case 'g':
- DisplayMode = DisplayGTK;
+ ctl->DisplayMode = DisplayGTK;
break;
#endif
case 'p': /* BL */
- DisplayMode = DisplaySplit;
+ ctl->DisplayMode = DisplaySplit;
break;
case 'l':
- DisplayMode = DisplayRaw;
+ ctl->DisplayMode = DisplayRaw;
break;
case 'C':
- DisplayMode = DisplayCSV;
+ ctl->DisplayMode = DisplayCSV;
break;
case 'j':
- DisplayMode = DisplayJSON;
+ ctl->DisplayMode = DisplayJSON;
break;
case 'x':
- DisplayMode = DisplayXML;
+ ctl->DisplayMode = DisplayXML;
break;
case OPT_DISPLAYMODE:
- display_mode = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if ((DisplayModeMAX - 1) < display_mode)
+ ctl->display_mode = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if ((DisplayModeMAX - 1) < ctl->display_mode)
error(EXIT_FAILURE, 0, "value out of range (%d - %d): %s",
DisplayModeDefault, (DisplayModeMAX - 1), optarg);
break;
case 'c':
- MaxPing = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- ForceMaxPing = 1;
+ ctl->MaxPing = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ ctl->ForceMaxPing = 1;
break;
case 's':
- cpacketsize = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ ctl->cpacketsize = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
break;
case 'a':
- InterfaceAddress = optarg;
+ ctl->InterfaceAddress = optarg;
break;
case 'e':
- enablempls = 1;
+ ctl->enablempls = 1;
break;
case 'n':
- dns = 0;
+ ctl->dns = 0;
break;
case 'i':
- WaitTime = strtofloat_or_err(optarg, "invalid argument");
- if (WaitTime <= 0.0) {
+ ctl->WaitTime = strtofloat_or_err(optarg, "invalid argument");
+ if (ctl->WaitTime <= 0.0) {
error(EXIT_FAILURE, 0, "wait time must be positive");
}
- if (getuid() != 0 && WaitTime < 1.0) {
+ if (getuid() != 0 && ctl->WaitTime < 1.0) {
error(EXIT_FAILURE, 0, "non-root users cannot request an interval < 1.0 seconds");
}
break;
case 'f':
- fstTTL = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (fstTTL > maxTTL) {
- fstTTL = maxTTL;
+ ctl->fstTTL = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->fstTTL > ctl->maxTTL) {
+ ctl->fstTTL = ctl->maxTTL;
}
- if (fstTTL < 1) { /* prevent 0 hop */
- fstTTL = 1;
+ if (ctl->fstTTL < 1) { /* prevent 0 hop */
+ ctl->fstTTL = 1;
}
break;
case 'F':
read_from_file(optarg);
break;
case 'm':
- maxTTL = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (maxTTL > (MaxHost - 1)) {
- maxTTL = MaxHost-1;
+ ctl->maxTTL = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->maxTTL > (MaxHost - 1)) {
+ ctl->maxTTL = MaxHost - 1;
}
- if (maxTTL < 1) { /* prevent 0 hop */
- maxTTL = 1;
+ if (ctl->maxTTL < 1) { /* prevent 0 hop */
+ ctl->maxTTL = 1;
}
- if (fstTTL > maxTTL) { /* don't know the pos of -m or -f */
- fstTTL = maxTTL;
+ if (ctl->fstTTL > ctl->maxTTL) { /* don't know the pos of -m or -f */
+ ctl->fstTTL = ctl->maxTTL;
}
break;
case 'U':
- maxUnknown = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (maxUnknown < 1) {
- maxUnknown = 1;
+ ctl->maxUnknown = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->maxUnknown < 1) {
+ ctl->maxUnknown = 1;
}
break;
case 'o':
error(EXIT_FAILURE, 0, "Too many fields: %s", optarg);
}
for (i=0; optarg[i]; i++) {
- if(!strchr (available_options, optarg[i])) {
+ if(!strchr (ctl->available_options, optarg[i])) {
error(EXIT_FAILURE, 0, "Unknown field identifier: %c", optarg[i]);
}
}
- strcpy ((char*)fld_active, optarg);
+ strcpy ((char*)ctl->fld_active, optarg);
break;
case 'B':
- bitpattern = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (bitpattern > 255)
- bitpattern = -1;
+ ctl->bitpattern = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->bitpattern > 255)
+ ctl->bitpattern = -1;
break;
case 'G':
- GraceTime = strtofloat_or_err(optarg, "invalid argument");
- if (GraceTime <= 0.0) {
+ ctl->GraceTime = strtofloat_or_err(optarg, "invalid argument");
+ if (ctl->GraceTime <= 0.0) {
error(EXIT_FAILURE, 0, "wait time must be positive");
}
break;
case 'Q':
- tos = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (tos > 255 || tos < 0) {
+ ctl->tos = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->tos > 255 || ctl->tos < 0) {
/* error message, should do more checking for valid values,
* details in rfc2474 */
- tos = 0;
+ ctl->tos = 0;
}
break;
case 'u':
- if (mtrtype != IPPROTO_ICMP) {
+ if (ctl->mtrtype != IPPROTO_ICMP) {
error(EXIT_FAILURE, 0, "-u , -T and -S are mutually exclusive");
}
- mtrtype = IPPROTO_UDP;
+ ctl->mtrtype = IPPROTO_UDP;
break;
case 'T':
- if (mtrtype != IPPROTO_ICMP) {
+ if (ctl->mtrtype != IPPROTO_ICMP) {
error(EXIT_FAILURE, 0, "-u , -T and -S are mutually exclusive");
}
- if (!remoteport) {
- remoteport = 80;
+ if (!ctl->remoteport) {
+ ctl->remoteport = 80;
}
- mtrtype = IPPROTO_TCP;
+ ctl->mtrtype = IPPROTO_TCP;
break;
case 'S':
#ifdef HAS_SCTP
- if (mtrtype != IPPROTO_ICMP) {
+ if (ctl->mtrtype != IPPROTO_ICMP) {
error(EXIT_FAILURE, 0, "-u , -T and -S are mutually exclusive");
}
- if (!remoteport) {
- remoteport = 80;
+ if (!ctl->remoteport) {
+ ctl->remoteport = 80;
}
- mtrtype = IPPROTO_SCTP;
+ ctl->mtrtype = IPPROTO_SCTP;
#else
error(EXIT_FAILURE, 0, "No SCTP support found at compiletime");
#endif
break;
case 'b':
- show_ips = 1;
+ ctl->show_ips = 1;
break;
case 'P':
- remoteport = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (remoteport < 1 || MaxPort < remoteport) {
- error(EXIT_FAILURE, 0, "Illegal port number: %d", remoteport);
+ ctl->remoteport = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->remoteport < 1 || MaxPort < ctl->remoteport) {
+ error(EXIT_FAILURE, 0, "Illegal port number: %d", ctl->remoteport);
}
break;
case 'L':
- localport = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (localport < MinPort || MaxPort < localport) {
- error(EXIT_FAILURE, 0, "Illegal port number: %d", localport);
+ ctl->localport = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->localport < MinPort || MaxPort < ctl->localport) {
+ error(EXIT_FAILURE, 0, "Illegal port number: %d", ctl->localport);
}
break;
case 'Z':
- tcp_timeout = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- tcp_timeout *= 1000000;
+ ctl->tcp_timeout = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ ctl->tcp_timeout *= 1000000;
break;
case '4':
- af = AF_INET;
+ ctl->af = AF_INET;
break;
case '6':
#ifdef ENABLE_IPV6
- af = AF_INET6;
+ ctl->af = AF_INET6;
break;
#else
error(EXIT_FAILURE, 0, "IPv6 not enabled");
#endif
#ifdef HAVE_IPINFO
case 'y':
- ipinfo_no = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
- if (ipinfo_no < 0)
- ipinfo_no = 0;
+ ctl->ipinfo_no = strtonum_or_err(optarg, "invalid argument", STRTO_INT);
+ if (ctl->ipinfo_no < 0)
+ ctl->ipinfo_no = 0;
break;
case 'z':
- ipinfo_no = 0;
+ ctl->ipinfo_no = 0;
break;
#else
case 'y':
#endif
#ifdef SO_MARK
case 'M':
- mark = strtonum_or_err(optarg, "invalid argument", STRTO_U32INT);
+ ctl->mark = strtonum_or_err(optarg, "invalid argument", STRTO_U32INT);
break;
#else
case 'M':
}
}
- if (DisplayMode == DisplayReport ||
- DisplayMode == DisplayTXT ||
- DisplayMode == DisplayJSON ||
- DisplayMode == DisplayXML ||
- DisplayMode == DisplayRaw ||
- DisplayMode == DisplayCSV)
- Interactive = 0;
+ if (ctl->DisplayMode == DisplayReport ||
+ ctl->DisplayMode == DisplayTXT ||
+ ctl->DisplayMode == DisplayJSON ||
+ ctl->DisplayMode == DisplayXML ||
+ ctl->DisplayMode == DisplayRaw ||
+ ctl->DisplayMode == DisplayCSV)
+ ctl->Interactive = 0;
if (optind > argc - 1)
return;
}
-static void parse_mtr_options (char *string)
+static void parse_mtr_options (struct mtr_ctl *ctl, char *string)
{
int argc;
char *argv[128], *p;
error(0, 0, "Warning: extra arguments ignored: %s", p);
}
- parse_arg (argc, argv);
+ parse_arg (ctl, argc, argv);
optind = 0;
}
#ifdef ENABLE_IPV6
struct sockaddr_in6 * sa6;
#endif
+ struct mtr_ctl ctl;
+ memset(&ctl, 0, sizeof(ctl));
+ /* initialize non-null values */
+ ctl.Interactive = 1;
+ ctl.MaxPing = 10;
+ ctl.WaitTime = 1.0;
+ ctl.GraceTime = 5.0;
+ ctl.dns = 1;
+ ctl.use_dns = 1;
+ ctl.cpacketsize = 64;
+ ctl.af = DEFAULT_AF;
+ ctl.mtrtype = IPPROTO_ICMP;
+ ctl.fstTTL = 1;
+ ctl.maxTTL = 30;
+ ctl.maxUnknown = 12;
+ ctl.tcp_timeout = 10 * 1000000;
+ strcpy(ctl.fld_active, "LS NABWV");
/* Get the raw sockets first thing, so we can drop to user euid immediately */
/* reset the random seed */
srand (getpid());
- display_detect(&argc, &argv);
- display_mode = DisplayModeDefault;
+ display_detect(&ctl, &argc, &argv);
+ ctl.display_mode = DisplayModeDefault;
/* The field options are now in a static array all together,
but that requires a run-time initialization. */
- init_fld_options ();
+ init_fld_options (&ctl);
- parse_mtr_options (getenv ("MTR_OPTIONS"));
+ parse_mtr_options (&ctl, getenv ("MTR_OPTIONS"));
- parse_arg (argc, argv);
+ parse_arg (&ctl, argc, argv);
while (optind < argc) {
char* name = argv[optind++];
}
/* Now that we know mtrtype we can select which socket to use */
- if (net_selectsocket() != 0) {
+ if (net_selectsocket(&ctl) != 0) {
error(EXIT_FAILURE, 0, "Couldn't determine raw socket type");
}
names_t* head = names;
while (names != NULL) {
- Hostname = names->name;
+ ctl.Hostname = names->name;
// if (Hostname == NULL) Hostname = "localhost"; // no longer necessary.
- if (gethostname(LocalHostname, sizeof(LocalHostname))) {
- strcpy(LocalHostname, "UNKNOWNHOST");
+ if (gethostname(ctl.LocalHostname, sizeof(ctl.LocalHostname))) {
+ strcpy(ctl.LocalHostname, "UNKNOWNHOST");
}
if (net_preopen_result != 0) {
error(0, 0, "Unable to get raw socket. (Executable not suid?)");
- if ( DisplayMode != DisplayCSV ) exit(EXIT_FAILURE);
+ if (ctl.DisplayMode != DisplayCSV)
+ exit(EXIT_FAILURE);
else {
names = names->next;
continue;
/* gethostbyname2() is deprecated so we'll use getaddrinfo() instead. */
memset( &hints, 0, sizeof hints );
- hints.ai_family = af;
+ hints.ai_family = ctl.af;
hints.ai_socktype = SOCK_DGRAM;
- gai_error = getaddrinfo( Hostname, NULL, &hints, &res );
+ gai_error = getaddrinfo( ctl.Hostname, NULL, &hints, &res );
if ( gai_error ) {
if (gai_error == EAI_SYSTEM)
- error(0, 0, "Failed to resolve host: %s", Hostname);
+ error(0, 0, "Failed to resolve host: %s", ctl.Hostname);
else
- error(0, 0, "Failed to resolve host: %s: %s", Hostname, gai_strerror(gai_error));
+ error(0, 0, "Failed to resolve host: %s: %s", ctl.Hostname, gai_strerror(gai_error));
- if ( DisplayMode != DisplayCSV ) exit(EXIT_FAILURE);
+ if ( ctl.DisplayMode != DisplayCSV ) exit(EXIT_FAILURE);
else {
names = names->next;
continue;
host->h_name = res->ai_canonname;
host->h_aliases = NULL;
host->h_addrtype = res->ai_family;
- af = res->ai_family;
+ ctl.af = res->ai_family;
host->h_length = res->ai_addrlen;
host->h_addr_list = alptr;
- switch ( af ) {
+ switch (ctl.af) {
case AF_INET:
sa4 = (struct sockaddr_in *) res->ai_addr;
alptr[0] = (void *) &(sa4->sin_addr);
#endif
default:
error(0, 0, "unknown address type");
- if ( DisplayMode != DisplayCSV ) exit(EXIT_FAILURE);
+ if (ctl.DisplayMode != DisplayCSV )
+ exit(EXIT_FAILURE);
else {
names = names->next;
continue;
}
alptr[1] = NULL;
- if (net_open(host) != 0) {
+ if (net_open(&ctl, host) != 0) {
error(0, 0, "Unable to start net module");
- if ( DisplayMode != DisplayCSV ) exit(EXIT_FAILURE);
+ if (ctl.DisplayMode != DisplayCSV)
+ exit(EXIT_FAILURE);
else {
names = names->next;
continue;
}
}
- if (net_set_interfaceaddress (InterfaceAddress) != 0) {
- error(0, 0, "Couldn't set interface address: %s", InterfaceAddress);
- if ( DisplayMode != DisplayCSV ) exit(EXIT_FAILURE);
+ if (net_set_interfaceaddress (&ctl) != 0) {
+ error(0, 0, "Couldn't set interface address: %s", ctl.InterfaceAddress);
+ if (ctl.DisplayMode != DisplayCSV)
+ exit(EXIT_FAILURE);
else {
names = names->next;
continue;
lock(stdout);
- display_open();
- dns_open();
+ display_open(&ctl);
+ dns_open(&ctl);
- display_loop();
+ display_loop(&ctl);
net_end_transit();
- display_close(now);
+ display_close(&ctl, now);
unlock(stdout);
- if ( DisplayMode != DisplayCSV ) break;
- else names = names->next;
+ if (ctl.DisplayMode != DisplayCSV)
+ break;
+ else
+ names = names->next;
}
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifndef MTR_MTR_H
+#define MTR_MTR_H
+
+#include <stdint.h>
+#include <sys/socket.h>
+
/* Typedefs */
/* Find the proper type for 8 bits */
typedef struct in_addr ip_t;
#endif
-extern int enablempls;
-extern int dns;
-extern int show_ips;
-extern int use_dns;
-
#ifdef __GNUC__
#define UNUSED __attribute__((__unused__))
#else
#define UNUSED
#endif
+/* stuff used by display such as report, curses... */
+#define MAXFLD 20 /* max stats fields to display */
+
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif
extern char *
trim(char * s);
+
+struct mtr_ctl {
+ int DisplayMode;
+ int display_mode;
+ int Interactive;
+ int MaxPing;
+ int ForceMaxPing;
+ float WaitTime;
+ float GraceTime;
+ char *Hostname;
+ char *InterfaceAddress;
+ char LocalHostname[128];
+ int dns;
+ int use_dns;
+ int show_ips;
+ int ipinfo_no;
+ int enablempls;
+ int cpacketsize; /* packet size used by ping */
+ int bitpattern; /* packet bit pattern used by ping */
+ int tos; /* type of service set in ping packet*/
+#ifdef SO_MARK
+ uint32_t mark;
+#endif
+ int reportwide;
+ int af; /* address family of remote target */
+ int mtrtype; /* type of query packet used */
+ int fstTTL; /* initial hub(ttl) to ping byMin */
+ int maxTTL; /* last hub to ping byMin*/
+ int maxUnknown; /* stop ping threshold */
+ int remoteport; /* target port for TCP tracing */
+ int localport; /* source port for UDP tracing */
+ int tcp_timeout; /* timeout for TCP connections */
+ unsigned char fld_active[2 * MAXFLD]; /* SO_MARK to set for ping packet*/
+ int fld_index[256]; /* default display field (defined by key in net.h) and order */
+ char available_options[MAXFLD];
+ void *gtk_data; /* pointer to hold arbitrary gtk data */
+};
+
+#endif /* MTR_MTR_H */
#include "display.h"
#include "dns.h"
+static int packetsize; /* packet size used by ping */
+static int spacketsize; /* packet size used by sendto */
+
static void sockaddrtop( struct sockaddr * saddr, char * strptr, size_t len );
static void decodempls(int, char *, struct mplslen *, int);
static int batch_at = 0;
static int numhosts = 10;
-extern int fstTTL; /* initial hub(ttl) to ping byMin */
-extern int maxTTL; /* last hub to ping byMin*/
-extern int maxUnknown; /* stop ping threshold */
-extern int cpacketsize; /* packet size used by ping */
-static int packetsize; /* packet size used by ping */
-static int spacketsize; /* packet size used by sendto */
-extern int bitpattern; /* packet bit pattern used by ping */
-extern int tos; /* type of service set in ping packet*/
-extern int af; /* address family of remote target */
-extern int mtrtype; /* type of query packet used */
-extern int remoteport; /* target port for TCP tracing */
-extern int localport; /* source port for UDP tracing */
-extern int tcp_timeout; /* timeout for TCP connections */
-#ifdef SO_MARK
-extern uint32_t mark; /* SO_MARK to set for ping packet*/
-#endif
-
/* return the number of microseconds to wait before sending the next
ping */
extern int calc_deltatime (float waittime)
/* Prepend pseudoheader to the udp datagram and calculate checksum */
-static int udp_checksum(void *pheader, void *udata, int psize, int dsize, int alt_checksum)
+static int udp_checksum(struct mtr_ctl *ctl, void *pheader, void *udata,
+ int psize, int dsize, int alt_checksum)
{
unsigned int tsize = psize + dsize;
char csumpacket[tsize];
- memset(csumpacket, (unsigned char) abs(bitpattern), tsize);
+ memset(csumpacket, (unsigned char) abs(ctl->bitpattern), tsize);
if (alt_checksum && dsize >= 2) {
csumpacket[psize + sizeof(struct UDPHeader)] = 0;
csumpacket[psize + sizeof(struct UDPHeader) + 1] = 0;
}
-static void save_sequence(int index, int seq)
+static void save_sequence(struct mtr_ctl *ctl, int index, int seq)
{
- display_rawxmit(index, seq);
+ display_rawxmit(ctl, index, seq);
sequence[seq].index = index;
sequence[seq].transit = 1;
net_save_xmit(index);
}
-static int new_sequence(int index)
+static int new_sequence(struct mtr_ctl *ctl, int index)
{
static int next_sequence = MinSequence;
int seq;
if (next_sequence >= MaxSequence)
next_sequence = MinSequence;
- save_sequence(index, seq);
+ save_sequence(ctl, index, seq);
return seq;
}
/* Attempt to connect to a TCP port with a TTL */
-static void net_send_tcp(int index)
+static void net_send_tcp(struct mtr_ctl *ctl, int index)
{
int ttl, s;
int port = 0;
ttl = index + 1;
- s = socket(af, SOCK_STREAM, 0);
+ s = socket(ctl->af, SOCK_STREAM, 0);
if (s < 0) {
- display_clear();
+ display_clear(ctl);
perror("socket()");
exit(EXIT_FAILURE);
}
memset(&local, 0, sizeof (local));
memset(&remote, 0, sizeof (remote));
- local.ss_family = af;
- remote.ss_family = af;
+ local.ss_family = ctl->af;
+ remote.ss_family = ctl->af;
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
- addrcpy((void *) &local4->sin_addr, (void *) &ssa4->sin_addr, af);
- addrcpy((void *) &remote4->sin_addr, (void *) remoteaddress, af);
- remote4->sin_port = htons(remoteport);
+ addrcpy((void *) &local4->sin_addr, (void *) &ssa4->sin_addr, ctl->af);
+ addrcpy((void *) &remote4->sin_addr, (void *) remoteaddress, ctl->af);
+ remote4->sin_port = htons(ctl->remoteport);
len = sizeof (struct sockaddr_in);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
- addrcpy((void *) &local6->sin6_addr, (void *) &ssa6->sin6_addr, af);
- addrcpy((void *) &remote6->sin6_addr, (void *) remoteaddress, af);
- remote6->sin6_port = htons(remoteport);
+ addrcpy((void *) &local6->sin6_addr, (void *) &ssa6->sin6_addr, ctl->af);
+ addrcpy((void *) &remote6->sin6_addr, (void *) remoteaddress, ctl->af);
+ remote6->sin6_port = htons(ctl->remoteport);
len = sizeof (struct sockaddr_in6);
break;
#endif
}
if (bind(s, (struct sockaddr *) &local, len)) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "bind()");
}
if (getsockname(s, (struct sockaddr *) &local, &len)) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "getsockname()");
}
// opt = 1;
flags = fcntl(s, F_GETFL, 0);
if (flags < 0) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "fcntl(F_GETFL)");
}
if (fcntl (s, F_SETFL, flags | O_NONBLOCK) < 0) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "fcntl(F_SETFL, O_NONBLOCK)");
}
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof (ttl))) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "setsockopt IP_TTL");
}
- if (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof (tos))) {
- display_clear();
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, &ctl->tos, sizeof (ctl->tos))) {
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "setsockopt IP_TOS");
}
break;
#ifdef ENABLE_IPV6
case AF_INET6:
if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof (ttl))) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "setsockopt IPPROTO_IPV6 ttl");
}
break;
}
#ifdef SO_MARK
- if (mark && setsockopt( s, SOL_SOCKET, SO_MARK, &mark, sizeof mark ) ) {
+ if (ctl->mark && setsockopt( s, SOL_SOCKET, SO_MARK, &ctl->mark, sizeof ctl->mark ) ) {
error(EXIT_FAILURE, errno, "setsockopt SO_MARK");
}
#endif
break;
#endif
default:
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, 0, "unknown address family");
}
- save_sequence(index, port);
+ save_sequence(ctl, index, port);
gettimeofday(&sequence[port].time, NULL);
sequence[port].socket = s;
#ifdef HAS_SCTP
/* Attempt to connect to a SCTP port with a TTL */
-static void net_send_sctp(int index)
+static void net_send_sctp(struct mtr_ctl *ctl, int index)
{
int ttl, s;
int opt = 1;
ttl = index + 1;
- s = socket(af, SOCK_STREAM, IPPROTO_SCTP);
+ s = socket(ctl->af, SOCK_STREAM, IPPROTO_SCTP);
if (s < 0) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "socket()");
}
memset(&local, 0, sizeof (local));
memset(&remote, 0, sizeof (remote));
- local.ss_family = af;
- remote.ss_family = af;
+ local.ss_family = ctl->af;
+ remote.ss_family = ctl->af;
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
- addrcpy((void *) &local4->sin_addr, (void *) &ssa4->sin_addr, af);
- addrcpy((void *) &remote4->sin_addr, (void *) remoteaddress, af);
- remote4->sin_port = htons(remoteport);
+ addrcpy((void *) &local4->sin_addr, (void *) &ssa4->sin_addr, ctl->af);
+ addrcpy((void *) &remote4->sin_addr, (void *) remoteaddress, ctl->af);
+ remote4->sin_port = htons(ctl->remoteport);
len = sizeof (struct sockaddr_in);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
- addrcpy((void *) &local6->sin6_addr, (void *) &ssa6->sin6_addr, af);
- addrcpy((void *) &remote6->sin6_addr, (void *) remoteaddress, af);
- remote6->sin6_port = htons(remoteport);
+ addrcpy((void *) &local6->sin6_addr, (void *) &ssa6->sin6_addr, ctl->af);
+ addrcpy((void *) &remote6->sin6_addr, (void *) remoteaddress, ctl->af);
+ remote6->sin6_port = htons(ctl->remoteport);
len = sizeof (struct sockaddr_in6);
break;
#endif
}
if (bind(s, (struct sockaddr *) &local, len)) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "bind()");
}
if (getsockname(s, (struct sockaddr *) &local, &len)) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "getsockname()");
}
opt = 1;
if (ioctl(s, FIONBIO, &opt)) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "ioctl FIONBIO");
}
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof (ttl))) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "setsockopt IP_TTL");
}
- if (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof (tos))) {
- display_clear();
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, &ctl->tos, sizeof (ctl->tos))) {
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "setsockopt IP_TOS");
}
break;
#ifdef ENABLE_IPV6
case AF_INET6:
if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof (ttl))) {
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, errno, "setsockopt IPPROTO_IPV6 ttl");
}
break;
}
#ifdef SO_MARK
- if (mark && setsockopt( s, SOL_SOCKET, SO_MARK, &mark, sizeof mark ) ) {
+ if (ctl->mark && setsockopt( s, SOL_SOCKET, SO_MARK, &ctl->mark, sizeof ctl->mark ) ) {
error(EXIT_FAILURE, errno, "setsockopt SO_MARK");
}
#endif
break;
#endif
default:
- display_clear();
+ display_clear(ctl);
error(EXIT_FAILURE, 0, "unknown address family");
}
- save_sequence(index, port);
+ save_sequence(ctl, index, port);
gettimeofday(&sequence[port].time, NULL);
sequence[port].socket = s;
#endif
/* Attempt to find the host at a particular number of hops away */
-static void net_send_query(int index)
+static void net_send_query(struct mtr_ctl *ctl, int index)
{
- if (mtrtype == IPPROTO_TCP) {
- net_send_tcp(index);
+ if (ctl->mtrtype == IPPROTO_TCP) {
+ net_send_tcp(ctl, index);
return;
}
#ifdef HAS_SCTP
- if (mtrtype == IPPROTO_SCTP) {
- net_send_sctp(index);
+ if (ctl->mtrtype == IPPROTO_SCTP) {
+ net_send_sctp(ctl, index);
return;
}
#endif
if ( packetsize < MINPACKET ) packetsize = MINPACKET;
if ( packetsize > MAXPACKET ) packetsize = MAXPACKET;
- if ( mtrtype == IPPROTO_UDP && remoteport && packetsize < (MINPACKET + 2)) {
+ if ( ctl->mtrtype == IPPROTO_UDP && ctl->remoteport && packetsize < (MINPACKET + 2)) {
packetsize = MINPACKET + 2;
}
- memset(packet, (unsigned char) abs(bitpattern), abs(packetsize));
+ memset(packet, (unsigned char) abs(ctl->bitpattern), abs(packetsize));
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
#if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL)
iphsize = 0;
- if ( setsockopt( sendsock, IPPROTO_IP, IP_TOS, &tos, sizeof tos ) ) {
+ if ( setsockopt( sendsock, IPPROTO_IP, IP_TOS, &ctl->tos, sizeof ctl->tos ) ) {
error(EXIT_FAILURE, errno, "setsockopt IP_TOS");
}
if ( setsockopt( sendsock, IPPROTO_IP, IP_TTL, &ttl, sizeof ttl ) ) {
iphsize = sizeof (struct IPHeader);
ip->version = 0x45;
- ip->tos = tos;
+ ip->tos = ctl->tos;
ip->len = BSDfix ? abs(packetsize): htons (abs(packetsize));
ip->id = 0;
ip->frag = 0; /* 1, if want to find mtu size? Min */
ip->ttl = ttl;
- ip->protocol = mtrtype;
+ ip->protocol = ctl->mtrtype;
ip->check = 0;
/* BSD needs the source address here, Linux & others do not... */
}
#ifdef SO_MARK
- if (mark && setsockopt( sendsock, SOL_SOCKET, SO_MARK, &mark, sizeof mark ) ) {
+ if (ctl->mark && setsockopt( sendsock, SOL_SOCKET, SO_MARK, &ctl->mark, sizeof ctl->mark ) ) {
error(EXIT_FAILURE, errno, "setsockopt SO_MARK");
}
#endif
- switch ( mtrtype ) {
+ switch ( ctl->mtrtype ) {
case IPPROTO_ICMP:
icmp = (struct ICMPHeader *)(packet + iphsize);
icmp->type = echotype;
icmp->code = 0;
icmp->checksum = 0;
icmp->id = getpid();
- icmp->sequence = new_sequence(index);
+ icmp->sequence = new_sequence(ctl, index);
icmp->checksum = checksum(icmp, abs(packetsize) - iphsize);
gettimeofday(&sequence[icmp->sequence].time, NULL);
case IPPROTO_UDP:
udp = (struct UDPHeader *)(packet + iphsize);
udp->checksum = 0;
- if (!localport) {
- localport = (uint16)getpid();
- if (localport < MinPort)
- localport += MinPort;
+ if (!ctl->localport) {
+ ctl->localport = (uint16)getpid();
+ if (ctl->localport < MinPort)
+ ctl->localport += MinPort;
}
- udp->srcport = htons(localport);
+ udp->srcport = htons(ctl->localport);
udp->length = htons(abs(packetsize) - iphsize);
- if (!remoteport) {
- udp->dstport = new_sequence(index);
+ if (!ctl->remoteport) {
+ udp->dstport = new_sequence(ctl, index);
gettimeofday(&sequence[udp->dstport].time, NULL);
udp->dstport = htons(udp->dstport);
} else {
// keep dstport constant, stuff sequence into the checksum
- udp->dstport = htons(remoteport);
- udp->checksum = new_sequence(index);
+ udp->dstport = htons(ctl->remoteport);
+ udp->checksum = new_sequence(ctl, index);
gettimeofday(&sequence[udp->checksum].time, NULL);
udp->checksum = htons(udp->checksum);
}
break;
}
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
- switch ( mtrtype ) {
+ switch ( ctl->mtrtype ) {
case IPPROTO_UDP:
/* checksum is not mandatory. only calculate if we know ip->saddr */
if (udp->checksum) {
udpp->daddr = ip->daddr;
udpp->protocol = ip->protocol;
udpp->len = udp->length;
- checksum_result = udp_checksum(udpp, udp, sizeof(struct UDPv4PHeader), abs(packetsize) - iphsize, 1);
+ checksum_result = udp_checksum(ctl, udpp, udp, sizeof(struct UDPv4PHeader), abs(packetsize) - iphsize, 1);
packet[iphsize + sizeof(struct UDPHeader)] = ((char *)&checksum_result)[0];
packet[iphsize + sizeof(struct UDPHeader) + 1] = ((char *)&checksum_result)[1];
} else if (ip->saddr) {
udpp->daddr = ip->daddr;
udpp->protocol = ip->protocol;
udpp->len = udp->length;
- udp->checksum = udp_checksum(udpp, udp, sizeof(struct UDPv4PHeader), abs(packetsize) - iphsize, 0);
+ udp->checksum = udp_checksum(ctl, udpp, udp, sizeof(struct UDPv4PHeader), abs(packetsize) - iphsize, 0);
}
break;
}
break;
#ifdef ENABLE_IPV6
case AF_INET6:
- switch ( mtrtype ) {
+ switch ( ctl->mtrtype ) {
case IPPROTO_UDP:
/* kernel checksum calculation */
if (udp->checksum) {
IPv6 header. */
spacketsize = abs(packetsize)
#ifdef ENABLE_IPV6
- - ( ( af == AF_INET ) ? 0 : sizeof (struct ip6_hdr) )
+ - ( ( ctl->af == AF_INET ) ? 0 : sizeof (struct ip6_hdr) )
#endif
;
/* We got a return on something we sent out. Record the address and
time. */
-static void net_process_ping(int seq, struct mplslen mpls, void * addr, struct timeval now)
+static void net_process_ping(struct mtr_ctl *ctl, int seq, struct mplslen mpls,
+ void *addr, struct timeval now)
{
int index;
int totusec;
#endif
/* Copy the from address ASAP because it can be overwritten */
- addrcpy( (void *) &addrcopy, addr, af );
+ addrcpy( (void *) &addrcopy, addr, ctl->af );
if (seq < 0 || seq >= MaxSequence)
return;
/* impossible? if( totusec < 0 ) totusec = 0 */;
if ( addrcmp( (void *) &(host[index].addr),
- (void *) &unspec_addr, af ) == 0 ) {
+ (void *) &unspec_addr, ctl->af ) == 0 ) {
/* should be out of if as addr can change */
- addrcpy( (void *) &(host[index].addr), addrcopy, af );
+ addrcpy( (void *) &(host[index].addr), addrcopy, ctl->af );
host[index].mpls = mpls;
- display_rawhost(index, (void *) &(host[index].addr));
+ display_rawhost(ctl, index, (void *) &(host[index].addr));
/* multi paths */
- addrcpy( (void *) &(host[index].addrs[0]), addrcopy, af );
+ addrcpy( (void *) &(host[index].addrs[0]), addrcopy, ctl->af );
host[index].mplss[0] = mpls;
} else {
for( i=0; i<MAXPATH; ) {
if( addrcmp( (void *) &(host[index].addrs[i]), (void *) &addrcopy,
- af ) == 0 ||
+ ctl->af ) == 0 ||
addrcmp( (void *) &(host[index].addrs[i]),
- (void *) &unspec_addr, af ) == 0 ) break;
+ (void *) &unspec_addr, ctl->af ) == 0 ) break;
i++;
}
- if( addrcmp( (void *) &(host[index].addrs[i]), addrcopy, af ) != 0 &&
+ if( addrcmp( (void *) &(host[index].addrs[i]), addrcopy, ctl->af ) != 0 &&
i<MAXPATH ) {
- addrcpy( (void *) &(host[index].addrs[i]), addrcopy, af );
+ addrcpy( (void *) &(host[index].addrs[i]), addrcopy, ctl->af );
host[index].mplss[i] = mpls;
- display_rawhost(index, (void *) &(host[index].addrs[i]));
+ display_rawhost(ctl, index, (void *) &(host[index].addrs[i]));
}
}
host[index].transit = 0;
net_save_return(index, sequence[seq].saved_seq, totusec);
- display_rawping(index, totusec, seq);
+ display_rawping(ctl, index, totusec, seq);
}
/* We know a packet has come in, because the main select loop has called us,
now we just need to read it, see if it is for us, and if it is a reply
to something we sent, then call net_process_ping() */
-extern void net_process_return(void)
+extern void net_process_return(struct mtr_ctl *ctl)
{
char packet[MAXPACKET];
#ifdef ENABLE_IPV6
mpls.labels = 0;
gettimeofday(&now, NULL);
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
fromsockaddrsize = sizeof (struct sockaddr_in);
fromaddress = (ip_t *) &(fsa4->sin_addr);
error(EXIT_FAILURE, errno, "recvfrom failed");
}
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
if((size_t) num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader))
return;
#endif
}
- switch ( mtrtype ) {
+ switch ( ctl->mtrtype ) {
case IPPROTO_ICMP:
if (header->type == echoreplytype) {
if(header->id != (uint16)getpid())
seq_num = header->sequence;
} else if (header->type == timeexceededtype) {
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
if ((size_t) num < sizeof(struct IPHeader) +
case IPPROTO_UDP:
if (header->type == timeexceededtype || header->type == unreachabletype) {
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
if ((size_t) num < sizeof(struct IPHeader) +
break;
#endif
}
- if (ntohs(udpheader->srcport) != (uint16)localport)
+ if (ntohs(udpheader->srcport) != (uint16)ctl->localport)
return;
- if (remoteport && remoteport == ntohs(udpheader->dstport)) {
+ if (ctl->remoteport && ctl->remoteport == ntohs(udpheader->dstport)) {
seq_num = ntohs(udpheader->checksum);
- } else if (!remoteport) {
+ } else if (!ctl->remoteport) {
seq_num = ntohs(udpheader->dstport);
}
}
case IPPROTO_TCP:
if (header->type == timeexceededtype || header->type == unreachabletype) {
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
if ((size_t) num < sizeof(struct IPHeader) +
#ifdef HAS_SCTP
case IPPROTO_SCTP:
if (header->type == timeexceededtype || header->type == unreachabletype) {
- switch ( af ) {
+ switch ( ctl->af ) {
case AF_INET:
if ((size_t) num < sizeof(struct IPHeader) +
#endif
}
if (seq_num)
- net_process_ping (seq_num, mpls, (void *) fromaddress, now);
+ net_process_ping (ctl, seq_num, mpls, (void *) fromaddress, now);
}
}
-extern int net_max(void)
+extern int net_max(struct mtr_ctl *ctl)
{
int at;
int max;
max = 0;
/* for(at = 0; at < MaxHost-2; at++) { */
- for(at = 0; at < maxTTL-1; at++) {
+ for(at = 0; at < ctl->maxTTL-1; at++) {
if ( addrcmp( (void *) &(host[at].addr),
- (void *) remoteaddress, af ) == 0 ) {
+ (void *) remoteaddress, ctl->af ) == 0 ) {
return at + 1;
} else if ( addrcmp( (void *) &(host[at].addr),
- (void *) &unspec_addr, af ) != 0 ) {
+ (void *) &unspec_addr, ctl->af ) != 0 ) {
max = at + 2;
}
}
}
-extern int net_min (void)
+extern int net_min (struct mtr_ctl *ctl)
{
- return ( fstTTL - 1 );
+ return ( ctl->fstTTL - 1 );
}
}
}
-extern int net_send_batch(void)
+extern int net_send_batch(struct mtr_ctl *ctl)
{
int n_unknown=0, i;
/* randomized packet size and/or bit pattern if packetsize<0 and/or
bitpattern<0. abs(packetsize) and/or abs(bitpattern) will be used
*/
- if( batch_at < fstTTL ) {
- if( cpacketsize < 0 ) {
+ if( batch_at < ctl->fstTTL ) {
+ if( ctl->cpacketsize < 0 ) {
/* Someone used a formula here that tried to correct for the
"end-error" in "rand()". By "end-error" I mean that if you
have a range for "rand()" that runs to 32768, and the
smaller (reasonable packet sizes), and our rand() range much
larger, this effect is insignificant. Oh! That other formula
didn't work. */
- packetsize = MINPACKET + rand () % (-cpacketsize - MINPACKET);
+ packetsize = MINPACKET + rand () % (- ctl->cpacketsize - MINPACKET);
} else {
- packetsize = cpacketsize;
+ packetsize = ctl->cpacketsize;
}
- if( bitpattern < 0 ) {
- bitpattern = - (int)(256 + 255*(rand()/(RAND_MAX+0.1)));
+ if(ctl->bitpattern < 0 ) {
+ ctl->bitpattern = - (int)(256 + 255*(rand()/(RAND_MAX+0.1)));
}
}
/* printf ("cpacketsize = %d, packetsize = %d\n", cpacketsize, packetsize); */
- net_send_query(batch_at);
+ net_send_query(ctl, batch_at);
- for (i=fstTTL-1;i<batch_at;i++) {
- if ( addrcmp( (void *) &(host[i].addr), (void *) &unspec_addr, af ) == 0 )
+ for (i=ctl->fstTTL-1;i<batch_at;i++) {
+ if ( addrcmp( (void *) &(host[i].addr), (void *) &unspec_addr, ctl->af ) == 0 )
n_unknown++;
/* The second condition in the next "if" statement was added in mtr-0.56,
If the line proves necessary, it should at least NOT trigger that line
when host[i].addr == 0 */
if ( ( addrcmp( (void *) &(host[i].addr),
- (void *) remoteaddress, af ) == 0 )
+ (void *) remoteaddress, ctl->af ) == 0 )
/* || (host[i].addr == host[batch_at].addr) */)
n_unknown = MaxHost; /* Make sure we drop into "we should restart" */
}
if ( /* success in reaching target */
( addrcmp( (void *) &(host[batch_at].addr),
- (void *) remoteaddress, af ) == 0 ) ||
+ (void *) remoteaddress, ctl->af ) == 0 ) ||
/* fail in consecutive maxUnknown (firewall?) */
- (n_unknown > maxUnknown) ||
+ (n_unknown > ctl->maxUnknown) ||
/* or reach limit */
- (batch_at >= maxTTL-1)) {
+ (batch_at >= ctl->maxTTL-1)) {
numhosts = batch_at+1;
- batch_at = fstTTL - 1;
+ batch_at = ctl->fstTTL - 1;
return 1;
}
}
-extern int net_selectsocket(void)
+extern int net_selectsocket(struct mtr_ctl *ctl)
{
#if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL)
- switch ( mtrtype ) {
+ switch ( ctl->mtrtype ) {
case IPPROTO_ICMP:
sendsock4 = sendsock4_icmp;
break;
if (sendsock4 < 0)
return -1;
#ifdef ENABLE_IPV6
- switch ( mtrtype ) {
+ switch ( ctl->mtrtype ) {
case IPPROTO_ICMP:
sendsock6 = sendsock6_icmp;
break;
}
-extern int net_open(struct hostent * hostent)
+extern int net_open(struct mtr_ctl *ctl, struct hostent * hostent)
{
#ifdef ENABLE_IPV6
struct sockaddr_storage name_struct;
struct sockaddr * name = (struct sockaddr *) &name_struct;
socklen_t len;
- net_reset();
+ net_reset(ctl);
remotesockaddr->sa_family = hostent->h_addrtype;
}
-extern void net_reopen(struct hostent * addr)
+extern void net_reopen(struct mtr_ctl *ctl, struct hostent * addr)
{
int at;
error(EXIT_FAILURE, 0, "net_reopen bad address type");
}
- net_reset ();
- net_send_batch();
+ net_reset (ctl);
+ net_send_batch(ctl);
}
-extern void net_reset(void)
+extern void net_reset(struct mtr_ctl *ctl)
{
int at;
int i;
- batch_at = fstTTL - 1; /* above replacedByMin */
+ batch_at = ctl->fstTTL - 1; /* above replacedByMin */
numhosts = 10;
for (at = 0; at < MaxHost; at++) {
gettimeofday(&reset, NULL);
}
-static int net_set_interfaceaddress_udp(void)
+static int net_set_interfaceaddress_udp(struct mtr_ctl *ctl)
{
struct sockaddr_in * sa4;
struct sockaddr_storage remote;
int s;
memset(&remote, 0, sizeof (remote));
- remote.ss_family = af;
+ remote.ss_family = ctl->af;
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
- addrcpy((void *) &remote4->sin_addr, (void *) remoteaddress, af);
- remote4->sin_port = htons(remoteport);
+ addrcpy((void *) &remote4->sin_addr, (void *) remoteaddress, ctl->af);
+ remote4->sin_port = htons(ctl->remoteport);
len = sizeof (struct sockaddr_in);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
- addrcpy((void *) &remote6->sin6_addr, (void *) remoteaddress, af);
- remote6->sin6_port = htons(remoteport);
+ addrcpy((void *) &remote6->sin6_addr, (void *) remoteaddress, ctl->af);
+ remote6->sin6_port = htons(ctl->remoteport);
len = sizeof (struct sockaddr_in6);
break;
#endif
}
- s = socket (af, SOCK_DGRAM, 0);
+ s = socket (ctl->af, SOCK_DGRAM, 0);
if (s < 0) {
error(EXIT_FAILURE, errno, "udp socket()");
}
getsockname(s, name, &len);
sockaddrtop( name, localaddr, sizeof localaddr );
- switch (af) {
+ switch (ctl->af) {
case AF_INET:
sa4 = (struct sockaddr_in *) name;
- addrcpy((void*)&ssa4->sin_addr, (void *) &(sa4->sin_addr), af );
+ addrcpy((void*)&ssa4->sin_addr, (void *) &(sa4->sin_addr), ctl->af );
break;
#ifdef ENABLE_IPV6
case AF_INET6:
sa6 = (struct sockaddr_in6 *) name;
- addrcpy((void*)&ssa6->sin6_addr, (void *) &(sa6->sin6_addr), af );
+ addrcpy((void*)&ssa6->sin6_addr, (void *) &(sa6->sin6_addr), ctl->af );
break;
#endif
}
}
-extern int net_set_interfaceaddress (char *InterfaceAddress)
+extern int net_set_interfaceaddress (struct mtr_ctl *ctl)
{
#ifdef ENABLE_IPV6
struct sockaddr_storage name_struct;
struct sockaddr * name = (struct sockaddr *) &name_struct;
socklen_t len = 0;
- if (mtrtype == IPPROTO_UDP && remoteport && !InterfaceAddress) {
- return net_set_interfaceaddress_udp();
+ if (ctl->mtrtype == IPPROTO_UDP && ctl->remoteport && !ctl->InterfaceAddress) {
+ return net_set_interfaceaddress_udp(ctl);
}
- if (!InterfaceAddress) return 0;
+ if (!ctl->InterfaceAddress) return 0;
- sourcesockaddr->sa_family = af;
- switch ( af ) {
+ sourcesockaddr->sa_family = ctl->af;
+ switch ( ctl->af ) {
case AF_INET:
ssa4->sin_port = 0;
- if ( inet_aton( InterfaceAddress, &(ssa4->sin_addr) ) < 1 ) {
- error(0, 0, "bad interface address: %s", InterfaceAddress);
+ if ( inet_aton( ctl->InterfaceAddress, &(ssa4->sin_addr) ) < 1 ) {
+ error(0, 0, "bad interface address: %s", ctl->InterfaceAddress);
return( 1 );
}
len = sizeof (struct sockaddr);
#ifdef ENABLE_IPV6
case AF_INET6:
ssa6->sin6_port = 0;
- if ( inet_pton( af, InterfaceAddress, &(ssa6->sin6_addr) ) < 1 ) {
- error(0, 0, "bad interface address: %s", InterfaceAddress);
+ if ( inet_pton( ctl->af, ctl->InterfaceAddress, &(ssa6->sin6_addr) ) < 1 ) {
+ error(0, 0, "bad interface address: %s", ctl->InterfaceAddress);
return( 1 );
}
len = sizeof (struct sockaddr_in6);
}
if ( bind( sendsock, sourcesockaddr, len ) == -1 ) {
- error(0, 0, "failed to bind to interface: %s", InterfaceAddress);
+ error(0, 0, "failed to bind to interface: %s", ctl->InterfaceAddress);
return( 1 );
}
getsockname (sendsock, name, &len);
}
/* check if we got connection or error on any fds */
-extern void net_process_fds(fd_set *writefd)
+extern void net_process_fds(struct mtr_ctl *ctl, fd_set *writefd)
{
int at, fd, r;
struct timeval now;
* (probably) reached the remote address. Anything else happens to the
* connection, we write it off to avoid leaking sockets */
if (r == 1 || errno == ECONNREFUSED)
- net_process_ping(at, mpls, remoteaddress, now);
+ net_process_ping(ctl, at, mpls, remoteaddress, now);
else if (errno != EAGAIN) {
close(fd);
sequence[at].socket = 0;
if (fd > 0) {
struct timeval subtract;
timersub(&now, &sequence[at].time, &subtract);
- if ((subtract.tv_sec * 1000000L + subtract.tv_usec) > tcp_timeout) {
+ if ((subtract.tv_sec * 1000000L + subtract.tv_usec) > ctl->tcp_timeout) {
close(fd);
sequence[at].socket = 0;
}
}
/* for GTK frontend */
-extern void net_harvest_fds(void)
+extern void net_harvest_fds(struct mtr_ctl *ctl)
{
fd_set writefd;
int maxfd = 0;
tv.tv_usec = 0;
net_add_fds(&writefd, &maxfd);
select(maxfd, NULL, &writefd, NULL, &tv);
- net_process_fds(&writefd);
+ net_process_fds(ctl, &writefd);
}
#include <netinet/icmp6.h>
#endif
+#include "mtr.h"
+
extern int net_preopen(void);
-extern int net_selectsocket(void);
-extern int net_open(struct hostent *host);
-extern void net_reopen(struct hostent *address);
-extern int net_set_interfaceaddress (char *InterfaceAddress);
-extern void net_reset(void);
+extern int net_selectsocket(struct mtr_ctl *ctl);
+extern int net_open(struct mtr_ctl *ctl, struct hostent *host);
+extern void net_reopen(struct mtr_ctl *ctl, struct hostent *address);
+extern int net_set_interfaceaddress (struct mtr_ctl *ctl);
+extern void net_reset(struct mtr_ctl *ctl);
extern void net_close(void);
extern int net_waitfd(void);
-extern void net_process_return(void);
-extern void net_harvest_fds(void);
+extern void net_process_return(struct mtr_ctl *ctl);
+extern void net_harvest_fds(struct mtr_ctl *ctl);
-extern int net_max(void);
-extern int net_min(void);
+extern int net_max(struct mtr_ctl *ctl);
+extern int net_min(struct mtr_ctl *ctl);
extern int net_last(int at);
extern ip_t * net_addr(int at);
extern void * net_mpls(int at);
extern ip_t * net_addrs(int at, int i);
extern char *net_localaddr(void);
-extern int net_send_batch(void);
+extern int net_send_batch(struct mtr_ctl *ctl);
extern void net_end_transit(void);
extern int calc_deltatime (float WaitTime);
extern void addrcpy( char * a, char * b, int af );
extern void net_add_fds(fd_set *writefd, int *maxfd);
-extern void net_process_fds(fd_set *writefd);
+extern void net_process_fds(struct mtr_ctl *ctl, fd_set *writefd);
#define MAXPATH 8
#define MaxHost 256
#define MINPACKET 28 /* 20 bytes IP header and 8 bytes ICMP or UDP */
#define MAXLABELS 8 /* http://kb.juniper.net/KB2190 (+ 3 just in case) */
-/* stuff used by display such as report, curses... */
-#define MAXFLD 20 /* max stats fields to display */
-
#if defined (__STDC__) && __STDC__
#define CONST const
#else
extern struct fields data_fields[MAXFLD];
-
/* keys: the value in the array is the index number in data_fields[] */
-extern int fld_index[];
-extern unsigned char fld_active[];
-extern char available_options[];
-
extern ip_t unspec_addr;
/* MPLS label object */
#if 0
-static char *addr_to_str(ip_t addr)
+static char *addr_to_str(struct mtr_ctl *ctl, ip_t addr)
{
static char buf[20];
- sprintf (buf, "%s", strlongip( &addr ));
+ sprintf (buf, "%s", strlongip(ctl, &addr ));
return buf;
}
#endif
}
// Log an echo reply, or a "pong"
-extern void raw_rawping (int host, int msec, int seq)
+extern void raw_rawping (struct mtr_ctl *ctl, int host, int msec, int seq)
{
static int havename[MaxHost];
char *name;
- if (dns && !havename[host]) {
- name = dns_lookup2(net_addr(host));
+ if (ctl->dns && !havename[host]) {
+ name = dns_lookup2(ctl, net_addr(host));
if (name) {
havename[host]++;
printf ("d %d %s\n", host, name);
}
-extern void raw_rawhost (int host, ip_t * ip_addr)
+extern void raw_rawhost (struct mtr_ctl *ctl, int host, ip_t * ip_addr)
{
- printf ("h %d %s\n", host, strlongip( ip_addr ));
+ printf ("h %d %s\n", host, strlongip(ctl, ip_addr));
fflush (stdout);
}
/* Prototypes for raw.c */
extern void raw_rawxmit(int host, int seq);
-extern void raw_rawping(int host, int msec, int seq);
-extern void raw_rawhost(int host, ip_t * addr);
+extern void raw_rawping(struct mtr_ctl *ctl, int host, int msec, int seq);
+extern void raw_rawhost(struct mtr_ctl *ctl, int host, ip_t * addr);
#define MAXLOADBAL 5
-extern int dns;
-extern char LocalHostname[];
-extern char *Hostname;
-extern int fstTTL;
-extern int maxTTL;
-extern int cpacketsize;
-extern int bitpattern;
-extern int tos;
-extern int MaxPing;
-extern int af;
-extern int reportwide;
extern void report_open(void)
printf ("Start: %s\n", t);
}
-static size_t snprint_addr(char *dst, size_t dst_len, ip_t *addr)
+static size_t snprint_addr(struct mtr_ctl *ctl, char *dst, size_t dst_len, ip_t *addr)
{
- if(addrcmp((void *) addr, (void *) &unspec_addr, af)) {
- struct hostent *host = dns ? addr2host((void *) addr, af) : NULL;
- if (!host) return snprintf(dst, dst_len, "%s", strlongip(addr));
- else if (dns && show_ips)
- return snprintf(dst, dst_len, "%s (%s)", host->h_name, strlongip(addr));
+ if(addrcmp((void *) addr, (void *) &unspec_addr, ctl->af)) {
+ struct hostent *host = ctl->dns ? addr2host((void *) addr, ctl->af) : NULL;
+ if (!host) return snprintf(dst, dst_len, "%s", strlongip(ctl, addr));
+ else if (ctl->dns && ctl->show_ips)
+ return snprintf(dst, dst_len, "%s (%s)", host->h_name, strlongip(ctl, addr));
else return snprintf(dst, dst_len, "%s", host->h_name);
} else return snprintf(dst, dst_len, "%s", "???");
}
}
#endif
-extern void report_close(void)
+extern void report_close(struct mtr_ctl *ctl)
{
int i, j, at, max, z, w;
struct mplslen *mpls, *mplss;
size_t len=0;
size_t len_hosts = 33;
- if (reportwide)
+ if (ctl->reportwide)
{
// get the longest hostname
- len_hosts = strlen(LocalHostname);
- max = net_max();
- at = net_min();
+ len_hosts = strlen(ctl->LocalHostname);
+ max = net_max(ctl);
+ at = net_min(ctl);
for (; at < max; at++) {
size_t nlen;
addr = net_addr(at);
- if ((nlen = snprint_addr(name, sizeof(name), addr)))
+ if ((nlen = snprint_addr(ctl, name, sizeof(name), addr)))
if (len_hosts < nlen)
len_hosts = nlen;
}
int len_tmp = len_hosts;
if (ipinfo_no >= 0) {
ipinfo_no %= iiwidth_len;
- if (reportwide) {
+ if (ctl->reportwide) {
len_hosts++; // space
len_tmp += get_iiwidth();
if (!ipinfo_no)
#else
snprintf( fmt, sizeof(fmt), "HOST: %%-%zus", len_hosts);
#endif
- snprintf(buf, sizeof(buf), fmt, LocalHostname);
- len = reportwide ? strlen(buf) : len_hosts;
+ snprintf(buf, sizeof(buf), fmt, ctl->LocalHostname);
+ len = ctl->reportwide ? strlen(buf) : len_hosts;
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j < 0) continue;
snprintf( fmt, sizeof(fmt), "%%%ds", data_fields[j].length );
}
printf("%s\n",buf);
- max = net_max();
- at = net_min();
+ max = net_max(ctl);
+ at = net_min(ctl);
for(; at < max; at++) {
addr = net_addr(at);
mpls = net_mpls(at);
- snprint_addr(name, sizeof(name), addr);
+ snprint_addr(ctl, name, sizeof(name), addr);
#ifdef HAVE_IPINFO
if (is_printii()) {
snprintf(fmt, sizeof(fmt), " %%2d. %%s%%-%zus", len_hosts);
- snprintf(buf, sizeof(buf), fmt, at+1, fmt_ipinfo(addr), name);
+ snprintf(buf, sizeof(buf), fmt, at+1, fmt_ipinfo(ctl, addr), name);
} else {
#endif
snprintf( fmt, sizeof(fmt), " %%2d.|-- %%-%zus", len_hosts);
#ifdef HAVE_IPINFO
}
#endif
- len = reportwide ? strlen(buf) : len_hosts;
+ len = ctl->reportwide ? strlen(buf) : len_hosts;
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active [i]];
+ j = ctl->fld_index[ctl->fld_active [i]];
if (j < 0) continue;
/* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
addr2 = net_addrs(at, z);
mplss = net_mplss(at, z);
int found = 0;
- if ((addrcmp ((void *) &unspec_addr, (void *) addr2, af)) == 0)
+ if ((addrcmp ((void *) &unspec_addr, (void *) addr2, ctl->af)) == 0)
break;
for (w = 0; w < z; w++)
/* Ok... checking if there are ips repeated on same hop */
- if ((addrcmp ((void *) addr2, (void *) net_addrs (at,w), af)) == 0) {
+ if ((addrcmp ((void *) addr2, (void *) net_addrs (at,w), ctl->af)) == 0) {
found = 1;
break;
}
#ifdef HAVE_IPINFO
if (is_printii()) {
- if (mpls->labels && z == 1 && enablempls)
+ if (mpls->labels && z == 1 && ctl->enablempls)
print_mpls(mpls);
- snprint_addr(name, sizeof(name), addr2);
- printf(" %s%s\n", fmt_ipinfo(addr2), name);
- if (enablempls)
+ snprint_addr(ctl, name, sizeof(name), addr2);
+ printf(" %s%s\n", fmt_ipinfo(ctl, addr2), name);
+ if (ctl->enablempls)
print_mpls(mplss);
} else {
#else
int k;
- if (mpls->labels && z == 1 && enablempls) {
+ if (mpls->labels && z == 1 && ctl->enablempls) {
for (k=0; k < mpls->labels; k++) {
printf(" | |+-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
}
}
if (z == 1) {
- printf (" | `|-- %s\n", strlongip(addr2));
- for (k=0; k < mplss->labels && enablempls; k++) {
+ printf (" | `|-- %s\n", strlongip(ctl, addr2));
+ for (k=0; k < mplss->labels && ctl->enablempls; k++) {
printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
}
} else {
- printf (" | |-- %s\n", strlongip(addr2));
- for (k=0; k < mplss->labels && enablempls; k++) {
+ printf (" | |-- %s\n", strlongip(ctl, addr2));
+ for (k=0; k < mplss->labels && ctl->enablempls; k++) {
printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
}
}
/* No multipath */
#ifdef HAVE_IPINFO
if (is_printii()) {
- if (mpls->labels && z == 1 && enablempls)
+ if (mpls->labels && z == 1 && ctl->enablempls)
print_mpls(mpls);
} else {
#else
- if(mpls->labels && z == 1 && enablempls) {
+ if(mpls->labels && z == 1 && ctl->enablempls) {
int k;
for (k=0; k < mpls->labels; k++) {
printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
}
-extern void txt_close(void)
+extern void txt_close(struct mtr_ctl *ctl)
{
- report_close();
+ report_close(ctl);
}
}
-extern void json_close(void)
+extern void json_close(struct mtr_ctl *ctl)
{
int i, j, at, first, max;
ip_t *addr;
printf("{\n");
printf(" \"report\": {\n");
printf(" \"mtr\": {\n");
- printf(" \"src\": \"%s\",\n", LocalHostname);
- printf(" \"dst\": \"%s\",\n", Hostname);
- printf(" \"tos\": \"0x%X\",\n", tos);
- if(cpacketsize >= 0) {
- printf(" \"psize\": \"%d\",\n", cpacketsize);
+ printf(" \"src\": \"%s\",\n", ctl->LocalHostname);
+ printf(" \"dst\": \"%s\",\n", ctl->Hostname);
+ printf(" \"tos\": \"0x%X\",\n", ctl->tos);
+ if(ctl->cpacketsize >= 0) {
+ printf(" \"psize\": \"%d\",\n", ctl->cpacketsize);
} else {
- printf(" \"psize\": \"rand(%d-%d)\",\n",MINPACKET, -cpacketsize);
+ printf(" \"psize\": \"rand(%d-%d)\",\n", MINPACKET, -ctl->cpacketsize);
}
- if( bitpattern>=0 ) {
- printf(" \"bitpattern\": \"0x%02X\",\n", (unsigned char)(bitpattern));
+ if (ctl->bitpattern >= 0) {
+ printf(" \"bitpattern\": \"0x%02X\",\n", (unsigned char)(ctl->bitpattern));
} else {
printf(" \"bitpattern\": \"rand(0x00-FF)\",\n");
}
- printf(" \"tests\": \"%d\"\n", MaxPing);
+ printf(" \"tests\": \"%d\"\n", ctl->MaxPing);
printf(" },\n");
printf(" \"hubs\": [");
- max = net_max();
- at = first = net_min();
+ max = net_max(ctl);
+ at = first = net_min(ctl);
for(; at < max; at++) {
addr = net_addr(at);
- snprint_addr(name, sizeof(name), addr);
+ snprint_addr(ctl, name, sizeof(name), addr);
if(at == first) {
printf("{\n");
printf(" \"count\": \"%d\",\n", at+1);
printf(" \"host\": \"%s\",\n", name);
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
/* Commas */
if(i + 1 == MAXFLD) {
}
-extern void xml_close(void)
+extern void xml_close(struct mtr_ctl *ctl)
{
int i, j, at, max;
ip_t *addr;
char name[81];
printf("<?xml version=\"1.0\"?>\n");
- printf("<MTR SRC=\"%s\" DST=\"%s\"", LocalHostname, Hostname);
- printf(" TOS=\"0x%X\"", tos);
- if(cpacketsize >= 0) {
- printf(" PSIZE=\"%d\"", cpacketsize);
+ printf("<MTR SRC=\"%s\" DST=\"%s\"", ctl->LocalHostname, ctl->Hostname);
+ printf(" TOS=\"0x%X\"", ctl->tos);
+ if(ctl->cpacketsize >= 0) {
+ printf(" PSIZE=\"%d\"", ctl->cpacketsize);
} else {
- printf(" PSIZE=\"rand(%d-%d)\"",MINPACKET, -cpacketsize);
+ printf(" PSIZE=\"rand(%d-%d)\"",MINPACKET, -ctl->cpacketsize);
}
- if( bitpattern>=0 ) {
- printf(" BITPATTERN=\"0x%02X\"", (unsigned char)(bitpattern));
+ if (ctl->bitpattern >= 0) {
+ printf(" BITPATTERN=\"0x%02X\"", (unsigned char)(ctl->bitpattern));
} else {
printf(" BITPATTERN=\"rand(0x00-FF)\"");
}
- printf(" TESTS=\"%d\">\n", MaxPing);
+ printf(" TESTS=\"%d\">\n", ctl->MaxPing);
- max = net_max();
- at = net_min();
+ max = net_max(ctl);
+ at = net_min(ctl);
for(; at < max; at++) {
addr = net_addr(at);
- snprint_addr(name, sizeof(name), addr);
+ snprint_addr(ctl, name, sizeof(name), addr);
printf(" <HUB COUNT=\"%d\" HOST=\"%s\">\n", at+1, name);
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j <= 0) continue; // Field nr 0, " " shouldn't be printed in this method.
strcpy(name, " <%s>");
{
}
-extern void csv_close(time_t now)
+extern void csv_close(struct mtr_ctl *ctl, time_t now)
{
int i, j, at, max;
ip_t *addr;
char name[81];
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j < 0) continue;
}
- max = net_max();
- at = net_min();
+ max = net_max(ctl);
+ at = net_min(ctl);
for(; at < max; at++) {
addr = net_addr(at);
- snprint_addr(name, sizeof(name), addr);
+ snprint_addr(ctl, name, sizeof(name), addr);
- if (at == net_min()) {
+ if (at == net_min(ctl)) {
printf("Mtr_Version,Start_Time,Status,Host,Hop,Ip,");
#ifdef HAVE_IPINFO
if(!ipinfo_no) {
}
#endif
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j < 0) continue;
printf("%s,", data_fields[j].title);
}
#ifdef HAVE_IPINFO
if(!ipinfo_no) {
- char* fmtinfo = fmt_ipinfo(addr);
+ char* fmtinfo = fmt_ipinfo(ctl, addr);
fmtinfo = trim(fmtinfo);
- printf("MTR.%s,%lld,%s,%s,%d,%s,%s", PACKAGE_VERSION, (long long)now, "OK", Hostname,
+ printf("MTR.%s,%lld,%s,%s,%d,%s,%s", PACKAGE_VERSION, (long long)now, "OK", ctl->Hostname,
at+1, name, fmtinfo);
} else
#endif
- printf("MTR.%s,%lld,%s,%s,%d,%s", PACKAGE_VERSION, (long long)now, "OK", Hostname,
+ printf("MTR.%s,%lld,%s,%s,%d,%s", PACKAGE_VERSION, (long long)now, "OK", ctl->Hostname,
at+1, name);
for( i=0; i<MAXFLD; i++ ) {
- j = fld_index[fld_active[i]];
+ j = ctl->fld_index[ctl->fld_active[i]];
if (j < 0) continue;
/* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
/* Prototypes for report.h */
extern void report_open(void);
-extern void report_close(void);
+extern void report_close(struct mtr_ctl *ctl);
extern void txt_open(void);
-extern void txt_close(void);
+extern void txt_close(struct mtr_ctl *ctl);
extern void json_open(void);
-extern void json_close(void);
+extern void json_close(struct mtr_ctl *ctl);
extern void xml_open(void);
-extern void xml_close(void);
+extern void xml_close(struct mtr_ctl *ctl);
extern void csv_open(void);
-extern void csv_close(time_t now);
+extern void csv_close(struct mtr_ctl *ctl, time_t now);
#include "asn.h"
#include "display.h"
-extern int Interactive;
-extern int MaxPing;
-extern int ForceMaxPing;
-extern float WaitTime;
-extern float GraceTime;
-extern int mtrtype;
-
static double dnsinterval;
static struct timeval intervaltime;
int display_offset = 0;
-#define GRACETIME (GraceTime * 1000*1000)
+#define GRACETIME (ctl->GraceTime * 1000*1000)
-extern void select_loop(void) {
+extern void select_loop(struct mtr_ctl *ctl){
fd_set readfd;
fd_set writefd;
int anyset = 0;
gettimeofday(&lasttime, NULL);
while(1) {
- dt = calc_deltatime (WaitTime);
+ dt = calc_deltatime (ctl->WaitTime);
intervaltime.tv_sec = dt / 1000000;
intervaltime.tv_usec = dt % 1000000;
maxfd = 0;
- if(Interactive) {
+ if(ctl->Interactive) {
FD_SET(0, &readfd);
maxfd = 1;
}
#ifdef ENABLE_IPV6
- if (dns) {
+ if (ctl->dns) {
dnsfd6 = dns_waitfd6();
if (dnsfd6 >= 0) {
FD_SET(dnsfd6, &readfd);
} else
dnsfd6 = 0;
#endif
- if (dns) {
+ if (ctl->dns) {
dnsfd = dns_waitfd();
FD_SET(dnsfd, &readfd);
if(dnsfd >= maxfd) maxfd = dnsfd + 1;
FD_SET(netfd, &readfd);
if(netfd >= maxfd) maxfd = netfd + 1;
- if (mtrtype == IPPROTO_TCP)
+ if (ctl->mtrtype == IPPROTO_TCP)
net_add_fds(&writefd, &maxfd);
do {
rv = select(maxfd, (void *)&readfd, &writefd, NULL, &selecttime);
} else {
- if(Interactive) display_redraw();
+ if(ctl->Interactive) display_redraw(ctl);
gettimeofday(&thistime, NULL);
lasttime = thistime;
if (!graceperiod) {
- if (NumPing >= MaxPing && (!Interactive || ForceMaxPing)) {
+ if (NumPing >= ctl->MaxPing && (!ctl->Interactive || ctl->ForceMaxPing)) {
graceperiod = 1;
startgrace = thistime;
}
/* do not send out batch when we've already initiated grace period */
- if (!graceperiod && net_send_batch())
+ if (!graceperiod && net_send_batch(ctl))
NumPing++;
}
}
selecttime.tv_usec += 1000000;
}
- if (dns) {
+ if (ctl->dns) {
if ((selecttime.tv_sec > (time_t)dnsinterval) ||
((selecttime.tv_sec == (time_t)dnsinterval) &&
(selecttime.tv_usec > ((time_t)(dnsinterval * 1000000) % 1000000)))) {
/* Have we got new packets back? */
if(FD_ISSET(netfd, &readfd)) {
- net_process_return();
+ net_process_return(ctl);
anyset = 1;
}
- if (dns) {
+ if (ctl->dns) {
/* Handle any pending resolver events */
- dnsinterval = WaitTime;
+ dnsinterval = ctl->WaitTime;
}
/* Have we finished a nameservice lookup? */
#ifdef ENABLE_IPV6
- if(dns && dnsfd6 && FD_ISSET(dnsfd6, &readfd)) {
+ if(ctl->dns && dnsfd6 && FD_ISSET(dnsfd6, &readfd)) {
dns_ack6();
anyset = 1;
}
#endif
- if(dns && dnsfd && FD_ISSET(dnsfd, &readfd)) {
- dns_ack();
+ if(ctl->dns && dnsfd && FD_ISSET(dnsfd, &readfd)) {
+ dns_ack(ctl);
anyset = 1;
}
/* Has a key been pressed? */
if(FD_ISSET(0, &readfd)) {
- switch (display_keyaction()) {
+ switch (display_keyaction(ctl)) {
case ActionQuit:
return;
break;
case ActionReset:
- net_reset();
+ net_reset(ctl);
break;
case ActionDisplay:
- display_mode = (display_mode + 1) % DisplayModeMAX;
+ ctl->display_mode = (ctl->display_mode + 1) % DisplayModeMAX;
break;
case ActionClear:
- display_clear();
+ display_clear(ctl);
break;
case ActionPause:
paused=1;
paused=0;
break;
case ActionMPLS:
- enablempls = !enablempls;
- display_clear();
+ ctl->enablempls = !ctl->enablempls;
+ display_clear(ctl);
break;
case ActionDNS:
- if (dns) {
- use_dns = !use_dns;
- display_clear();
+ if (ctl->dns) {
+ ctl->use_dns = !ctl->use_dns;
+ display_clear(ctl);
}
break;
#ifdef HAVE_IPINFO
}
/* Check for activity on open sockets */
- if (mtrtype == IPPROTO_TCP)
- net_process_fds(&writefd);
+ if (ctl->mtrtype == IPPROTO_TCP)
+ net_process_fds(ctl, &writefd);
}
return;
}
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-extern void select_loop(void);
+extern void select_loop(struct mtr_ctl *ctl);
#endif
-extern char *Hostname;
-extern int WaitTime;
-extern int af;
-
/* There is 256 hops max in the IP header (coded with a byte) */
#define MAX_LINE_COUNT 256
#define MAX_LINE_SIZE 256
#define DEBUG 0
-extern void split_redraw(void)
+extern void split_redraw(struct mtr_ctl *ctl)
{
int max;
int at;
* If there is less lines than last time, we delete them
* TEST THIS PLEASE
*/
- max = net_max();
+ max = net_max(ctl);
for (i=LineCount; i>max; i--) {
printf("-%d\n", i);
LineCount--;
*/
for(at = 0; at < max; at++) {
addr = net_addr(at);
- if(addrcmp((void*)addr, (void*)&unspec_addr, af)) {
+ if(addrcmp((void*)addr, (void*)&unspec_addr, ctl->af)) {
char str[256], *name;
- if (!(name = dns_lookup(addr)))
- name = strlongip(addr);
- if (show_ips) {
- snprintf(str, sizeof(str), "%s %s", name, strlongip(addr));
+ if (!(name = dns_lookup(ctl, addr)))
+ name = strlongip(ctl, addr);
+ if (ctl->show_ips) {
+ snprintf(str, sizeof(str), "%s %s", name, strlongip(ctl, addr));
name = str;
}
/* May be we should test name's length */
/* Prototypes for split.c */
extern void split_open(void);
extern void split_close(void);
-extern void split_redraw(void);
+extern void split_redraw(struct mtr_ctl *ctl);
extern int split_keyaction(void);