PF or "traceroute -e -P TCP" bug?
Rostislav Krasny
rosti.bsd at gmail.com
Fri Aug 18 20:58:24 UTC 2006
Hi,
I've tried the new "-e" traceroute option on today's RELENG_6 and
found following problem:
> traceroute -nq 1 -e -P TCP -p 80 216.136.204.117
traceroute to 216.136.204.117 (216.136.204.117), 64 hops max, 52 bytepackets
1 192.168.1.1 0.619 ms
2 10.0.0.138 2.108 ms
3 192.168.1.1 0.481 ms !H
>
The 192.168.1.1 is other 6.1-STABLE machine which is used as a NAT
router. It's one or two days older RELENG_6. The NATing is done by PF.
The 10.0.0.138 is my ADSL modem which I use in "DHCP spoofing" mode,
i.e. it gives to the router an external IP address from my ISP.
I've fixed the bug by following patch:
--- traceroute.c.orig Fri Aug 18 19:19:23 2006
+++ traceroute.c Fri Aug 18 22:05:08 2006
@@ -1355,7 +1355,7 @@
{
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,7 +1375,7 @@
{
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);
}
However this patch isn't complete or it is just a workaround of
completely different bug in the router, because sometimes the new
traceroute produced a similar problem:
> traceroute -nq 1 -e -P TCP -p 12345 216.136.204.117
traceroute to 216.136.204.117 (216.136.204.117), 64 hops max, 52 byte packets
1 192.168.1.1 1.414 ms
2 10.0.0.138 4.584 ms
3 212.143.208.128 203.325 ms
4 212.143.208.126 101.073 ms
5 212.143.10.65 175.442 ms
^C
> traceroute -nq 1 -e -P TCP -p 12345 216.136.204.117
traceroute to 216.136.204.117 (216.136.204.117), 64 hops max, 52 byte packets
1 192.168.1.1 0.740 ms
2 192.168.1.1 0.718 ms !H
> traceroute -nq 1 -e -P TCP -p 12345 216.136.204.117
traceroute to 216.136.204.117 (216.136.204.117), 64 hops max, 52 byte packets
1 192.168.1.1 0.692 ms
2 192.168.1.1 0.770 ms !H
>
After waiting enough time I can successfully repeat the command.
Is it actually a PF bug?
Finally I made other version of my patch:
--- traceroute.c.orig Fri Aug 18 19:19:23 2006
+++ traceroute.c Fri Aug 18 23:40:43 2006
@@ -471,6 +471,7 @@
register int lsrr = 0;
register u_short off = 0;
struct ifaddrlist *al;
+ struct timespec time_sp;
char errbuf[132];
int requestPort = -1;
int sump = 0;
@@ -721,7 +722,8 @@
outip->ip_dst = to->sin_addr;
outip->ip_hl = (outp - (u_char *)outip) >> 2;
- ident = (getpid() & 0xffff) | 0x8000;
+ clock_gettime(CLOCK_REALTIME, &time_sp);
+ ident = ((u_short)time_sp.tv_nsec & 0xffff) | 0x8000;
if (pe == NULL) {
Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
@@ -1355,7 +1357,7 @@
{
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,7 +1377,7 @@
{
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);
}
Now traceroute works fine. But I'm still suspecting PF.
More information about the freebsd-net
mailing list