On Thu, Sep 13, 2012 at 03:02:09PM -0400, Ted Unangst wrote:
> So sometimes a machine is hiding behind a firewall that blocks icmp
> (looking at you, amazon ec2), but I want to know if it's up and/or how
> long away it is.  tcp to the rescue.

Seems like a bit of a "rude" method of testing whether a
host is up, especially if you leave it ping-ing in a
continuous loop.

telnet works just fine if you want to test if a host is up
and listening on a specific port, minus the timing info you
are looking for.

--patrick


> This adds a -T portnum option to ping.  I haven't polished the output
> because I'm not sure if this is desirable or not, but I found it
> useful.  If it's not a "hell no, never in base" I can finish it up some.
> 
> Index: ping.c
> ===================================================================
> RCS file: /cvs/src/sbin/ping/ping.c,v
> retrieving revision 1.92
> diff -u -p -r1.92 ping.c
> --- ping.c    17 Mar 2012 10:16:40 -0000      1.92
> +++ ping.c    13 Sep 2012 18:57:06 -0000
> @@ -169,6 +169,7 @@ quad_t qsqrt(quad_t);
>  void pr_iph(struct ip *);
>  #ifndef SMALL
>  int map_tos(char *, int *);
> +void tcpping(void);
>  #endif       /* SMALL */
>  void usage(void);
>  
> @@ -191,6 +192,7 @@ main(int argc, char *argv[])
>       size_t fdmasks;
>       uid_t uid;
>       u_int rtableid;
> +     unsigned short portnum = 0;
>  
>       if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
>               err(1, "socket");
> @@ -203,7 +205,7 @@ main(int argc, char *argv[])
>       preload = 0;
>       datap = &outpack[8 + sizeof(struct tvi)];
>       while ((ch = getopt(argc, argv,
> -         "DEI:LRS:c:defi:l:np:qrs:T:t:V:vw:")) != -1)
> +         "DEI:LRS:c:defi:l:nP:p:qrs:T:t:V:vw:")) != -1)
>               switch(ch) {
>               case 'c':
>                       npackets = (unsigned long)strtonum(optarg, 0,
> @@ -277,6 +279,13 @@ main(int argc, char *argv[])
>                       options |= F_PINGFILLED;
>                       fill((char *)datap, optarg);
>                               break;
> +#ifndef SMALL
> +             case 'P':
> +                     portnum = strtonum(optarg, 1, 65535, &errstr);
> +                     if (errstr)
> +                             errx(1, "portnum is %s: %s", errstr, optarg);
> +                     break;
> +#endif
>               case 'q':
>                       options |= F_QUIET;
>                       break;
> @@ -369,6 +378,17 @@ main(int argc, char *argv[])
>               hostname = hnamebuf;
>       }
>  
> +#ifndef SMALL
> +     if (portnum) {
> +             close(s);
> +             whereto.sin_port = htons(portnum);
> +             while (!npackets || ntransmitted++ < npackets) {
> +                     tcpping();
> +                     sleep(1);
> +             }
> +     }
> +#endif
> +
>       if (options & F_FLOOD && options & F_INTERVAL)
>               errx(1, "-f and -i options are incompatible");
>  
> @@ -1413,6 +1433,27 @@ map_tos(char *s, int *val)
>       }
>       
>       return (0);
> +}
> +
> +void
> +tcpping(void)
> +{
> +     struct timeval before, after, diff;
> +     int rtt;
> +
> +     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
> +     if (!s)
> +             err(1, "can't open socket");
> +     gettimeofday(&before, NULL);
> +     if (connect(s, (const struct sockaddr *)&whereto,
> +                 sizeof(whereto)))
> +             err(1, "can't connect");
> +     gettimeofday(&after, NULL);
> +     close(s);
> +     timersub(&after, &before, &diff);
> +     
> +     rtt = diff.tv_sec * 10000000 + diff.tv_usec;
> +     printf("tcpping %d.%d ms\n", rtt / 1000, rtt % 1000);
>  }
>  #endif       /* SMALL */

Reply via email to