Ed Ravin on 24 Nov 2003 12:14:02 -0500


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[tcptra-dev] tcptraceroute patch for sub one-second timeouts, gcc3


Thanks to a failure this weekend in Level3's NYC network, which blocked
TCP packets in seemingly-random netblocks, I had the occasion to dig out
tcptraceroute.  It worked outstandingly well in identifying the problem
gateway.  My thanks to all who worked on it for an excellent product!

An affected customer of mine submitted the following patches:
He needed the conversion of the -w timeout into floating point to let
him test lots and lots of IP addresses to see which were affected by
the routing problem, and he had some trouble building tcptraceroute
under GCC3.

----- Forwarded message from Thor Lancelot Simon <tls@NetBSD.org> -----

Date: Sun, 23 Nov 2003 20:36:19 +0000
From: Thor Lancelot Simon <tls@NetBSD.org>
Subject: tcptraceroute patch

This patch does two things: it makes tcptraceroute build with GCC 3
(which doesn't like newlines in the middle of strings), and it makes
-w take a floating-point argument instead of an integer.

--- ../../work.i386/tcptraceroute-1.4/tcptraceroute.c	2003-11-23 20:31:04.000000000 +0000
+++ tcptraceroute.c	2003-11-23 20:03:41.000000000 +0000
@@ -315,9 +315,10 @@
 int pcap_fd;
 struct timeval now;
 int	sockfd, datalink, offset;
-int o_minttl, o_maxttl, o_timeout, o_debug, o_numeric, o_pktlen,
+int o_minttl, o_maxttl, o_debug, o_numeric, o_pktlen,
 	o_nqueries, o_dontfrag, o_tos, o_forceport, o_syn, o_ack, o_ecn,
 	o_nofilter, o_nogetinterfaces, o_noselect, o_trackport;
+float o_timeout;
 
 /* interface linked list, built later by getinterfaces() */
 struct interface_entry {
@@ -391,10 +392,7 @@
 void usage(void)
 {
 	printf("\n%s\n%s\n", VERSION, BANNER);
-    fatal("Usage: %s [-nNFSAE] [-i <interface>] [-f <first ttl>]
-       [-l <packet length>] [-q <number of queries>] [-t <tos>]
-       [-m <max ttl>] [-pP] <source port>] [-s <source address>]
-       [-w <wait time>] <host> [destination port] [packet length]\n\n", name);
+    fatal("Usage: %s [-nNFSAE] [-i <interface>] [-f <first ttl>] [-l <packet length>] [-q <number of queries>] [-t <tos>] [-m <max ttl>] [-pP] <source port>] [-s <source address>] [-w <wait time>] <host> [destination port] [packet length]\n\n", name);
 }
 
 void about(void)
@@ -487,6 +485,20 @@
 	return 1;
 }
 
+int isfloat(char *s)
+{
+	int i;
+
+	if (!s || !s[0])
+		return 0;
+
+	for(i = 0; s[i]; i++)
+		if (! isdigit((u_char) s[i]))
+			if(s[i] != '.')
+				return  0;
+	return 1;
+}
+
 int datalinkoffset(int type)
 {
 	int i;
@@ -1011,7 +1023,7 @@
 		"datalink", datalink,
 		"datalinkoffset", datalinkoffset(datalink));
 
-	debug("%16s: %-2d %16s: %-2d %16s: %-2d\n",
+	debug("%16s: %-2d %16s: %-2d %16s: %-2f\n",
 		"o_minttl", o_minttl,
 		"o_maxttl", o_maxttl,
 		"o_timeout", o_timeout);
@@ -1129,8 +1141,8 @@
 	if (o_nqueries <= 0)
 		fatal("Number of queries must be at least 1\n");
 
-	if (o_timeout <= 0)
-		fatal("Timeout must be at least 1\n");
+	if (o_timeout < 0.01)
+		fatal("Timeout must be at least 0.01\n");
 
 	if (o_pktlen < LIBNET_TCP_H + LIBNET_IP_H)
 	{
@@ -1181,10 +1193,7 @@
 	if (! (pcap = pcap_open_live(device, offset + SNAPLEN, 0, 10, errbuf)))
 		fatal("pcap_open_live failed: %s", errbuf);
 
-	safe_snprintf(filter, TEXTSIZE, "
-		(tcp and src host %s and src port %d and dst host %s)
-		or ((icmp[0] == 11 or icmp[0] == 3) and dst host %s)",
-			iptos(dst_ip), dst_prt, iptos(src_ip), iptos(src_ip));
+	safe_snprintf(filter, TEXTSIZE, " (tcp and src host %s and src port %d and dst host %s) or ((icmp[0] == 11 or icmp[0] == 3) and dst host %s)", iptos(dst_ip), dst_prt, iptos(src_ip), iptos(src_ip));
 
 	if (o_nofilter)
 		filter[0] = '\0';
@@ -1336,7 +1345,7 @@
 
 	firstpass = 1;
 	timeout_tv.tv_sec = o_timeout;
-	timeout_tv.tv_usec = 0;
+	timeout_tv.tv_usec = (o_timeout - (float)timeout_tv.tv_sec) * 1000000UL;
 
 	if (gettimeofday(&start, NULL) < 0)
 		pfatal("gettimeofday");
@@ -1730,6 +1739,13 @@
 	return atoi(optarg);
 }
 
+float checkfloatarg(void)
+{
+	if(! isfloat(optarg))
+		fatal("Floating-point argument required for -%c\n", optopt);
+	return atof(optarg);
+}
+
 /*
  * A kludge to help us process long command line arguments, only to be called
  * using the CHECKLONG() macro, and only from main().  If the given word
@@ -1934,8 +1950,8 @@
 				break;
 
 			case 'w': /* ARG */
-				o_timeout = checknumericarg();
-				debug("o_timeout set to %d\n", o_timeout);
+				o_timeout = checkfloatarg();
+				debug("o_timeout set to %f\n", o_timeout);
 				break;
 
 			case 's': /* ARG */
Thor


----- End forwarded message -----
_______________________________________________
tcptraceroute-dev mailing list
tcptraceroute-dev@netisland.net
http://lists.netisland.net/mailman/listinfo/tcptraceroute-dev