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.
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 */