diff --git a/SRC/AUTHORS b/SRC/AUTHORS index 2494097..cd36f5f 100644 --- a/SRC/AUTHORS +++ b/SRC/AUTHORS @@ -3,9 +3,9 @@ Stephane Bortzmeyer With help from: -W. Richard Stevens, author of the book "Unix network programming" -for his book and his many examples (a lot of the code comes from -him by copy-and-paste). +The late W. Richard Stevens, author of the book "Unix network +programming" for his book and his many examples (a lot of the code +comes from him by copy-and-paste). Pierre Beyssac author of the "bing" tool for examples of code and beta-testing. @@ -19,6 +19,9 @@ and porting. Glen Turner for the Type Of Service code. +Munechika Sumikawa , from the KAME +project, for the getaddrinfo() code, necessary for IPv6 support. + The Pasteur Institute because the work was done when working on the French national Web cache project, while being an employee of the Institute. @@ -27,3 +30,4 @@ Institute. $Id$ + diff --git a/SRC/config.h.in b/SRC/config.h.in index 704f23a..05a5357 100644 --- a/SRC/config.h.in +++ b/SRC/config.h.in @@ -18,8 +18,8 @@ /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME -/* Define if you have the gethostbyname function. */ -#undef HAVE_GETHOSTBYNAME +/* Define if you have the getaddrinfo function. */ +#undef HAVE_GETADDRINFO /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY diff --git a/SRC/configure b/SRC/configure index c1ce3a9..0689168 100755 --- a/SRC/configure +++ b/SRC/configure @@ -705,7 +705,7 @@ fi PACKAGE=echoping -VERSION=4.2.0-BETA +VERSION=5.0.0-BETA if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -1866,7 +1866,7 @@ fi fi -for ac_func in gettimeofday socket gethostbyname sigaction +for ac_func in gettimeofday socket sigaction do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1873: checking for $ac_func" >&5 @@ -1977,11 +1977,66 @@ else fi done +for ac_func in getaddrinfo +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1984: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + if test "$OPENSSL" = "1"; then echo $ac_n "checking for SSL_CTX_new in -lssl""... $ac_c" 1>&6 -echo "configure:1985: checking for SSL_CTX_new in -lssl" >&5 +echo "configure:2040: checking for SSL_CTX_new in -lssl" >&5 ac_lib_var=`echo ssl'_'SSL_CTX_new | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1990,7 +2045,7 @@ else LIBS="-lssl -lcrypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2025,9 +2080,9 @@ fi fi echo $ac_n "checking T/TCP""... $ac_c" 1>&6 -echo "configure:2029: checking T/TCP" >&5 +echo "configure:2084: checking T/TCP" >&5 cat > conftest.$ac_ext < #include @@ -2036,7 +2091,7 @@ int main() { int foobar = MSG_EOF; ; return 0; } EOF -if { (eval echo configure:2040: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2095: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define TTCP 1 @@ -2077,9 +2132,9 @@ fi echo $ac_n "checking Type Of Service""... $ac_c" 1>&6 -echo "configure:2081: checking Type Of Service" >&5 +echo "configure:2136: checking Type Of Service" >&5 cat > conftest.$ac_ext < #include @@ -2088,7 +2143,7 @@ int main() { int foobar = IP_TOS; ; return 0; } EOF -if { (eval echo configure:2092: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_TOS 1 @@ -2129,9 +2184,9 @@ fi echo $ac_n "checking Socket priority""... $ac_c" 1>&6 -echo "configure:2133: checking Socket priority" >&5 +echo "configure:2188: checking Socket priority" >&5 cat > conftest.$ac_ext < #include @@ -2140,7 +2195,7 @@ int main() { int foobar = SO_PRIORITY; ; return 0; } EOF -if { (eval echo configure:2144: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2199: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_SOCKET_PRIORITY 1 @@ -2557,7 +2612,7 @@ echo "Configuration of echoping:" echo $ac_n "checking HTTP""... $ac_c" 1>&6 -echo "configure:2561: checking HTTP" >&5 +echo "configure:2616: checking HTTP" >&5 if eval 'test "$HTTP" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else @@ -2566,7 +2621,7 @@ fi echo $ac_n "checking ICP""... $ac_c" 1>&6 -echo "configure:2570: checking ICP" >&5 +echo "configure:2625: checking ICP" >&5 if eval 'test "$ICP" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else @@ -2575,7 +2630,7 @@ fi echo $ac_n "checking OPENSSL""... $ac_c" 1>&6 -echo "configure:2579: checking OPENSSL" >&5 +echo "configure:2634: checking OPENSSL" >&5 if eval 'test "$OPENSSL" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else @@ -2584,7 +2639,7 @@ fi echo $ac_n "checking SMTP""... $ac_c" 1>&6 -echo "configure:2588: checking SMTP" >&5 +echo "configure:2643: checking SMTP" >&5 if eval 'test "$SMTP" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else @@ -2593,7 +2648,7 @@ fi echo $ac_n "checking TTCP""... $ac_c" 1>&6 -echo "configure:2597: checking TTCP" >&5 +echo "configure:2652: checking TTCP" >&5 if eval 'test "$TTCP" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else @@ -2602,7 +2657,7 @@ fi echo $ac_n "checking TOS""... $ac_c" 1>&6 -echo "configure:2606: checking TOS" >&5 +echo "configure:2661: checking TOS" >&5 if eval 'test "$TOS" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else @@ -2611,7 +2666,7 @@ fi echo $ac_n "checking PRIORITY""... $ac_c" 1>&6 -echo "configure:2615: checking PRIORITY" >&5 +echo "configure:2670: checking PRIORITY" >&5 if eval 'test "$PRIORITY" = "1"' > /dev/null; then echo "$ac_t""enabled" 1>&6 else diff --git a/SRC/configure.in b/SRC/configure.in index de38fd6..5eb04ed 100644 --- a/SRC/configure.in +++ b/SRC/configure.in @@ -3,7 +3,7 @@ dnl $Id$ dnl Process this file with autoconf to produce a configure script. AC_INIT(echoping.h) dnl AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(echoping, 4.2.0-BETA) +AM_INIT_AUTOMAKE(echoping, 5.0.0-BETA) AM_CONFIG_HEADER(config.h) dnl User options @@ -67,8 +67,9 @@ CF_LIB_SOCKET CF_LIB_NSL AC_TYPE_SIGNAL AC_FUNC_VPRINTF -AC_CHECK_FUNCS(gettimeofday socket gethostbyname sigaction, , AC_MSG_ERROR(Missing mandatory function)) -AC_CHECK_FUNCS(usleep getaddrinfo) +AC_CHECK_FUNCS(gettimeofday socket sigaction, , AC_MSG_ERROR(Missing mandatory function)) +AC_CHECK_FUNCS(usleep) +AC_CHECK_FUNCS(getaddrinfo) if test "$OPENSSL" = "1"; then CF_LIB_OPENSSL diff --git a/SRC/echoping.1 b/SRC/echoping.1 index 96694fb..8c73e90 100644 --- a/SRC/echoping.1 +++ b/SRC/echoping.1 @@ -21,6 +21,8 @@ echoping \- tests a remote host with TCP or UDP .RI [-P tos] .RI [-C] .RI [-S] +.RI [-4] +.RI [-6] .B hostname [:port] @@ -70,7 +72,7 @@ Use the "chargen" service instead of echo .IP -h\ url Use the HTTP protocol (instead of echo) for the given URL. The URL has to be a relative one (for instance '/' or '/pics/foobar.gif') because HTTP 1.0 -servers will not understand a request for an absolute URL. +servers will «not understand a request for an absolute URL. .IP -i\ url Use the ICP protocol (instead of echo) for the given URL. The URL has to be an absolute one. This is mostly for testing Squid Web proxy/caches. @@ -95,6 +97,12 @@ in Set the IP type of service octet in the transmitted packets to the least significant eight bits of the integer .IR n . +.IP -4 +Uses IPv4 only +.IR n . +.IP -6 +Uses IPv6 only +.IR n . .SH EXAMPLES .IP echoping\ \-v\ foobar.example.com Tests the remote machine with TCP echo (one test). diff --git a/SRC/echoping.c b/SRC/echoping.c index 624a7be..e089d45 100644 --- a/SRC/echoping.c +++ b/SRC/echoping.c @@ -29,6 +29,9 @@ struct timeval max, min, total, median, temp; unsigned int successes, attempts = 0; unsigned int size = DEFLINE; unsigned int j = 0; +#ifdef HAVE_GETADDRINFO +int family = PF_UNSPEC; +#endif struct result { unsigned short valid; @@ -49,17 +52,30 @@ main (argc, argv) signed char ch; int sockfd; +#ifdef HAVE_GETADDRINFO + struct addrinfo hints, *res; + int error; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; +#ifdef NI_WITHSCOPEID + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; +#else + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; +#endif +#endif + FILE *files = NULL; CHANNEL channel; +#ifndef HAVE_GETADDRINFO struct hostent *hostptr; struct sockaddr_in serv_addr; struct sockaddr_in udp_cli_addr; /* client's Internet socket * addr */ struct servent *sp = NULL; - int verbose = FALSE; char *server_address; u_int addr; struct in_addr *ptr; +#endif + int verbose = FALSE; int n, nr = 0; int rc; #ifdef OPENSSL @@ -90,7 +106,9 @@ main (argc, argv) unsigned short size_requested = 0; char *url = ""; short port = 0; +#ifndef HAVE_GETADDRINFO char *text_port = malloc (6); +#endif #if USE_SIGACTION struct sigaction mysigaction; #endif @@ -140,7 +158,7 @@ main (argc, argv) results[i].valid = 0; } progname = argv[0]; - while ((ch = getopt (argc, argv, "vs:n:w:dch:i:rut:f:SCp:P:")) != EOF) + while ((ch = getopt (argc, argv, "vs:n:w:dch:i:rut:f:SCp:P:46")) != EOF) { switch (ch) { @@ -272,6 +290,20 @@ main (argc, argv) exit (1); } break; + case '4': +#ifdef HAVE_GETADDRINFO + family = AF_INET; +#endif + break; + case '6': +#ifdef HAVE_GETADDRINFO + family = AF_INET6; +#else + (void) fprintf (stderr, + "%s: not compiled for IPv6 support.\n", progname); + exit (1); +#endif + break; default: usage (); } @@ -284,16 +316,6 @@ main (argc, argv) progname); exit (1); } -/* - Version 2.1 now allows global timeouts for TCP connections - * - if (!udp && (timeout_requested)) - { - (void) fprintf (stderr, - "%s: Time out ignored for TCP connections.\n", progname); - exit (1); - } - */ if ((http || smtp) && (fill_requested)) { (void) fprintf (stderr, @@ -405,19 +427,33 @@ main (argc, argv) { find_server_and_port (server, &port, port_name); if (port == 0) +#ifdef HAVE_GETADDRINFO port = 3130; +#else + port_name = "3130"; +#endif } else { find_server_and_port (server, &port, port_name); if (port == 0) +#ifdef HAVE_GETADDRINFO port = 80; +#else + port_name = "80"; +#endif } - +#ifndef HAVE_GETADDRINFO sprintf (text_port, "(port %d)", ntohs (port)); +#else + port_name = malloc (5); /* To prevent overflow. A short uses at most + 5 digits in decimal form */ + sprintf (port_name, "%hd", ntohs (port)); +#endif } #endif signal (SIGINT, interrupted); +#ifndef HAVE_GETADDRINFO if ((addr = inet_addr (server)) == INADDR_NONE) { if ((hostptr = gethostbyname (server)) == NULL) @@ -427,10 +463,6 @@ main (argc, argv) } server_address = *(hostptr->h_addr_list); /* First item of the * list */ - /* - * addr = (u_long) *server_address; - */ - /* ptr.s_addr = addr; */ ptr = (struct in_addr *) server_address; /* hostptr->h_addr_list * points actually to * u_longs, not strings */ @@ -441,6 +473,23 @@ main (argc, argv) ptr = (struct in_addr *) malloc (sizeof (struct in_addr)); ptr->s_addr = addr; } +#else + memset (&hints, 0, sizeof (hints)); + hints.ai_family = family; + hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; + /* printf ("DEBUG: server %s:%d (%s)\n", server, ntohs(port), port_name); */ + error = getaddrinfo (server, port_name, &hints, &res); + if (error) + err_quit ("getaddrinfo error for host: %s %s", + server, gai_strerror (error)); + if (getnameinfo (res->ai_addr, res->ai_addrlen, hbuf, sizeof (hbuf), + pbuf, sizeof (pbuf), niflags) != 0) + { + strcpy (hbuf, "?"); + strcpy (pbuf, "?"); + } +#endif +#ifndef HAVE_GETADDRINFO if (!http && !icp) /* Already find */ { if (!udp) @@ -462,7 +511,6 @@ main (argc, argv) * Fill in the structure "serv_addr" with the address of the server * that we want to connect with. */ - bzero ((char *) &serv_addr, sizeof (serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = addr; @@ -474,11 +522,17 @@ main (argc, argv) { serv_addr.sin_port = port; } +#endif + #ifdef HTTP if (http) { +#ifdef HAVE_GETADDRINFO + sendline = make_http_sendline (url, server, (int) ntohs (atoi (pbuf))); +#else sendline = make_http_sendline (url, server, (int) ntohs (port)); +#endif } else #endif @@ -538,6 +592,14 @@ main (argc, argv) if ((sslh = SSL_new (ctx)) == NULL) err_sys ("Cannot initialize SSL context"); #endif +#ifdef HAVE_GETADDRINFO + /* + * Open a socket. + */ + if ((sockfd = socket (res->ai_family, + res->ai_socktype, res->ai_protocol)) < 0) + err_sys ("Can't open socket"); +#else if (!udp) { /* @@ -562,6 +624,7 @@ main (argc, argv) err_sys ("bind error"); } } +#endif #ifdef USE_PRIORITY if (priority_requested) { @@ -601,20 +664,32 @@ main (argc, argv) { printf ("Trying to connect to internet address %s %s to transmit %u bytes...\n", +#ifdef HAVE_GETADDRINFO + hbuf, pbuf, n); +#else inet_ntoa (*ptr), (port == 0 ? "" : text_port), n); +#endif } #ifdef ICP if (icp) { printf ("Trying to send an ICP packet of %u bytes to the internet address %s...\n", +#ifdef HAVE_GETADDRINFO + length, hbuf); +#else length, inet_ntoa (*ptr)); +#endif } #endif else { printf ("Trying to send %u bytes to internet address %s...\n", +#ifdef HAVE_GETADDRINFO + size, hbuf); +#else size, inet_ntoa (*ptr)); +#endif } #ifdef FLUSH_OUTPUT if (fflush ((FILE *) NULL) != 0) @@ -649,8 +724,12 @@ main (argc, argv) * Connect to the server. */ +#ifdef HAVE_GETADDRINFO + if (connect (sockfd, res->ai_addr, res->ai_addrlen) < 0) +#else if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) +#endif { if ((errno == EINTR) && (timeout_flag)) { @@ -661,7 +740,7 @@ main (argc, argv) { err_sys ("I cannot flush"); } -#endif +#endif /* « */ } else err_sys ("Can't connect to server"); @@ -708,9 +787,14 @@ main (argc, argv) #ifdef USE_TTCP if (ttcp) { +#ifdef HAVE_GETADDRINFO if (sendto (sockfd, sendline, n, MSG_EOF, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) != n) +#else + if (sendto (sockfd, sendline, n, MSG_EOF, + res->ai_addr, res->ai_addrlen) != n) +#endif err_sys ("sendto error on socket"); if (verbose) { @@ -774,8 +858,13 @@ main (argc, argv) #ifdef ICP if (icp) { +#ifdef GET_HAVEADDRINFO + if (sendto (sockfd, sendline, length, 0, + res->ai_addr, res->ai_addrlen) != length) +#else if (sendto (sockfd, sendline, length, 0, &serv_addr, sizeof (serv_addr)) != length) +#endif err_sys ("sendto error on socket"); } else diff --git a/SRC/error.c b/SRC/error.c index 3dcb996..b81d4ac 100644 --- a/SRC/error.c +++ b/SRC/error.c @@ -88,7 +88,7 @@ void usage () { fprintf (stderr, - "Usage: %s [-v] [-r] [-f fill] [-t timeout] [-c] [-d] [-u] [-s size] [-n number] [-w delay] [-h url] [-i url] [-p priority] [-P tos] [-C] [-S] hostname[:port]\n", + "Usage: %s [-v] [-r] [-f fill] [-t timeout] [-c] [-d] [-u] [-s size] [-n number] [-w delay] [-h url] [-i url] [-p priority] [-P tos] [-C] [-S] [-4] [-6] hostname[:port]\n", progname); exit (1); }