From: Roger Wolff Date: Thu, 23 Mar 2006 00:00:00 +0000 (+0000) Subject: mtr v0.70 X-Git-Tag: v0.70^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1217d66e6b8ccddf3297a5ddf9507c18fb1c14d9;p=thirdparty%2Fmtr.git mtr v0.70 - Antinio submitted a cumulative patch containing some nice improvements. He also submitted an automake patch that causes mtr to no longer compile on my system. I refuse to have mtr "in the dark" that I can't test-compile the dist. source: ftp://ftp.bitwizard.nl/mtr/mtr-0.70.tar.gz --- diff --git a/NEWS b/NEWS index 4ba70ed..4b2967b 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,9 @@ WHAT'S NEW? + v0.70 Antinio submitted a cumulative patch containing some + nice improvements. He also submitted an automake patch + that causes mtr to no longer compile on my system. I + refuse to have mtr "in the dark" that I can't test-compile + the dist. v0.69 make distclean should now also remove "rej" files. Antonio Querubin: update getopt.h . More cleanups using new infrastructure. diff --git a/configure.in b/configure.in index 629f643..0cf10f8 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_INIT(mtr.c) -AM_INIT_AUTOMAKE(mtr, 0.69) +AM_INIT_AUTOMAKE(mtr, 0.70) AC_SUBST(GTK_OBJ) diff --git a/curses.c b/curses.c index f7f5fa1..a2c9272 100644 --- a/curses.c +++ b/curses.c @@ -496,10 +496,10 @@ void mtr_curses_redraw(void) attroff(A_BOLD); 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))); - /* if( packetsize>0 ){ printw("psize=%d ", packetsize); } else { diff --git a/dns.c b/dns.c index 2b746b6..ada3ab2 100644 --- a/dns.c +++ b/dns.c @@ -283,7 +283,7 @@ struct sockaddr_in * from4 = (struct sockaddr_in *) &from_sastruct; struct sockaddr * from = (struct sockaddr *) &from_sastruct; int resfd; -int fromlen = sizeof from_sastruct; +socklen_t fromlen = sizeof from_sastruct; char tempstring[16384+1+1]; char sendstring[1024+1]; @@ -437,7 +437,7 @@ char *strlongip(ip_t * ip) } -int longipstr(char *s, ip_t *dst) +int longipstr( char *s, ip_t *dst, int af ) { #ifdef ENABLE_IPV6 return inet_pton( af, s, dst ); @@ -488,7 +488,7 @@ void dns_open(void) strerror(errno)); exit(-1); } - longipstr( "127.0.0.1", &localhost ); + longipstr( "127.0.0.1", &localhost, AF_INET ); aseed = time(NULL) ^ (time(NULL) << 3) ^ (dword)getpid(); for (i = 0;i < BashSize;i++) { idbash[i] = NULL; @@ -1228,7 +1228,7 @@ void dns_ack(void) 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 */ + (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++) @@ -1357,8 +1357,8 @@ char *dns_lookup(ip_t * 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; + char * p = (char *) ip; + char * b = buf; int i; for ( i = sizeof (struct in6_addr) - 1; i >= 0; i-- ) { @@ -1369,3 +1369,19 @@ void addr2ip6arpa( ip_t * ip, char * buf ) { return; } #endif + +/* Resolve an IP address to a hostname. */ +struct hostent *addr2host( const char *addr, int af ) { + int len = 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 + } + return gethostbyaddr( addr, len, af ); +} diff --git a/dns.h b/dns.h index cbf0006..e33c2d2 100644 --- a/dns.h +++ b/dns.h @@ -32,4 +32,4 @@ struct hostent * dns_forward(char *name); char *strlongip(ip_t * ip); void addr2ip6arpa( ip_t * ip, char * buf ); - +struct hostent *addr2host( const char *addr, int type ); diff --git a/mtr.c b/mtr.c index 7cb02f4..40bbb6a 100644 --- a/mtr.c +++ b/mtr.c @@ -387,12 +387,6 @@ int main(int argc, char **argv) exit(1); } - - if (net_set_interfaceaddress (InterfaceAddress) != 0) { - fprintf (stderr, "mtr: Couldn't set interface addres.\n"); - exit (1); - } - #ifdef ENABLE_IPV6 /* gethostbyname2() is deprecated so we'll use getaddrinfo() instead. */ bzero( &hints, sizeof hints ); @@ -442,6 +436,11 @@ int main(int argc, char **argv) exit(1); } + if (net_set_interfaceaddress (InterfaceAddress) != 0) { + fprintf( stderr, "mtr: Couldn't set interface address.\n" ); + exit( EXIT_FAILURE ); + } + display_open(); dns_open(); diff --git a/net.c b/net.c index 1905ae3..f341fed 100644 --- a/net.c +++ b/net.c @@ -120,9 +120,10 @@ struct sequence { #define MAX_UNKNOWN_HOSTS 5 -/* There is something stupid with BSD. We now detect this automatically */ +/* BSD-derived kernels use host byte order for the IP length and + offset fields when using raw sockets. We detect this automatically at + run-time and do the right thing. */ static int BSDfix = 0; -#define saddr_correction(addr) BSDfix ? addr : 0 static struct nethost host[MaxHost]; static struct sequence sequence[MaxSequence]; @@ -250,6 +251,17 @@ void net_send_query(int index) switch ( 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 ) ) { + perror( "setsockopt IP_TOS" ); + exit( EXIT_FAILURE ); + } + if ( setsockopt( sendsock, IPPROTO_IP, IP_TTL, &ttl, sizeof ttl ) ) { + perror( "setsockopt IP_TTL" ); + exit( EXIT_FAILURE ); + } +#else iphsize = sizeof (struct IPHeader); ip->version = 0x45; @@ -264,7 +276,7 @@ void net_send_query(int index) /* BSD needs the source address here, Linux & others do not... */ addrcpy( (void *) &(ip->saddr), (void *) &(ssa4->sin_addr), AF_INET ); addrcpy( (void *) &(ip->daddr), (void *) remoteaddress, AF_INET ); - +#endif echotype = ICMP_ECHO; salen = sizeof (struct sockaddr_in); break; @@ -277,7 +289,7 @@ void net_send_query(int index) exit( EXIT_FAILURE); } echotype = ICMP6_ECHO_REQUEST; - salen = sizeof (struct sockaddr_storage); + salen = sizeof (struct sockaddr_in6); break; #endif } @@ -300,12 +312,12 @@ void net_send_query(int index) rv = sendto(sendsock, packet, abs(packetsize), 0, remotesockaddr, salen); - if (first && (rv < 0) && (errno == EINVAL)) { + if (first && (rv < 0) && ((errno == EINVAL) || (errno == EMSGSIZE))) { + /* Try the first packet again using host byte order. */ ip->len = abs (packetsize); rv = sendto(sendsock, packet, abs(packetsize), 0, remotesockaddr, salen); if (rv >= 0) { - fprintf (stderr, "You've got a broken (FreeBSD?) system\n"); BSDfix = 1; } } @@ -346,7 +358,7 @@ void net_process_ping(int seq, void * addr, struct timeval now) addrcpy( (void *) &(host[index].addrs[0]), addr, af ); } else { for( i=0; isin6_addr); echoreplytype = ICMP6_ECHO_REPLY; timeexceededtype = ICMP6_TIME_EXCEEDED; @@ -724,7 +736,11 @@ int net_preopen(void) { int trueopt = 1; +#if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL) + sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); +#else sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); +#endif if (sendsock4 < 0) return -1; #ifdef ENABLE_IPV6 @@ -759,7 +775,7 @@ int net_open(struct hostent * host) struct sockaddr_in name_struct; #endif struct sockaddr * name = (struct sockaddr *) &name_struct; - int len; + socklen_t len; net_reset(); @@ -811,10 +827,11 @@ void net_reopen(struct hostent * addr) } remotesockaddr->sa_family = addr->h_addrtype; + addrcpy( (void *) remoteaddress, addr->h_addr, addr->h_addrtype ); switch ( addr->h_addrtype ) { case AF_INET: - addrcpy( (void *) remoteaddress, addr->h_addr, AF_INET ); + addrcpy( (void *) &(rsa4->sin_addr), addr->h_addr, AF_INET ); break; #ifdef ENABLE_IPV6 case AF_INET6: @@ -871,8 +888,7 @@ void net_reset(void) int net_set_interfaceaddress (char *InterfaceAddress) { - int i1, i2, i3, i4; - char dummy; + int len = 0; if (!InterfaceAddress) return 0; @@ -880,29 +896,27 @@ int net_set_interfaceaddress (char *InterfaceAddress) 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); + if ( inet_aton( InterfaceAddress, &(ssa4->sin_addr) ) < 1 ) { + fprintf( stderr, "mtr: bad interface address: %s\n", InterfaceAddress ); + return( 1 ); } - - ((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; + len = sizeof (struct sockaddr); break; #ifdef ENABLE_IPV6 case AF_INET6: ssa6->sin6_port = 0; - inet_pton( af, InterfaceAddress, &(ssa6->sin6_addr) ); + if ( inet_pton( af, InterfaceAddress, &(ssa6->sin6_addr) ) < 1 ) { + fprintf( stderr, "mtr: bad interface address: %s\n", InterfaceAddress ); + return( 1 ); + } + len = sizeof (struct sockaddr_in6); break; #endif } - if (bind(sendsock, sourcesockaddr, sizeof sourcesockaddr_struct) == -1) { + if ( bind( sendsock, sourcesockaddr, len ) == -1 ) { perror("mtr: failed to bind to interface"); - exit(1); + return( 1 ); } return 0; } @@ -967,7 +981,8 @@ void sockaddrtop( struct sockaddr * saddr, char * strptr, size_t len ) { switch ( saddr->sa_family ) { case AF_INET: sa4 = (struct sockaddr_in *) saddr; - strncpy( strptr, inet_ntoa( (struct in_addr) sa4->sin_addr ), len ); + strncpy( strptr, inet_ntoa( (struct in_addr) sa4->sin_addr ), len - 1 ); + strptr[ len - 1 ] = '\0'; return; #ifdef ENABLE_IPV6 case AF_INET6: diff --git a/report.c b/report.c index 41208b9..7a1847e 100644 --- a/report.c +++ b/report.c @@ -77,11 +77,11 @@ void report_close(void) if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) { sprintf(name, "???"); } else { - host = dns?gethostbyaddr( (void *) addr, sizeof(int), AF_INET):NULL; + host = dns ? addr2host( (void *) addr, af ) : NULL; if (host != NULL) { - strncpy(name, host->h_name, 80); - name[80] = 0; + strncpy( name, host->h_name, (sizeof name) - 1 ); + name[ (sizeof name) - 1 ] = '\0'; } else { sprintf(name, "%s", strlongip( addr ) ); } @@ -154,11 +154,11 @@ void xml_close(void) if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) { sprintf(name, "???"); } else { - host = dns?gethostbyaddr( (void *) addr, sizeof(int), AF_INET):NULL; + host = dns ? addr2host( (void *) addr, af ) : NULL; if (host != NULL) { - strncpy(name, host->h_name, 80); - name[80] = 0; + strncpy( name, host->h_name, (sizeof name) - 1 ); + name[ (sizeof name) - 1 ] = '\0'; } else { sprintf(name, "%s", strlongip( addr ) ); } @@ -236,11 +236,11 @@ void csv_close(void) if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) { sprintf(name, "???"); } else { - host = dns?gethostbyaddr( (void *) addr, sizeof(int), AF_INET):NULL; + host = dns ? addr2host( (void *) addr, af ) : NULL; if (host != NULL) { - strncpy(name, host->h_name, 80); - name[80] = 0; + strncpy( name, host->h_name, (sizeof name) - 1 ); + name[ (sizeof name) - 1 ] = '\0'; } else { sprintf(name, "%s", strlongip( addr ) ); }