From: Willy Tarreau <willy@w.ods.org>
To: Josan Kadett <corporate@superonline.com>
Cc: linux-net@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
Date: Sat, 21 Aug 2004 09:10:35 +0200 [thread overview]
Message-ID: <20040821071035.GG1456@alpha.home.local> (raw)
In-Reply-To: <S268848AbUHUFP2/20040821051528Z+1662@vger.kernel.org>
Hi !
Have you tried to reach the device on its 192.168.1.1 address by adding a
static route on you host stating that 192.168.1.1 is behind 192.168.77.1 ?
You might also give iproute a try, it can do static NAT, although I'm not
certain that checksums are recomputed entirely. There's a big probability
that it uses differential checksums.
Last solution would be to use iptables (without conntrack) and assign packets
to the QUEUE target, then mangling them with a small user-space program
which would then reinject them into the network stack. It might not be too
hard to do. There's even a 'perlipq' perl extension which might do all the
dirty work for you.
Regards,
Willy
On Sat, Aug 21, 2004 at 08:15:30AM +0200, Josan Kadett wrote:
> I will explain the problem briefly;
>
> - We have an old network concentrator device in our WAN, this device uses IP
> number 192.168.77.1 as its primary address
> - The device has another IP number (a local address) that is 192.168.1.1
>
> When we ping the device from the internal network, we have to use the
> device's primary IP number which is 192.168.77.1:
>
> ping -> 192.168.77.1
> reply from 192.168.1.1
>
> Normally the reply should come from 192.168.77.1, but the device has some
> kind of programming failure and thus responds us using its internal IP
> number regardless of how we configure it.
>
> This does not affect the ping from returning back even it is sourced by a
> different address than it is originally destined to, however; if we telnet
> to the device we get the following failure:
>
> telnet -> TCP SYN sent to 192.168.77.1
> TCP SYN ACK reply from 192.168.1.1
> TCP SYN sent to 192.168.77.1
> TCP SYN sent to 192.168.77.1
> TCP SYN sent to 192.168.77.1
> .... [The connection times since our linux host does not "see" the TCP SYN
> ACK reply for an obvious reason)
>
> The client from which we send telnet requests to the device gets a packet
> from 192.168.1.1 instead of getting a packet from 192.168.77.1. However; at
> this case, the returning TCP SYN ACK packet has the wrong CRC checksum
> because;
>
> The network concentrator computes the TCP checksum with the source address
> header of its IP number 192.167.77.1, however; our client that gets the
> packet from the address 192.168.1.1 uses this address instead of the correct
> one in order to compute the checksum and thus they mismatch;
>
> Eg.
> 0D 74 (Checksum computed by concentrator device)
> 13 D6 (Checksum computed by our client)
>
> So the incoming packets are dropped due to the fact that they have "wrong"
> checksum... Now either we should find a way to correct the source address
> and the IP checksum in each incoming packet received by our client, or we
> should "program" a utility for it. Here is what we plan to do;
>
> - Intercept each packet coming from interface eth0
> - Put the IP data in buffer
> - Find and change the bits in which the source IP address is encoded (from
> 192.168.1.1 back to 192.168.77.1)
> - Since the TCP packet has already been checksummed for the correct IP,
> after we change the source, the TCP checksum would be "automatically"
> corrected
> - But since we modified the source IP, now the IP header checksum is broken;
> so recalculate it and put it in correct place
> - "Re-inject" the packet to the interface eth0, but to the "incoming" data
> path that would be received by kernel (just as generating a packet that goes
> to system itself, instead of an external link)
>
> I found that in /usr/src/linux/net/ipv4/tcp_input.c and udp.c are the two
> sources that control how the communication occurs. I experimented with the
> code and re-compiled the kernel times over times, though either the "CRC"
> checksum checking was still there or the communication was totally cut out.
>
> I also investigated terms such as CRC checksum offloading and such, and as I
> could see that there was no easy way (a switch or a definition) to disable
> CRC checksumming of received packets, either it be TCP or UDP. I am still
> sure that if the kernel is "told" to allow all packets regardless of their
> CRC field, I would resolve the problem with our network, but the question is
> "how ??"
>
> Below is a detailed view of the malformed packet;
>
> Ethernet II Header
> |
> - IP Header
> (flags) Source IP: 192.168.1.1 (This is where the problem begins, it
> should have been 192.168.77.1)
> Dest. IP: 192.168.1.5 (Our client's IP number)
> Checksum [0x7d43] --> Correct CRC for IP header
> |
> - UDP Header (The same case for TCP)
> (flags) Source Port: 161
> Dest. Port: 32816
> Length: 0x0048
> Checksum [0x341a] --> Wrong CRC that causes all problems.**
>
> Our system thinks that the checksum would be what it wants to be, so the
> conflict between these two devices makes communication impossible. I know,
> if a patch is applied to the source code of the kernel, both TCP and UDP
> would ingore the CRC and allow communication. Since our network is
> absolutely reliable, there will not be a single side effect of disabling
> TCP/UDP checksums.
>
> Now if all else fails, at least I have one option though I really do not
> wish to program a packet interceptor for no reason but the dumbness of a
> router and the "abhorrent rigidity" of linux TCP/IP stack. But if I must
> then I will... (We will not replace a multi-K$ UAC device just for this
> reason)
>
> Perhaps there is a small utility that corrects checksums of the incoming
> data (in real-time) ? Indeed many sniffers have this option to correct the
> CRC (or show the correct value), but none of them are programmed to create a
> stream in which the modifications are done and the packets get re-injected.
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
next prev parent reply other threads:[~2004-08-21 7:28 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-21 6:15 Entirely ignoring TCP and UDP checksum in kernel level Josan Kadett
2004-08-21 7:10 ` Willy Tarreau [this message]
[not found] <4126F16D.1000507@gmc.lt>
2004-08-21 8:02 ` Josan Kadett
2004-08-21 7:36 ` Kalin KOZHUHAROV
2004-08-21 8:54 ` Josan Kadett
-- strict thread matches above, loose matches on Subject: below --
2004-08-21 8:27 Denis Vlasenko
2004-08-21 8:41 ` Lee Revell
2004-08-21 9:50 ` Josan Kadett
2004-08-21 9:06 ` Kalin KOZHUHAROV
2004-08-21 21:46 ` Josan Kadett
2004-08-21 9:39 ` Josan Kadett
[not found] <1093078213.854.76.camel@krustophenia.net>
2004-08-21 8:58 ` Lee Revell
2004-08-21 21:41 ` Josan Kadett
[not found] <4126FDD8.1090101@gmc.lt>
2004-08-21 9:00 ` Josan Kadett
2004-08-21 8:11 ` Denis Vlasenko
2004-08-21 9:18 ` Josan Kadett
2004-08-21 8:26 ` Lee Revell
2004-08-21 9:35 ` Josan Kadett
2004-08-21 9:14 ` Vojtech Pavlik
[not found] <1093120934.854.155.camel@krustophenia.net>
2004-08-21 20:46 ` Lee Revell
2004-08-21 21:53 ` Josan Kadett
[not found] <04Aug21.205911edt.41960@gpu.utcc.utoronto.ca>
2004-08-22 2:08 ` Josan Kadett
2004-08-22 6:01 ` Brad Campbell
2004-08-22 7:06 ` Josan Kadett
2004-08-22 6:17 Brad Campbell
2004-08-22 7:18 ` Josan Kadett
2004-08-22 7:24 ` Josan Kadett
2004-08-22 7:04 ` Brad Campbell
2004-08-22 8:12 ` Josan Kadett
2004-08-22 8:29 ` Brad Campbell
2004-08-22 9:19 Brad Campbell
[not found] <41285DB3.6070605@wasp.net.au>
2004-08-22 10:14 ` Josan Kadett
2004-08-22 11:48 ` James Courtier-Dutton
2004-08-22 10:25 ` Josan Kadett
2004-08-22 9:36 ` Brad Campbell
2004-08-22 10:48 ` Josan Kadett
2004-08-22 13:10 ` Brad Campbell
2004-08-22 13:13 ` Brad Campbell
2004-08-22 19:27 ` Josan Kadett
2004-08-22 20:28 ` Josan Kadett
2004-08-23 3:38 ` David Meybohm
2004-08-23 5:26 ` Josan Kadett
2004-08-23 8:40 ` Josan Kadett
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040821071035.GG1456@alpha.home.local \
--to=willy@w.ods.org \
--cc=corporate@superonline.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-net@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.