PF or "traceroute -e -P TCP" bug?

Rostislav Krasny rosti.bsd at gmail.com
Sat Oct 14 10:21:40 PDT 2006


Hi,

On Mon, 21 Aug 2006 12:59:38 -0700
"Crist J. Clark" <cristjc at comcast.net> wrote:

> On Mon, Aug 21, 2006 at 11:23:50AM +0200, Daniel Hartmeier wrote:
> > [ I'm CC'ing Crist, maybe he can explain why -e behaves like it does ]

[hided]

> So, to expand on the three points above, we need (1) fixed
> destination port, (2) to increment IP TTL, (3) the sequence
> number encoded in some head field, and (3) a source port
> chosen so that multiple traceroute invocations do not
> share any src-sport-dst-dport-tuples during their lifetime.
> In the past, using the PID worked for the sport, but think about
> what happens if you start with the PID then start incrementing
> or decrementing, you get overlaps (unless your system does a
> decent job with random PIDs; not the default for FreeBSD
> unfortunately).
> 
> The patch to freebsd-net addresses these problems. It
> changes the sorce port so that we don't have overlapping
> src-sport-dst-dport-tuples, and uses a base source port from
> the LSBs of the clock for a "random" number. That would seem
> to fix the problem. The only question would be is that a good
> way to pick the base source port? It's probably good enough,
> although some kind of hash of the PID might be better.

What do you think about new version of the patch, attached to this
email? It swaps high and low bytes of the "ident" - 16-bits integer
variable. This technique should produce far standing numbers from any
close standing numbers.
-------------- next part --------------
--- traceroute.c.orig	Fri Aug 18 18:52:57 2006
+++ traceroute.c	Sat Oct 14 18:49:11 2006
@@ -721,7 +721,8 @@ main(int argc, char **argv)
 		outip->ip_dst = to->sin_addr;
 
 	outip->ip_hl = (outp - (u_char *)outip) >> 2;
-	ident = (getpid() & 0xffff) | 0x8000;
+	ident = getpid();
+	ident = ((ident << CHAR_BIT) | (ident >> CHAR_BIT) & 0xffff) | 0x8000;
 
 	if (pe == NULL) {
 		Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
@@ -1355,7 +1356,7 @@ tcp_prep(struct outdata *outdata)
 {
 	struct tcphdr *const tcp = (struct tcphdr *) outp;
 
-	tcp->th_sport = htons(ident);
+	tcp->th_sport = htons(ident + (fixedPort ? outdata->seq : 0));
 	tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
 	tcp->th_seq = (tcp->th_sport << 16) | (tcp->th_dport +
 	    (fixedPort ? outdata->seq : 0));
@@ -1375,9 +1376,10 @@ tcp_check(const u_char *data, int seq)
 {
 	struct tcphdr *const tcp = (struct tcphdr *) data;
 
-	return (ntohs(tcp->th_sport) == ident
+	return (ntohs(tcp->th_sport) == ident + (fixedPort ? seq : 0)
 	    && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq))
-	    && tcp->th_seq == (ident << 16) | (port + seq);
+	    && tcp->th_seq == (tcp->th_sport << 16) |
+		(port + (fixedPort ? seq : 0));
 }
 
 void


More information about the freebsd-net mailing list