From: Roger Wolff Date: Tue, 11 Jan 2005 00:00:00 +0000 (+0000) Subject: mtr v0.68 X-Git-Tag: v0.68^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fc3fcefbc29a540def2826790c2f5fc77e5838fa;p=thirdparty%2Fmtr.git mtr v0.68 - included some old patches. - included patch from Antonio Querubin for better IPV6 support restructured some more whitespace. - added mtr.h where "global" things should go. Not finished moving things around, but now that the infrastructure is there, it should be easy. source: ftp://ftp.bitwizard.nl/mtr/mtr-0.68.tar.gz --- diff --git a/AUTHORS b/AUTHORS index 629f1ed..18d452c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -25,6 +25,7 @@ Mike Simons (msimons@moria.simons-clan.com) Aaron Scarisbrick, Craig Milo Rogers (Rogers@ISI.EDU) + Antonio Querubin Russell Nelson (rn-mtr@crynwr.com) Davin Milun (milun@acm.org) Josh Martin (jmartin@columbiaservices.net) diff --git a/Makefile.am b/Makefile.am index ac610ac..d02920f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = img sbin_PROGRAMS = mtr man_MANS = mtr.8 -install-exec-am: +install-exec-hook: chmod u+s $(DESTDIR)$(sbindir)/mtr mtr_SOURCES = mtr.c \ diff --git a/NEWS b/NEWS index 9b4e31c..529ffd7 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,10 @@ WHAT'S NEW? + v0.68 included some old patches. + included patch from Antonio Querubin for better IPV6 support + restructured some more whitespace. + added mtr.h where "global" things should go. Not finished + moving things around, but now that the infrastructure is there, + it should be easy. v0.67 Bad keyboarding by REW caused this one out the door. Sorry. No changes. v0.66 Through the Debian bugtracking system a bug report and diff --git a/configure.in b/configure.in index 4733390..9e52a31 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_INIT(mtr.c) -AM_INIT_AUTOMAKE(mtr, 0.67) +AM_INIT_AUTOMAKE(mtr, 0.68) AC_SUBST(GTK_OBJ) @@ -49,6 +49,10 @@ AC_ARG_ENABLE(gtk2, [ --enable-gtk2 Compile against GTK2 instead of GTK+], WANTS_GTK2=$enableval, WANTS_GTK2=no) +AC_ARG_ENABLE(ipv6, +[ --disable-ipv6 Do not enable IPv6], +WANTS_IPV6=$enableval, WANTS_IPV6=yes) + if test "x$WANTS_GTK" = "xyes"; then if test "x$WANTS_GTK2" = "xyes"; then AM_PATH_GTK_2_0(2.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS" @@ -88,6 +92,10 @@ AC_CHECK_FUNC(res_mkquery, , AC_CHECK_FUNC(herror, , AC_DEFINE(NO_HERROR)) AC_CHECK_FUNC(strerror, , AC_DEFINE(NO_STRERROR)) +AC_CHECK_FUNC(getaddrinfo, +[if test "$WANTS_IPV6" = "yes"; then + AC_DEFINE([ENABLE_IPV6], [], [Define to enable IPv6]) +fi]) dnl Add C flags to display more warnings AC_MSG_CHECKING(for C flags to get more warnings) diff --git a/curses.c b/curses.c index 414f5f2..f7f5fa1 100644 --- a/curses.c +++ b/curses.c @@ -18,6 +18,7 @@ */ #include +#include #ifndef NO_CURSES #include @@ -57,6 +58,7 @@ # define getmaxyx(win,y,x) ((y) = (win)->_maxy + 1, (x) = (win)->_maxx + 1) #endif +#include "mtr.h" #include "mtr-curses.h" #include "display.h" #include "net.h" @@ -72,7 +74,7 @@ extern int packetsize; extern int bitpattern; extern int tos; extern float WaitTime; - +extern int af; void pwcenter(char *str) { @@ -86,7 +88,8 @@ void pwcenter(char *str) printw(str); } -int mtr_curses_keyaction() + +int mtr_curses_keyaction(void) { int c = getch(); int i=0; @@ -119,7 +122,7 @@ int mtr_curses_keyaction() mvprintw(3, 0, "Size Range: %d-%d, <0 random.\n", MINPACKET, MAXPACKET); move(2,20); refresh(); - while ( (c=getch ()) != '\n' && i> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); + printw("%s", strlongip( addr ) ); } attroff(A_BOLD); @@ -330,17 +333,15 @@ void mtr_curses_hosts(int startstat) /* Multi path by Min */ for (i=0; i < MAXPATH; i++ ) { addrs = net_addrs(at, i); - if (addrs == addr) continue; - if (addrs == 0) break; + if ( addrcmp( (void *) addrs, (void *) addr, af ) == 0 ) continue; + if ( addrcmp( (void *) addrs, (void *) &unspec_addr, af ) == 0 ) break; name = dns_lookup(addrs); if (! net_up(at)) attron(A_BOLD); if (name != NULL) { printw("\n %s", name); } else { - printw("\n %d.%d.%d.%d", - (addrs >> 24) & 0xff, (addrs >> 16) & 0xff, - (addrs >> 8) & 0xff, addrs & 0xff); + printw("\n %s", strlongip( addrs ) ); } attroff(A_BOLD); } @@ -354,6 +355,7 @@ void mtr_curses_hosts(int startstat) move(2, 0); } + static double factors[] = { 0.02, 0.05, 0.08, 0.15, 0.33, 0.50, 0.80, 1.00 }; static int scale[8]; static int low_ms, high_ms; @@ -388,6 +390,7 @@ void mtr_gen_scale(void) } } + static const char* block_map = ".123abc>"; void mtr_print_scaled(int ms) @@ -403,6 +406,7 @@ void mtr_print_scaled(int ms) printw(">"); } + void mtr_fill_graph(int at, int cols) { int* saved; @@ -430,9 +434,11 @@ void mtr_fill_graph(int at, int cols) } } + void mtr_curses_graph(int startstat, int cols) { - int max, at, addr, y, x; + int max, at, y, x; + ip_t * addr; char* name; max = net_max(); @@ -452,7 +458,7 @@ void mtr_curses_graph(int startstat, int cols) if (name) { printw("%s", name); } else { - printw("%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) && 0xff, (addr >> 8) & 0xff, addr & 0xff); + printw("%s", strlongip( addr ) ); } attroff(A_BOLD); @@ -465,7 +471,8 @@ void mtr_curses_graph(int startstat, int cols) } } -void mtr_curses_redraw() + +void mtr_curses_redraw(void) { int maxx, maxy; int startstat; @@ -488,7 +495,7 @@ void mtr_curses_redraw() pwcenter("My traceroute [v" VERSION "]"); attroff(A_BOLD); - mvprintw(1, 0, "%s (%s)", LocalHostname, inet_ntoa(*net_localaddr())); + mvprintw(1, 0, "%s (%s)", LocalHostname, net_localaddr()); printw("(tos=0x%X ", tos); printw("psize=%d ", abs(packetsize) ); printw("bitpattern=0x%02X)", (unsigned char)(abs(bitpattern))); @@ -562,7 +569,7 @@ void mtr_curses_redraw() } -void mtr_curses_open() +void mtr_curses_open(void) { initscr(); raw(); @@ -572,14 +579,14 @@ void mtr_curses_open() } -void mtr_curses_close() +void mtr_curses_close(void) { printw("\n"); endwin(); } -void mtr_curses_clear() +void mtr_curses_clear(void) { mtr_curses_close(); mtr_curses_open(); diff --git a/display.c b/display.c index b9502ce..e18374f 100644 --- a/display.c +++ b/display.c @@ -19,12 +19,17 @@ #include #include +#include +#include + +#include "mtr.h" #include "display.h" #include "mtr-curses.h" #include "mtr-gtk.h" #include "report.h" #include "select.h" #include "raw.h" +#include "dns.h" extern int DisplayMode; @@ -71,7 +76,9 @@ void display_detect(int *argc, char ***argv) { #endif } -void display_open() { + +void display_open(void) +{ switch(DisplayMode) { case DisplayReport: @@ -98,7 +105,9 @@ void display_open() { } } -void display_close() { + +void display_close(void) +{ switch(DisplayMode) { case DisplayReport: report_close(); @@ -124,7 +133,9 @@ void display_close() { } } -void display_redraw() { + +void display_redraw(void) +{ switch(DisplayMode) { case DisplayCurses: @@ -141,7 +152,9 @@ void display_redraw() { } } -int display_keyaction() { + +int display_keyaction(void) +{ switch(DisplayMode) { case DisplayCurses: return mtr_curses_keyaction(); @@ -156,7 +169,8 @@ int display_keyaction() { } -void display_rawping(int host, int msec) { +void display_rawping(int host, int msec) +{ switch(DisplayMode) { case DisplayReport: case DisplayTXT: @@ -173,7 +187,8 @@ void display_rawping(int host, int msec) { } -void display_rawhost(int host, int ip_addr) { +void display_rawhost(int host, ip_t *ip_addr) +{ switch(DisplayMode) { case DisplayReport: case DisplayTXT: @@ -190,7 +205,8 @@ void display_rawhost(int host, int ip_addr) { } -void display_loop() { +void display_loop(void) +{ switch(DisplayMode) { case DisplayReport: case DisplayTXT: @@ -208,7 +224,8 @@ void display_loop() { } -void display_clear() { +void display_clear(void) +{ switch(DisplayMode) { case DisplayCurses: mtr_curses_clear(); diff --git a/display.h b/display.h index 648e5b1..d75c27b 100644 --- a/display.h +++ b/display.h @@ -17,6 +17,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + enum { ActionNone, ActionQuit, ActionReset, ActionDisplay, ActionClear, ActionPause, ActionResume, ActionDNS, ActionScrollDown, ActionScrollUp, }; @@ -25,16 +27,14 @@ enum { DisplayReport, DisplayCurses, DisplayGTK, DisplaySplit, /* Prototypes for display.c */ void display_detect(int *argc, char ***argv); -void display_open(); -void display_close(); -void display_redraw(); +void display_open(void); +void display_close(void); +void display_redraw(void); void display_rawping(int hostnum, int msec); -void display_rawhost(int hostnum, int ip_addr); -int display_keyaction(); -void display_loop(); -void display_clear(); +void display_rawhost(int hostnum, ip_t *ip_addr); +int display_keyaction(void); +void display_loop(void); +void display_clear(void); extern int display_mode; -extern int use_dns; -extern int dns; extern int display_offset; /* only used in text mode */ diff --git a/dns.c b/dns.c index 32a96b3..2b746b6 100644 --- a/dns.c +++ b/dns.c @@ -44,7 +44,9 @@ #include #include +#include "mtr.h" #include "dns.h" +#include "net.h" #ifdef NO_STRERROR extern int sys_nerr; @@ -55,6 +57,8 @@ extern char *sys_errlist[]; /* Hmm, it seems Irix requires this */ extern int errno; +extern int af; + /* Defines */ #undef Debug @@ -268,10 +272,18 @@ dword resolvecount = 0; long idseed = 0xdeadbeef; long aseed; -struct sockaddr_in from; +#ifdef ENABLE_IPV6 +struct sockaddr_storage from_sastruct; +struct sockaddr_in6 * from6 = (struct sockaddr_in6 *) &from_sastruct; +#else +struct sockaddr_in from_sastruct; +#endif + +struct sockaddr_in * from4 = (struct sockaddr_in *) &from_sastruct; +struct sockaddr * from = (struct sockaddr *) &from_sastruct; int resfd; -int fromlen = sizeof(struct sockaddr_in); +int fromlen = sizeof from_sastruct; char tempstring[16384+1+1]; char sendstring[1024+1]; @@ -413,28 +425,36 @@ void clearset(fd_set *set) } -char *strlongip(ip_t ip) +char *strlongip(ip_t * ip) { - struct in_addr a; - a.s_addr = htonl(ip); - return inet_ntoa(a); +#ifdef ENABLE_IPV6 + static char buf[INET6_ADDRSTRLEN]; + + return (char *) inet_ntop( af, ip, buf, sizeof buf ); +#else + return inet_ntoa( *ip ); +#endif } -ip_t longipstr(char *s) +int longipstr(char *s, ip_t *dst) { - return inet_addr(s); +#ifdef ENABLE_IPV6 + return inet_pton( af, s, dst ); +#else + return inet_aton( s, dst ); +#endif } -int dns_forward(char *name) +struct hostent * dns_forward(char *name) { struct hostent *host; if ((host = gethostbyname(name))) - return *(int *)host->h_addr; + return host; else - return 0; + return NULL; } @@ -468,7 +488,7 @@ void dns_open(void) strerror(errno)); exit(-1); } - localhost = longipstr("127.0.0.1"); + longipstr( "127.0.0.1", &localhost ); aseed = time(NULL) ^ (time(NULL) << 3) ^ (dword)getpid(); for (i = 0;i < BashSize;i++) { idbash[i] = NULL; @@ -497,9 +517,27 @@ dword getidbash(word id) } -dword getipbash(ip_t ip) +dword getipbash(ip_t * ip) { - return (dword)BashModulo(ip); + char *p = (char *) ip; + int i, len = 0; + dword bashvalue = 0; + + switch ( af ) { + case AF_INET: + len = sizeof (struct in_addr); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + len = sizeof (struct in6_addr); + break; +#endif + } + for (i = 0; i < len; i++, p++) { + bashvalue^= *p; + bashvalue+= (*p >> 1) + (bashvalue >> 1); + } + return BashModulo(bashvalue); } @@ -611,14 +649,18 @@ void linkresolveip(struct resolve *addrp) struct resolve *rp; dword bashnum; - bashnum = getipbash(addrp->ip); + bashnum = getipbash( &(addrp->ip) ); rp = ipbash[bashnum]; if (rp) { - while ((rp->nextip) && (addrp->ip > rp->nextip->ip)) + while ((rp->nextip) && + ( addrcmp( (void *) &(addrp->ip), + (void *) &(rp->nextip->ip), af ) > 0 )) rp = rp->nextip; - while ((rp->previousip) && (addrp->ip < rp->previousip->ip)) + while ((rp->previousip) && + ( addrcmp( (void *) &(addrp->ip), + (void *) &(rp->previousip->ip), af ) < 0 )) rp = rp->previousip; - if (rp->ip < addrp->ip) { + if ( addrcmp( (void *) &(rp->ip), (void *) &(addrp->ip), af ) < 0 ) { addrp->previousip = rp; addrp->nextip = rp->nextip; if (rp->nextip) @@ -641,7 +683,7 @@ void unlinkresolveip(struct resolve *rp) { dword bashnum; - bashnum = getipbash(rp->ip); + bashnum = getipbash( &(rp->ip) ); if (ipbash[bashnum] == rp) ipbash[bashnum] = (rp->previousip)? rp->previousip : rp->nextip; if (rp->nextip) @@ -781,7 +823,7 @@ struct resolve *findhost(char *hostname) } -struct resolve *findip(ip_t ip) +struct resolve *findip(ip_t * ip) { struct resolve *rp; dword bashnum; @@ -789,11 +831,13 @@ struct resolve *findip(ip_t ip) bashnum = getipbash(ip); rp = ipbash[bashnum]; if (rp) { - while ((rp->nextip) && (ip >= rp->nextip->ip)) + while ((rp->nextip) && + ( addrcmp( (void *) ip, (void *) &(rp->nextip->ip), af ) >= 0 )) rp = rp->nextip; - while ((rp->previousip) && (ip <= rp->previousip->ip)) + while ((rp->previousip) && + ( addrcmp( (void *) ip, (void *) &(rp->previousip->ip), af ) <= 0 )) rp = rp->previousip; - if (ip == rp->ip) { + if ( addrcmp( (void *) ip, (void *) &(rp->ip), af ) == 0 ) { ipbash[bashnum] = rp; return rp; } else @@ -838,15 +882,24 @@ void resendrequest(struct resolve *rp,int type) restell(tempstring); } } else if (type == T_PTR) { + switch ( af ) { + case AF_INET: sprintf(tempstring,"%u.%u.%u.%u.in-addr.arpa", ((byte *)&rp->ip)[3], ((byte *)&rp->ip)[2], ((byte *)&rp->ip)[1], ((byte *)&rp->ip)[0]); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + addr2ip6arpa( &(rp->ip), tempstring ); + break; +#endif + } dorequest(tempstring,type,rp->id); if (debug) { sprintf(tempstring,"Resolver: Sent domain lookup request for \"%s\".", - strlongip(rp->ip)); + strlongip( &(rp->ip) )); restell(tempstring); } } @@ -887,7 +940,7 @@ void passrp(struct resolve *rp,long ttl) } -void parserespacket(byte *s,int l) +void parserespacket(byte *s, int l) { struct resolve *rp; packetheader *hp; @@ -898,11 +951,11 @@ void parserespacket(byte *s,int l) word rr,datatype,class,qdatatype,qclass; byte rdatalength; - if (l < sizeof(packetheader)) { + if (l < (int) sizeof(packetheader)) { restell("Resolver error: Packet smaller than standard header size."); return; } - if (l == sizeof(packetheader)) { + if (l == (int) sizeof(packetheader)) { restell("Resolver error: Packet has empty body."); return; } @@ -954,12 +1007,20 @@ void parserespacket(byte *s,int l) case STATE_PTRREQ1: case STATE_PTRREQ2: case STATE_PTRREQ3: + switch ( af ) { + case AF_INET: sprintf(stackstring,"%u.%u.%u.%u.in-addr.arpa", ((byte *)&rp->ip)[3], ((byte *)&rp->ip)[2], ((byte *)&rp->ip)[1], ((byte *)&rp->ip)[0]); break; +#ifdef ENABLE_IPV6 + case AF_INET6: + addr2ip6arpa( &(rp->ip), stackstring ); + break; +#endif + } } *namestring = '\0'; r = dn_expand(s,s + l,c,namestring,MAXDNAME); @@ -1068,17 +1129,17 @@ void parserespacket(byte *s,int l) restell(tempstring); return; } - if (memcmp(&rp->ip,(ip_t *)c,sizeof(ip_t))) { + if ( addrcmp( (void *) &(rp->ip), (void *) c, af ) == 0 ) { sprintf(tempstring,"Resolver: Reverse authentication failed: %s != ", - strlongip(rp->ip)); - memcpy(&alignedip,(ip_t *)c,sizeof(ip_t)); - strcat(tempstring,strlongip(alignedip)); + strlongip( &(rp->ip) )); + addrcpy( (void *) &alignedip, (void *) c, af ); + strcat(tempstring,strlongip( &alignedip )); restell(tempstring); res_hostipmismatch++; failrp(rp); } else { sprintf(tempstring,"Resolver: Reverse authentication complete: %s == \"%s\".", - strlongip(rp->ip),nonull(rp->hostname)); + strlongip( &(rp->ip) ),nonull(rp->hostname)); restell(tempstring); res_reversesuccess++; passrp(rp,ttl); @@ -1157,21 +1218,26 @@ void dns_ack(void) { int r,i; - r = recvfrom(resfd,(byte *)resrecvbuf,MaxPacketsize,0,(struct sockaddr *)&from,&fromlen); + r = recvfrom(resfd,(byte *)resrecvbuf,MaxPacketsize,0, + from, &fromlen); if (r > 0) { /* Check to see if this server is actually one we sent to */ - if (from.sin_addr.s_addr == localhost) { + if ( addrcmp( (void *) &(from4->sin_addr), (void *) &localhost, + (int) AF_INET ) == 0 ) { for (i = 0;i < _res.nscount;i++) - if ((_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr) || - (!_res.nsaddr_list[i].sin_addr.s_addr)) /* 0.0.0.0 replies as 127.0.0.1 */ + if ( addrcmp( (void *) &(_res.nsaddr_list[i].sin_addr), + (void *) &(from4->sin_addr), (int) AF_INET ) == 0 || + addrcmp( (void *) &(_res.nsaddr_list[i].sin_addr), + (void *) &unspec_addr, (int) AF_INET ) != 0 ) /* 0.0.0.0 replies as 127.0.0.1 */ break; } else for (i = 0;i < _res.nscount;i++) - if (_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr) + if ( addrcmp( (void *) &(_res.nsaddr_list[i].sin_addr), + (void *) &(from4->sin_addr), AF_INET ) == 0 ) break; if (i == _res.nscount) { sprintf(tempstring,"Resolver error: Received reply from unknown source: %s", - inet_ntoa(from.sin_addr)); + inet_ntoa(from4->sin_addr )); restell(tempstring); } else parserespacket((byte *)resrecvbuf,r); @@ -1206,7 +1272,8 @@ void dns_events(double *sinterval) case STATE_FAILED: /* Fake TTL has expired */ if (debug) { sprintf(tempstring,"Resolver: Cache record for \"%s\" (%s) has expired. (state: %u) Marked for expire at: %g, time: %g.", - nonull(rp->hostname),strlongip(rp->ip),rp->state,rp->expiretime,sweeptime); + nonull(rp->hostname), strlongip( &(rp->ip) ), + rp->state, rp->expiretime, sweeptime); restell(tempstring); } unlinkresolve(rp); @@ -1240,11 +1307,10 @@ void dns_events(double *sinterval) } -char *dns_lookup2(ip_t ip) +char *dns_lookup2(ip_t * ip) { struct resolve *rp; - ip = htonl(ip); if ((rp = findip(ip))) { if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED)) { if ((rp->state == STATE_FINISHED) && (rp->hostname)) { @@ -1270,16 +1336,16 @@ char *dns_lookup2(ip_t ip) rp = allocresolve(); rp->state = STATE_PTRREQ1; rp->expiretime = sweeptime + ResRetryDelay1; - rp->ip = ip; + addrcpy( (void *) &(rp->ip), (void *) ip, af ); linkresolve(rp); - rp->ip = ip; + addrcpy( (void *) &(rp->ip), (void *) ip, af ); linkresolveip(rp); sendrequest(rp,T_PTR); return NULL; } -char *dns_lookup(ip_t ip) +char *dns_lookup(ip_t * ip) { char *t; @@ -1287,3 +1353,19 @@ char *dns_lookup(ip_t ip) t = dns_lookup2 (ip); return (t&&use_dns)?t:strlongip(ip); } + +#ifdef ENABLE_IPV6 +/* Returns an ip6.arpa character string. */ +void addr2ip6arpa( ip_t * ip, char * buf ) { + unsigned char * p = (char *) ip; + unsigned char * b = buf; + int i; + + for ( i = sizeof (struct in6_addr) - 1; i >= 0; i-- ) { + sprintf( b, "%x.%x.", p[i] % 16, p[i] >> 4 ); + b += 4; + } + sprintf( b, "ip6.arpa" ); + return; +} +#endif diff --git a/dns.h b/dns.h index 8daccb7..cbf0006 100644 --- a/dns.h +++ b/dns.h @@ -17,25 +17,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Typedefs */ - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long dword; - -typedef unsigned int ip_t; - +#include /* Prototypes for dns.c */ -void dns_open(); -int dns_waitfd(); -void dns_ack(); +void dns_open(void); +int dns_waitfd(void); +void dns_ack(void); void dns_events(double *sinterval); -char *dns_lookup(ip_t address); -char *dns_lookup2(ip_t address); -int dns_forward(char *name); -char *strlongip(ip_t ip); +char *dns_lookup(ip_t * address); +char *dns_lookup2(ip_t * address); +struct hostent * dns_forward(char *name); +char *strlongip(ip_t * ip); + +void addr2ip6arpa( ip_t * ip, char * buf ); -extern int dns; diff --git a/getopt.h b/getopt.h index 4ac33b7..2f26893 100644 --- a/getopt.h +++ b/getopt.h @@ -101,7 +101,7 @@ struct option errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ -extern int getopt (); +extern int getopt (void); #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); @@ -115,11 +115,11 @@ extern int _getopt_internal (int argc, char *const *argv, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); +extern int getopt (void); +extern int getopt_long (void); +extern int getopt_long_only (void); -extern int _getopt_internal (); +extern int _getopt_internal (void); #endif /* __STDC__ */ #ifdef __cplusplus diff --git a/gtk.c b/gtk.c index 2d72a29..63e43e5 100644 --- a/gtk.c +++ b/gtk.c @@ -27,9 +27,13 @@ #include #ifndef NO_GTK +#include #include +#include +#include #include +#include "mtr.h" #include "net.h" #include "dns.h" #include "mtr-gtk.h" @@ -37,12 +41,12 @@ #include "img/mtr_icon.xpm" #endif - gint gtk_ping(gpointer data); extern char *Hostname; extern float WaitTime; +extern int af; static int tag; static GtkWidget *Pause_Button; @@ -67,7 +71,8 @@ void gtk_do_init(int *argc, char ***argv) } } -int gtk_detect(int *argc, char ***argv) + +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 @@ -79,14 +84,16 @@ int gtk_detect(int *argc, char ***argv) } } -gint Window_destroy(GtkWidget *Window, gpointer data) + +gint Window_destroy(UNUSED GtkWidget *Window, UNUSED gpointer data) { gtk_main_quit(); return FALSE; } -gint Restart_clicked(GtkWidget *Button, gpointer data) + +gint Restart_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data) { net_reset(); gtk_redraw(); @@ -95,7 +102,7 @@ gint Restart_clicked(GtkWidget *Button, gpointer data) } -gint Pause_clicked(GtkWidget *Button, gpointer data) +gint Pause_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data) { static int paused = 0; @@ -110,6 +117,7 @@ gint Pause_clicked(GtkWidget *Button, gpointer data) return FALSE; } + /* * There is a small problem with the following code: * The timeout is canceled and removed in order to ensure that @@ -119,7 +127,7 @@ gint Pause_clicked(GtkWidget *Button, gpointer data) * What's the problem with this? (-> "I don't think so) -- REW */ -gint WaitTime_changed(GtkAdjustment *Adj, GtkWidget *Button) +gint WaitTime_changed(UNUSED GtkAdjustment *Adj, UNUSED GtkWidget *Button) { WaitTime = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(Button)); gtk_timeout_remove (tag); @@ -129,9 +137,10 @@ gint WaitTime_changed(GtkAdjustment *Adj, GtkWidget *Button) return FALSE; } -gint Host_activate(GtkWidget *Entry, gpointer data) + +gint Host_activate(GtkWidget *Entry, UNUSED gpointer data) { - int addr; + struct hostent * addr; addr = dns_forward(gtk_entry_get_text(GTK_ENTRY(Entry))); if(addr) { @@ -147,6 +156,7 @@ gint Host_activate(GtkWidget *Entry, gpointer data) return FALSE; } + GdkPixmap *gtk_load_pixmap(char **pixmap) { return gdk_pixmap_colormap_create_from_xpm_d(NULL, @@ -154,6 +164,7 @@ GdkPixmap *gtk_load_pixmap(char **pixmap) NULL, NULL, pixmap); } + void Toolbar_fill(GtkWidget *Toolbar) { GtkWidget *Button; @@ -207,6 +218,7 @@ void Toolbar_fill(GtkWidget *Toolbar) gtk_widget_show(Entry); } + char *Report_Text[] = { "Hostname", "Loss", "Rcv", "Snt", "Last", "Best", "Avg", "Worst", "StDev", NULL }; int Report_Positions[] = { 10, 200, 240, 280, 320, 360, 400, 440, 480, 0 }; GtkWidget *Report; @@ -214,7 +226,7 @@ GtkWidget *ReportBody; GtkWidget *GetRow(int index) { - int addr; + ip_t * addr; char *name; GtkWidget *Row, *Label; @@ -222,7 +234,7 @@ GtkWidget *GetRow(int index) addr = net_addr(index); name = "???"; - if(addr != 0) { + if ( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) { name = dns_lookup(addr); if(!name) { /* Actually this is not neccesary: @@ -238,7 +250,8 @@ GtkWidget *GetRow(int index) return Row; } -GtkWidget *Scrollarea_create() + +GtkWidget *Scrollarea_create(void) { GtkWidget *List; GtkWidget *scroll; @@ -265,6 +278,7 @@ GtkWidget *Scrollarea_create() return scroll; } + void gtk_add_row(GtkWidget *List) { int at; @@ -286,10 +300,12 @@ void gtk_add_row(GtkWidget *List) gtk_widget_show(Row); } + void gtk_set_field(GtkCList *List, int row, int ix, char *str) { gtk_clist_set_text(List, row, ix, str); } + //void gtk_set_field_num(GtkCList *List, int row, int ix, char *format, int num) { // changed int to dobule byMin void gtk_set_field_num(GtkCList *List, int row, int ix, char *format, double num) @@ -300,20 +316,20 @@ void gtk_set_field_num(GtkCList *List, int row, int ix, char *format, double num gtk_set_field(List, row, ix, str); } + void gtk_update_row(GtkCList *List, int row) { - int addr; + ip_t *addr; char str[256], *name; GdkColor color; GdkColormap *cmap; addr = net_addr(row); name = "???"; - if(addr != 0) { + if ( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) { name = dns_lookup(addr); if(!name) { - sprintf(str, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); + sprintf(str, "%s", strlongip( addr )); name = str; } } @@ -333,7 +349,7 @@ void gtk_update_row(GtkCList *List, int row) /* the row - net_min() is kind of not clean, need some more work */ gtk_set_field(List, row - net_min(), 0, name); - gtk_set_field_num(List, row - net_min(), 1, "%.0f%%", net_loss(row)/1000.0); + gtk_set_field_num(List, row - net_min(), 1, "%.1f%%", net_loss(row)/1000.0); gtk_set_field_num(List, row - net_min(), 2, "%.0f", net_returned(row)); gtk_set_field_num(List, row - net_min(), 3, "%.0f", net_xmit(row)); @@ -342,10 +358,10 @@ void gtk_update_row(GtkCList *List, int row) gtk_set_field_num(List, row - net_min(), 6, "%.0f", net_avg(row)/1000.0); gtk_set_field_num(List, row - net_min(), 7, "%.0f", net_worst(row)/1000.0); gtk_set_field_num(List, row - net_min(), 8, "%.2f", net_stdev(row)/1000.0); - } -void gtk_redraw() + +void gtk_redraw(void) { int at = net_min(); // changed from 0 to net_min for TTL stuff byMin int max = net_max(); @@ -368,6 +384,7 @@ void gtk_redraw() gtk_clist_thaw(GTK_CLIST(ReportBody)); } + void Window_fill(GtkWidget *Window) { GtkWidget *VBox; @@ -393,7 +410,8 @@ void Window_fill(GtkWidget *Window) gtk_widget_show(VBox); } -void gtk_open() + +void gtk_open(void) { GtkWidget *Window; GdkPixmap *icon; @@ -423,16 +441,19 @@ void gtk_open() gdk_window_set_icon_name(Window->window, "mtr"); } -void gtk_close() + +void gtk_close(void) { } -int gtk_keyaction() + +int gtk_keyaction(void) { return 0; } -gint gtk_ping(gpointer data) + +gint gtk_ping(UNUSED gpointer data) { gtk_redraw(); net_send_batch(); @@ -441,20 +462,21 @@ gint gtk_ping(gpointer data) return TRUE; } -void gtk_net_data(gpointer data, gint fd, GdkInputCondition cond) + +void gtk_net_data(UNUSED gpointer data, UNUSED gint fd, UNUSED GdkInputCondition cond) { net_process_return(); } -void gtk_dns_data(gpointer data, gint fd, GdkInputCondition cond) + +void gtk_dns_data(UNUSED gpointer data, UNUSED gint fd, UNUSED GdkInputCondition cond) { dns_ack(); - gtk_redraw(); } -void gtk_loop() +void gtk_loop(void) { gtk_add_ping_timeout (); gdk_input_add(net_waitfd(), GDK_INPUT_READ, gtk_net_data, NULL); @@ -462,3 +484,5 @@ void gtk_loop() gtk_main(); } + + diff --git a/mtr-curses.h b/mtr-curses.h index d12d878..732a71a 100644 --- a/mtr-curses.h +++ b/mtr-curses.h @@ -18,8 +18,8 @@ */ /* Prototypes for curses.c */ -void mtr_curses_open(); -void mtr_curses_close(); -void mtr_curses_redraw(); -int mtr_curses_keyaction(); -void mtr_curses_clear(); +void mtr_curses_open(void); +void mtr_curses_close(void); +void mtr_curses_redraw(void); +int mtr_curses_keyaction(void); +void mtr_curses_clear(void); diff --git a/mtr-gtk.h b/mtr-gtk.h index fe87bb3..01bc03d 100644 --- a/mtr-gtk.h +++ b/mtr-gtk.h @@ -19,8 +19,8 @@ /* Prototypes for gtk.c */ int gtk_detect(int *argc, char ***argv); -void gtk_open(); -void gtk_close(); -void gtk_redraw(); -int gtk_keyaction(); -void gtk_loop(); +void gtk_open(void); +void gtk_close(void); +void gtk_redraw(void); +int gtk_keyaction(void); +void gtk_loop(void); diff --git a/mtr.8 b/mtr.8 index 89ac76c..d670859 100644 --- a/mtr.8 +++ b/mtr.8 @@ -8,7 +8,7 @@ mtr \- a network diagnostic tool .SH SYNOPSIS .B mtr [\c -.B \-hvrctglsni\c +.B \-hvrctglsni46\c ] [\c .B \-\-help\c @@ -204,6 +204,16 @@ what you want). Use this option to specify the positive number of seconds between ICMP ECHO requests. The default value for this parameter is one second. +.TP +.B \-4 +.br +Use IPv4 only. + +.TP +.B \-6 +.br +Use IPv6 only. + .SH BUGS Some modern routers give a lower priority to ICMP ECHO packets than diff --git a/mtr.c b/mtr.c index fc52824..7cb02f4 100644 --- a/mtr.c +++ b/mtr.c @@ -26,7 +26,9 @@ #include #include #include +#include +#include "mtr.h" #include "mtr-curses.h" #include "getopt.h" #include "display.h" @@ -141,6 +143,8 @@ void parse_arg (int argc, char **argv) { "address", 1, 0, 'a' }, { "first-ttl", 1, 0, 'f' }, /* -f & -m are borrowed from traceroute */ { "max-ttl", 1, 0, 'm' }, + { "inet", 0, 0, '4' }, /* IPv4 only */ + { "inet6", 0, 0, '6' }, /* IPv6 only */ { 0, 0, 0, 0 } }; @@ -148,7 +152,7 @@ void parse_arg (int argc, char **argv) while(1) { /* added f:m:o: byMin */ opt = getopt_long(argc, argv, - "vhrxtglpo:i:c:s:b:Q:na:f:m:", long_options, NULL); + "vhrxtglpo:i:c:s:b:Q:na:f:m:46", long_options, NULL); if(opt == -1) break; @@ -253,6 +257,17 @@ void parse_arg (int argc, char **argv) tos = 0; } break; + case '4': + af = AF_INET; + break; + case '6': +#ifdef ENABLE_IPV6 + af = AF_INET6; + break; +#else + fprintf( stderr, "IPv6 not enabled.\n" ); + break; +#endif } } @@ -288,11 +303,11 @@ void parse_mtr_options (char *string) argv[0] = "mtr"; argc = 1; p = strtok (string, " \t"); - while (p && (argc < (sizeof(argv)/sizeof(argv[0])))) { + while (p != NULL && ((size_t) argc < (sizeof(argv)/sizeof(argv[0])))) { argv[argc++] = p; p = strtok (NULL, " \t"); } - if (p) { + if (p != NULL) { fprintf (stderr, "Warning: extra arguments ignored: %s", p); } @@ -303,13 +318,24 @@ void parse_mtr_options (char *string) int main(int argc, char **argv) { - int traddr; + ip_t * traddr; struct hostent * host = NULL; int net_preopen_result; +#ifdef ENABLE_IPV6 + struct addrinfo hints, *res; + int error; + struct hostent trhost; + char * alptr[2]; + struct sockaddr_in * sa4; + struct sockaddr_in6 * sa6; +#endif /* Get the raw sockets first thing, so we can drop to user euid immediately */ - net_preopen_result = net_preopen (); + if ( ( net_preopen_result = net_preopen () ) ) { + fprintf( stderr, "mtr: unable to get raw sockets.\n" ); + exit( EXIT_FAILURE ); + } /* Now drop to user permissions */ if (setuid(getuid())) { @@ -342,7 +368,7 @@ int main(int argc, char **argv) } if (PrintHelp) { - printf("usage: %s [-hvrctglsni] [--help] [--version] [--report]\n" + printf("usage: %s [-hvrctglsni46] [--help] [--version] [--report]\n" "\t\t[--report-cycles=COUNT] [--curses] [--gtk]\n" "\t\t[--raw] [--split] [--no-dns] [--address interface]\n" /* BL */ "\t\t[--psize=bytes/-p=bytes]\n" /* ok */ @@ -368,40 +394,53 @@ int main(int argc, char **argv) } #ifdef ENABLE_IPV6 - if (af == AF_UNSPEC) { - af = AF_INET6; - host = gethostbyname2(Hostname, af); - if (host == NULL) af = AF_INET; + /* gethostbyname2() is deprecated so we'll use getaddrinfo() instead. */ + bzero( &hints, sizeof hints ); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; + error = getaddrinfo( Hostname, "0", &hints, &res ); + if ( error ) { + perror( gai_strerror(error) ); + exit( EXIT_FAILURE ); } -#endif - - if (host == NULL) { - host = gethostbyname(Hostname); + /* Convert the first addrinfo into a hostent. */ + host = &trhost; + bzero( host, sizeof trhost ); + host->h_name = res->ai_canonname; + host->h_aliases = NULL; + host->h_addrtype = res->ai_family; + af = res->ai_family; + host->h_length = res->ai_addrlen; + host->h_addr_list = alptr; + switch ( af ) { + case AF_INET: + sa4 = (struct sockaddr_in *) res->ai_addr; + alptr[0] = (void *) &(sa4->sin_addr); + break; + case AF_INET6: + sa6 = (struct sockaddr_in6 *) res->ai_addr; + alptr[0] = (void *) &(sa6->sin6_addr); + break; + default: + fprintf( stderr, "mtr unknown address type\n" ); + exit( EXIT_FAILURE ); } - + alptr[1] = NULL; +#else + host = gethostbyname(Hostname); if (host == NULL) { - herror("mtr"); + herror("mtr gethostbyname"); exit(1); } + af = host->h_addrtype; +#endif - switch (af) { - case AF_INET: - traddr = *(int *)host->h_addr; + traddr = (ip_t *) host->h_addr; - if (net_open(traddr) != 0) { + if (net_open(host) != 0) { fprintf(stderr, "mtr: Unable to start net module.\n"); exit(1); } - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - if(net6_open((struct in6_addr *)host->h_addr) != 0) { - printf("mtr: Unable to get raw socket. (Executable not suid?)\n"); - exit(1); - } - break; -#endif - } display_open(); dns_open(); diff --git a/mtr.h b/mtr.h new file mode 100644 index 0000000..5fecd2f --- /dev/null +++ b/mtr.h @@ -0,0 +1,41 @@ +/* + mtr -- a network diagnostic tool + Copyright (C) 1997,1998 Matt Kimball + Copyright (C) 2005 R.E.Wolff@BitWizard.nl + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* Typedefs */ + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; + +#ifdef ENABLE_IPV6 +typedef struct in6_addr ip_t; +#else +typedef struct in_addr ip_t; +#endif + +extern int dns; +extern int use_dns; + +#ifdef __GNUC__ +#define UNUSED __attribute__((__unused__)) +#else +#define UNUSED +#endif + diff --git a/net.c b/net.c index 0ed228e..22861a7 100644 --- a/net.c +++ b/net.c @@ -36,10 +36,12 @@ #include #include #include +#include +#include "mtr.h" #include "net.h" #include "display.h" - +#include "dns.h" /* We can't rely on header files to provide this information, because the fields have different names between, for instance, Linux and @@ -81,8 +83,8 @@ struct IPHeader { #endif struct nethost { - uint32 addr; - uint32 addrs[MAXPATH]; /* for multi paths byMin */ + ip_t addr; + ip_t addrs[MAXPATH]; /* for multi paths byMin */ int xmit; int returned; int sent; @@ -127,13 +129,40 @@ static struct sequence sequence[MaxSequence]; static struct timeval reset = { 0, 0 }; int timestamp; +int sendsock4; +int recvsock4; +int sendsock6; +int recvsock6; int sendsock; int recvsock; -struct sockaddr_in sourceaddress; -struct sockaddr_in remoteaddress; + +#ifdef ENABLE_IPV6 +struct sockaddr_storage sourcesockaddr_struct; +struct sockaddr_storage remotesockaddr_struct; +struct sockaddr_in6 * ssa6 = (struct sockaddr_in6 *) &sourcesockaddr_struct; +struct sockaddr_in6 * rsa6 = (struct sockaddr_in6 *) &remotesockaddr_struct; +#else +struct sockaddr_in sourcesockaddr_struct; +struct sockaddr_in remotesockaddr_struct; +#endif + +struct sockaddr * sourcesockaddr = (struct sockaddr *) &sourcesockaddr_struct; +struct sockaddr * remotesockaddr = (struct sockaddr *) &remotesockaddr_struct; +struct sockaddr_in * ssa4 = (struct sockaddr_in *) &sourcesockaddr_struct; +struct sockaddr_in * rsa4 = (struct sockaddr_in *) &remotesockaddr_struct; + +ip_t * sourceaddress; +ip_t * remoteaddress; /* XXX How do I code this to be IPV6 compatible??? -- REW */ -struct in_addr localaddr; +#ifdef ENABLE_IPV6 +char localaddr[INET6_ADDRSTRLEN]; +#else +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif +char localaddr[INET_ADDRSTRLEN]; +#endif static int batch_at = 0; static int numhosts = 10; @@ -143,7 +172,7 @@ extern int maxTTL; /* last hub to ping byMin*/ extern int packetsize; /* packet size used by ping */ 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 */ /* return the number of microseconds to wait before sending the next @@ -204,50 +233,77 @@ void net_send_query(int index) { /*ok char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader)];*/ char packet[MAXPACKET]; - struct IPHeader *ip; + struct IPHeader *ip = (struct IPHeader *) packet; struct ICMPHeader *icmp; /*ok int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + datasize;*/ int rv; static int first=1; + int ttl, iphsize = 0, echotype = 0, salen = 0; + + ttl = index + 1; if ( packetsize < MINPACKET ) packetsize = MINPACKET; if ( packetsize > MAXPACKET ) packetsize = MAXPACKET; memset(packet, (unsigned char) abs(bitpattern), abs(packetsize)); - ip = (struct IPHeader *)packet; - icmp = (struct ICMPHeader *)(packet + sizeof(struct IPHeader)); + switch ( af ) { + case AF_INET: + iphsize = sizeof (struct IPHeader); ip->version = 0x45; ip->tos = 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 = index + 1; + ip->ttl = ttl; ip->protocol = IPPROTO_ICMP; ip->check = 0; /* BSD needs the source address here, Linux & others do not... */ - ip->saddr = saddr_correction(sourceaddress.sin_addr.s_addr); - ip->daddr = remoteaddress.sin_addr.s_addr; + addrcpy( (void *) &(ip->saddr), (void *) &(ssa4->sin_addr), AF_INET ); + addrcpy( (void *) &(ip->daddr), (void *) remoteaddress, AF_INET ); + + echotype = ICMP_ECHO; + salen = sizeof (struct sockaddr_in); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + iphsize = 0; + if ( setsockopt( sendsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + &ttl, sizeof ttl ) ) { + perror( "setsockopt IPV6_UNICAST_HOPS" ); + exit( EXIT_FAILURE); + } + echotype = ICMP6_ECHO_REQUEST; + salen = sizeof (struct sockaddr_storage); + break; +#endif + } - icmp->type = ICMP_ECHO; + icmp = (struct ICMPHeader *)(packet + iphsize); + icmp->type = echotype; icmp->code = 0; icmp->checksum = 0; icmp->id = getpid(); icmp->sequence = new_sequence(index); + icmp->checksum = checksum(icmp, abs(packetsize) - iphsize); - icmp->checksum = checksum(icmp, abs(packetsize) - sizeof(struct IPHeader)); - ip->check = checksum(ip, abs(packetsize)); + switch ( af ) { + case AF_INET: + ip->check = checksum(packet, abs(packetsize)); + break; + } gettimeofday(&sequence[icmp->sequence].time, NULL); + rv = sendto(sendsock, packet, abs(packetsize), 0, - (struct sockaddr *)&remoteaddress, sizeof(remoteaddress)); + remotesockaddr, salen); if (first && (rv < 0) && (errno == EINVAL)) { ip->len = abs (packetsize); rv = sendto(sendsock, packet, abs(packetsize), 0, - (struct sockaddr *)&remoteaddress, sizeof(remoteaddress)); + remotesockaddr, salen); if (rv >= 0) { fprintf (stderr, "You've got a broken (FreeBSD?) system\n"); BSDfix = 1; @@ -259,7 +315,7 @@ void net_send_query(int index) /* We got a return on something we sent out. Record the address and time. */ -void net_process_ping(int seq, uint32 addr, struct timeval now) +void net_process_ping(int seq, void * addr, struct timeval now) { int index; int totusec; @@ -280,19 +336,25 @@ void net_process_ping(int seq, uint32 addr, struct timeval now) (now.tv_usec - sequence[seq].time.tv_usec); /* impossible? if( totusec < 0 ) totusec = 0 */; - if (host[index].addr == 0) { - host[index].addr = addr; // should be out of if as addr can change - display_rawhost(index, host[index].addr); + if ( addrcmp( (void *) &(host[index].addr), + (void *) &unspec_addr, af ) == 0 ) { + // should be out of if as addr can change + addrcpy( (void *) &(host[index].addr), addr, af ); + display_rawhost(index, (void *) &(host[index].addr)); /* multi paths by Min */ - host[index].addrs[0] = addr; + addrcpy( (void *) &(host[index].addrs[0]), addr, af ); } else { for( i=0; isin_addr); + echoreplytype = ICMP_ECHOREPLY; + timeexceededtype = ICMP_TIME_EXCEEDED; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + fromsockaddrsize = sizeof (struct sockaddr_storage); + fromaddress = (ip_t *) &(fsa6->sin6_addr); + echoreplytype = ICMP6_ECHO_REPLY; + timeexceededtype = ICMP6_TIME_EXCEEDED; + break; +#endif + } - fromaddrsize = sizeof(fromaddr); num = recvfrom(recvsock, packet, MAXPACKET, 0, - (struct sockaddr *)&fromaddr, &fromaddrsize); + fromsockaddr, &fromsockaddrsize); - if(num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader)) - return; + switch ( af ) { + case AF_INET: + if((size_t) num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader)) + return; + header = (struct ICMPHeader *)(packet + sizeof(struct IPHeader)); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + if(num < sizeof(struct ICMPHeader)) + return; - header = (struct ICMPHeader *)(packet + sizeof(struct IPHeader)); - if(header->type == ICMP_ECHOREPLY) { + header = (struct ICMPHeader *) packet; + break; +#endif + } + if (header->type == echoreplytype) { if(header->id != (uint16)getpid()) return; - net_process_ping(header->sequence, fromaddr.sin_addr.s_addr, now); - } else if(header->type == ICMP_TIME_EXCEEDED) { - if(num < sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + - sizeof(struct IPHeader) + sizeof(struct ICMPHeader)) - return; - - header = (struct ICMPHeader *)(packet + sizeof(struct IPHeader) + - sizeof(struct ICMPHeader) + sizeof(struct IPHeader)); - if(header->id != (uint16)getpid()) + net_process_ping (header->sequence, (void *) fromaddress, now); + } else if (header->type == timeexceededtype) { + switch ( af ) { + case AF_INET: + + if ((size_t) num < sizeof(struct IPHeader) + + sizeof(struct ICMPHeader) + + sizeof (struct IPHeader) + + sizeof (struct ICMPHeader)) + return; + header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) + + sizeof (struct ICMPHeader) + + sizeof (struct IPHeader)); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + if ( num < sizeof (struct ICMPHeader) + + sizeof (struct ip6_hdr) + sizeof (struct ICMPHeader) ) + return; + header = (struct ICMPHeader *) ( packet + + sizeof (struct ICMPHeader) + + sizeof (struct ip6_hdr) ); + break; +#endif + } + + if (header->id != (uint16)getpid()) return; - net_process_ping(header->sequence, fromaddr.sin_addr.s_addr, now); + net_process_ping(header->sequence, (void *)fromaddress, now); } } -int net_addr(int at) { - return ntohl(host[at].addr); +ip_t *net_addr(int at) +{ + return (ip_t *)&(host[at].addr); } -int net_addrs(int at, int i) { - return ntohl(host[at].addrs[i]); +ip_t *net_addrs(int at, int i) +{ + return (ip_t *)&(host[at].addrs[i]); } - int net_loss(int at) { if ((host[at].xmit - host[at].transit) == 0) @@ -484,7 +600,7 @@ int net_jinta(int at) /* end jitter */ -int net_max() +int net_max(void) { int at; int max; @@ -493,9 +609,11 @@ int net_max() // replacedByMin // for(at = 0; at < MaxHost-2; at++) { for(at = 0; at < maxTTL-1; at++) { - if(host[at].addr == remoteaddress.sin_addr.s_addr) { + if ( addrcmp( (void *) &(host[at].addr), + (void *) remoteaddress, af ) == 0 ) { return at + 1; - } else if(host[at].addr != 0) { + } else if ( addrcmp( (void *) &(host[at].addr), + (void *) &unspec_addr, af ) != 0 ) { max = at + 2; } } @@ -505,7 +623,7 @@ int net_max() /* add by Min (wonder its named net_min;-)) because of ttl stuff */ -int net_min () +int net_min (void) { return ( fstTTL - 1 ); } @@ -536,13 +654,13 @@ int net_up(int at) } -struct in_addr *net_localaddr (void) +char * net_localaddr (void) { - return &localaddr; + return localaddr; } -void net_end_transit() +void net_end_transit(void) { int at; @@ -551,7 +669,7 @@ void net_end_transit() } } -int net_send_batch() +int net_send_batch(void) { int n_unknown=0, i; @@ -571,7 +689,7 @@ int net_send_batch() net_send_query(batch_at); for (i=fstTTL-1;i MAX_UNKNOWN_HOSTS) || // or reach limit @@ -600,53 +720,89 @@ int net_send_batch() } -int net_preopen() +int net_preopen(void) { int trueopt = 1; - sendsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - if (sendsock < 0) + sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (sendsock4 < 0) + return -1; +#ifdef ENABLE_IPV6 + sendsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + if (sendsock6 < 0) return -1; +#endif #ifdef IP_HDRINCL /* FreeBSD wants this to avoid sending out packets with protocol type RAW to the network. */ - if (setsockopt(sendsock, SOL_IP, IP_HDRINCL, &trueopt, sizeof(trueopt))) { + if (setsockopt(sendsock4, SOL_IP, IP_HDRINCL, &trueopt, sizeof(trueopt))) { perror("setsockopt(IP_HDRINCL,1)"); return -1; } -#endif +#endif /* IP_HDRINCL */ - recvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (recvsock < 0) + recvsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (recvsock4 < 0) return -1; +#ifdef ENABLE_IPV6 + recvsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + if (recvsock6 < 0) + return -1; +#endif return 0; } -int net_open(int addr) +int net_open(struct hostent * host) { - struct sockaddr_in name; +#ifdef ENABLE_IPV6 + struct sockaddr_storage name_struct; +#else + struct sockaddr_in name_struct; +#endif + struct sockaddr * name = (struct sockaddr *) &name_struct; int len; net_reset(); - remoteaddress.sin_family = AF_INET; - remoteaddress.sin_addr.s_addr = addr; + remotesockaddr->sa_family = host->h_addrtype; + + switch ( host->h_addrtype ) { + case AF_INET: + sendsock = sendsock4; + recvsock = recvsock4; + addrcpy( (void *) &(rsa4->sin_addr), host->h_addr, AF_INET ); + sourceaddress = (ip_t *) &(ssa4->sin_addr); + remoteaddress = (ip_t *) &(rsa4->sin_addr); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + sendsock = sendsock6; + recvsock = recvsock6; + addrcpy( (void *) &(rsa6->sin6_addr), host->h_addr, AF_INET6 ); + sourceaddress = (ip_t *) &(ssa6->sin6_addr); + remoteaddress = (ip_t *) &(rsa6->sin6_addr); + break; +#endif + default: + fprintf( stderr, "net_open bad address type\n" ); + exit( EXIT_FAILURE ); + } - len = sizeof (name); - getsockname (recvsock, (struct sockaddr *)&name, &len); - localaddr = name.sin_addr; + len = sizeof name_struct; + getsockname (recvsock, name, &len); + sockaddrtop( name, localaddr, sizeof localaddr ); #if 0 - printf ("got localaddr: %x\n", *(int *)&localaddr); + printf ("got localaddr: %s\n", localaddr); #endif return 0; } -void net_reopen(int addr) +void net_reopen(struct hostent * addr) { int at; @@ -654,15 +810,28 @@ void net_reopen(int addr) memset(&host[at], 0, sizeof(host[at])); } - remoteaddress.sin_family = AF_INET; - remoteaddress.sin_addr.s_addr = addr; + remotesockaddr->sa_family = addr->h_addrtype; + + switch ( addr->h_addrtype ) { + case AF_INET: + addrcpy( (void *) remoteaddress, addr->h_addr, AF_INET ); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + addrcpy( (void *) &(rsa6->sin6_addr), addr->h_addr, AF_INET6 ); + break; +#endif + default: + fprintf( stderr, "net_reopen bad address type\n" ); + exit( EXIT_FAILURE ); + } net_reset (); net_send_batch(); } -void net_reset() +void net_reset(void) { int at; int i; @@ -707,21 +876,31 @@ int net_set_interfaceaddress (char *InterfaceAddress) if (!InterfaceAddress) return 0; - sourceaddress.sin_family = AF_INET; - sourceaddress.sin_port = 0; - sourceaddress.sin_addr.s_addr = 0; + sourcesockaddr->sa_family = af; + switch ( af ) { + case AF_INET: + ssa4->sin_port = 0; + ssa4->sin_addr.s_addr = 0; if(sscanf(InterfaceAddress, "%u.%u.%u.%u%c", &i1, &i2, &i3, &i4, &dummy) != 4) { printf("mtr: bad interface address: %s\n", InterfaceAddress); exit(1); } - ((unsigned char*)&sourceaddress.sin_addr)[0] = i1; - ((unsigned char*)&sourceaddress.sin_addr)[1] = i2; - ((unsigned char*)&sourceaddress.sin_addr)[2] = i3; - ((unsigned char*)&sourceaddress.sin_addr)[3] = i4; + ((unsigned char*)&ssa4->sin_addr)[0] = i1; + ((unsigned char*)&ssa4->sin_addr)[1] = i2; + ((unsigned char*)&ssa4->sin_addr)[2] = i3; + ((unsigned char*)&ssa4->sin_addr)[3] = i4; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + ssa6->sin6_port = 0; + inet_pton( af, InterfaceAddress, &(ssa6->sin6_addr) ); + break; +#endif + } - if(bind(sendsock, (struct sockaddr*)&sourceaddress, sizeof(sourceaddress)) == -1) { + if (bind(sendsock, sourcesockaddr, sizeof sourcesockaddr_struct) == -1) { perror("mtr: failed to bind to interface"); exit(1); } @@ -730,26 +909,26 @@ int net_set_interfaceaddress (char *InterfaceAddress) -void net_close() +void net_close(void) { close(sendsock); close(recvsock); } -int net_waitfd() +int net_waitfd(void) { return recvsock; } -int* net_saved_pings(int at) +int* net_saved_pings(int at) { return host[at].saved; } -void net_save_increment() +void net_save_increment(void) { int at; for (at = 0; at < MaxHost; at++) { @@ -760,7 +939,7 @@ void net_save_increment() } -void net_save_xmit(int at) +void net_save_xmit(int at) { if (host[at].saved[SAVED_PINGS-1] != -2) net_save_increment(); @@ -768,7 +947,7 @@ void net_save_xmit(int at) } -void net_save_return(int at, int seq, int ms) +void net_save_return(int at, int seq, int ms) { int idx; idx = seq - host[at].saved_seq_offset; @@ -777,3 +956,61 @@ void net_save_return(int at, int seq, int ms) } host[at].saved[idx] = ms; } + +/* Similar to inet_ntop but uses a sockaddr as it's argument. */ +void sockaddrtop( struct sockaddr * saddr, char * strptr, size_t len ) { + struct sockaddr_in * sa4; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 * sa6; +#endif + + switch ( saddr->sa_family ) { + case AF_INET: + sa4 = (struct sockaddr_in *) saddr; + strncpy( strptr, inet_ntoa( (struct in_addr) sa4->sin_addr ), len ); + return; +#ifdef ENABLE_IPV6 + case AF_INET6: + sa6 = (struct sockaddr_in6 *) saddr; + inet_ntop( sa6->sin6_family, &(sa6->sin6_addr), strptr, len ); + return; +#endif + default: + fprintf( stderr, "sockaddrtop unknown address type\n" ); + strptr[0] = '\0'; + return; + } +} + +/* Address comparison. */ +int addrcmp( char * a, char * b, int af ) { + int rc = -1; + + switch ( af ) { + case AF_INET: + rc = memcmp( a, b, sizeof (struct in_addr) ); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + rc = memcmp( a, b, sizeof (struct in6_addr) ); + break; +#endif + } + + return rc; +} + +/* Address copy. */ +void addrcpy( char * a, char * b, int af ) { + + switch ( af ) { + case AF_INET: + memcpy( a, b, sizeof (struct in_addr) ); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + memcpy( a, b, sizeof (struct in6_addr) ); + break; +#endif + } +} diff --git a/net.h b/net.h index 3042f37..db43973 100644 --- a/net.h +++ b/net.h @@ -18,20 +18,32 @@ */ /* Prototypes for functions in net.c */ +#include +#include +#include +#include +#ifdef ENABLE_IPV6 +#include +#include +#endif -int net_preopen(); -int net_open(int address); -void net_reopen(int address); +int net_preopen(void); +int net_open(struct hostent *host); +void net_reopen(struct hostent *address); int net_set_interfaceaddress (char *InterfaceAddress); -void net_reset(); -void net_close(); -int net_waitfd(); -void net_process_return(); +void net_reset(void); +void net_close(void); +int net_waitfd(void); +void net_process_return(void); int net_max(void); int net_min(void); int net_last(int at); -int net_addr(int at); +#ifdef ENABLE_IPV6 +struct in6_addr * net_addr(int at); +#else +struct in_addr * net_addr(int at); +#endif int net_loss(int at); int net_drop(int at); int net_last(int at); @@ -44,11 +56,15 @@ int net_jitter(int at); int net_jworst(int at); int net_javg(int at); int net_jinta(int at); -int net_addrs(int at, int i); -struct in_addr *net_localaddr(void); +#ifdef ENABLE_IPV6 +struct in6_addr * net_addrs(int at, int i); +#else +struct in_addr * net_addrs(int at, int i); +#endif +char *net_localaddr(void); -int net_send_batch(); -void net_end_transit(); +int net_send_batch(void); +void net_end_transit(void); int calc_deltatime (float WaitTime); @@ -66,6 +82,10 @@ void net_save_xmit(int at); void net_save_return(int at, int seq, int ms); int net_duplicate(int at, int seq); +void sockaddrtop( struct sockaddr * saddr, char * strptr, size_t len ); +int addrcmp( char * a, char * b, int af ); +void addrcpy( char * a, char * b, int af ); + #define MAXPATH 8 #define MaxHost 256 #define MaxSequence 65536 @@ -104,3 +124,8 @@ extern int fld_index[]; extern unsigned char fld_active[]; extern char available_options[]; +#ifdef ENABLE_IPV6 +struct in6_addr unspec_addr; +#else +struct in_addr unspec_addr; +#endif diff --git a/raw.c b/raw.c index 65c1129..1674167 100644 --- a/raw.c +++ b/raw.c @@ -19,30 +19,31 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include +#include #include #include #include +#include "mtr.h" #include "raw.h" #include "net.h" #include "dns.h" static int havename[MaxHost]; +extern int af; + #if 0 -static char *addr_to_str(int addr) +static char *addr_to_str(ip_t addr) { static char buf[20]; - sprintf (buf, "%d.%d.%d.%d", - (addr >> 0) & 0xff, - (addr >> 8) & 0xff, - (addr >> 16) & 0xff, - (addr >> 24) & 0xff); + sprintf (buf, "%s", strlongip( &addr )); return buf; } #endif @@ -63,17 +64,8 @@ void raw_rawping (int host, int msec) } -void raw_rawhost (int host, int ip_addr) +void raw_rawhost (int host, ip_t * ip_addr) { - struct in_addr in; - - in.s_addr = ip_addr; - - printf ("h %d %s\n", - host, inet_ntoa(in)); + printf ("h %d %s\n", host, strlongip( ip_addr )); fflush (stdout); } - - - - diff --git a/raw.h b/raw.h index 710aabe..4020e5a 100644 --- a/raw.h +++ b/raw.h @@ -21,4 +21,8 @@ /* Prototypes for raw.c */ void raw_rawping(int host, int msec); -void raw_rawhost(int host, int addr); +#ifdef ENABLE_IPV6 +void raw_rawhost(int host, struct in6_addr * addr); +#else +void raw_rawhost(int host, struct in_addr * addr); +#endif diff --git a/report.c b/report.c index b979650..41208b9 100644 --- a/report.c +++ b/report.c @@ -24,9 +24,12 @@ #include #include #include +#include +#include "mtr.h" #include "report.h" #include "net.h" +#include "dns.h" extern int dns; extern char LocalHostname[]; @@ -37,12 +40,18 @@ extern int packetsize; extern int bitpattern; extern int tos; extern int MaxPing; +extern int af; -void report_open() {} -void report_close() { - int i, j, at, max, addr; - int haddr; +void report_open(void) +{ +} + + +void report_close(void) +{ + int i, j, at, max; + ip_t *addr; char name[81]; char buf[1024]; char fmt[16]; @@ -65,18 +74,16 @@ void report_close() { for(; at < max; at++) { addr = net_addr(at); - if(addr == 0) { + if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) { sprintf(name, "???"); } else { - haddr = htonl(addr); - host = dns?gethostbyaddr((char *)&haddr, sizeof(int), AF_INET):NULL; + host = dns?gethostbyaddr( (void *) addr, sizeof(int), AF_INET):NULL; if (host != NULL) { strncpy(name, host->h_name, 80); name[80] = 0; } else { - sprintf(name, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); + sprintf(name, "%s", strlongip( addr ) ); } } @@ -99,15 +106,29 @@ void report_close() { printf("%s\n",buf); } } -void txt_open() {} -void txt_close() { report_close(); } +void txt_open(void) +{ +} + + +void txt_close(void) +{ + report_close(); +} + + + +void xml_open(void) +{ +} + -void xml_open() {} -void xml_close() { - int i, j, at, max, addr; - int haddr; +void xml_close(void) +{ + int i, j, at, max; + ip_t *addr; char name[81]; struct hostent *host; @@ -130,18 +151,16 @@ void xml_close() { for(; at < max; at++) { addr = net_addr(at); - if(addr == 0) { + if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) { sprintf(name, "???"); } else { - haddr = htonl(addr); - host = dns?gethostbyaddr((char *)&haddr, sizeof(int), AF_INET):NULL; + host = dns?gethostbyaddr( (void *) addr, sizeof(int), AF_INET):NULL; if (host != NULL) { strncpy(name, host->h_name, 80); name[80] = 0; } else { - sprintf(name, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); + sprintf(name, "%s", strlongip( addr ) ); } } @@ -171,10 +190,16 @@ void xml_close() { printf("\n"); } -void csv_open() {} -void csv_close() { - int i, j, at, max, addr; - int haddr; + +void csv_open(void) +{ +} + + +void csv_close(void) +{ + int i, j, at, max; + ip_t *addr; char name[81]; struct hostent *host; @@ -208,18 +233,16 @@ void csv_close() { for(; at < max; at++) { addr = net_addr(at); - if(addr == 0) { + if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) { sprintf(name, "???"); } else { - haddr = htonl(addr); - host = dns?gethostbyaddr((char *)&haddr, sizeof(int), AF_INET):NULL; + host = dns?gethostbyaddr( (void *) addr, sizeof(int), AF_INET):NULL; if (host != NULL) { strncpy(name, host->h_name, 80); name[80] = 0; } else { - sprintf(name, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); + sprintf(name, "%s", strlongip( addr ) ); } } diff --git a/report.h b/report.h index b402f9b..4e8fd1c 100644 --- a/report.h +++ b/report.h @@ -19,11 +19,11 @@ /* Prototypes for report.h */ -void report_open(); -void report_close(); -void txt_open(); -void txt_close(); -void xml_open(); -void xml_close(); -void csv_open(); -void csv_close(); +void report_open(void); +void report_close(void); +void txt_open(void); +void txt_close(void); +void xml_open(void); +void xml_close(void); +void csv_open(void); +void csv_close(void); diff --git a/select.c b/select.c index 7136582..3577c9c 100644 --- a/select.c +++ b/select.c @@ -29,6 +29,7 @@ #include #include +#include "mtr.h" #include "display.h" #include "dns.h" #include "net.h" @@ -43,7 +44,7 @@ static struct timeval intervaltime; int display_offset = 0; -void select_loop() { +void select_loop(void) { fd_set readfd; int anyset = 0; int maxfd = 0; @@ -116,11 +117,13 @@ void select_loop() { selecttime.tv_usec += 1000000; } - if ((selecttime.tv_sec > (time_t)dnsinterval) || - ((selecttime.tv_sec == (time_t)dnsinterval) && - (selecttime.tv_usec > ((time_t)(dnsinterval * 1000000) % 1000000)))) { - selecttime.tv_sec = (time_t)dnsinterval; - selecttime.tv_usec = (time_t)(dnsinterval * 1000000) % 1000000; + if (dns) { + if ((selecttime.tv_sec > (time_t)dnsinterval) || + ((selecttime.tv_sec == (time_t)dnsinterval) && + (selecttime.tv_usec > ((time_t)(dnsinterval * 1000000) % 1000000)))) { + selecttime.tv_sec = (time_t)dnsinterval; + selecttime.tv_usec = (time_t)(dnsinterval * 1000000) % 1000000; + } } rv = select(maxfd, (void *)&readfd, NULL, NULL, &selecttime); diff --git a/select.h b/select.h index 33a9a96..03876e5 100644 --- a/select.h +++ b/select.h @@ -17,4 +17,4 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -void select_loop(); +void select_loop(void); diff --git a/split.c b/split.c index 7e01124..e49bc6b 100644 --- a/split.c +++ b/split.c @@ -21,20 +21,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include #include +#include +#include "mtr.h" #include "display.h" #include "dns.h" #include "net.h" #include "split.h" - -#include - #ifdef NO_CURSES #include #include @@ -57,6 +57,7 @@ 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 @@ -68,11 +69,12 @@ int LineCount; #define DEBUG 0 -void -split_redraw() { + +void split_redraw(void) +{ int max; int at; - int addr; + ip_t *addr; char *name; char newLine[MAX_LINE_SIZE]; int i; @@ -97,7 +99,7 @@ split_redraw() { for(at = 0; at < max; at++) { addr = net_addr(at); - if(addr != 0) { + if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) { name = dns_lookup(addr); if(name != NULL) { /* May be we should test name's length */ @@ -107,9 +109,8 @@ split_redraw() { net_best(at) /1000, net_avg(at)/1000, net_worst(at)/1000); } else { - sprintf(newLine, "%d.%d.%d.%d %d %d %d %d %d %d", - (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff, + sprintf(newLine, "%s %d %d %d %d %d %d", + strlongip( addr ), net_loss(at), net_returned(at), net_xmit(at), net_best(at) /1000, net_avg(at)/1000, @@ -135,8 +136,9 @@ split_redraw() { } } -void -split_open() { + +void split_open(void) +{ int i; #if DEBUG printf("split_open()\n"); @@ -147,15 +149,17 @@ split_open() { } } -void -split_close() { + +void split_close(void) +{ #if DEBUG printf("split_close()\n"); #endif } -int -split_keyaction() { + +int split_keyaction(void) +{ #ifdef NO_CURSES fd_set readfds; struct timeval tv; diff --git a/split.h b/split.h index ad4f318..2a19eb9 100644 --- a/split.h +++ b/split.h @@ -20,7 +20,7 @@ */ /* Prototypes for split.c */ -void split_open(); -void split_close(); -void split_redraw(); -int split_keyaction(); +void split_open(void); +void split_close(void); +void split_redraw(void); +int split_keyaction(void);