* Entirely ignoring TCP and UDP checksum in kernel level
@ 2004-08-21 6:15 Josan Kadett
2004-08-21 7:10 ` Willy Tarreau
0 siblings, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 6:15 UTC (permalink / raw)
To: linux-net, linux-kernel
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.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 6:15 Josan Kadett
@ 2004-08-21 7:10 ` Willy Tarreau
0 siblings, 0 replies; 43+ messages in thread
From: Willy Tarreau @ 2004-08-21 7:10 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-net, linux-kernel
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/
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 8:02 ` Josan Kadett
@ 2004-08-21 7:36 ` Kalin KOZHUHAROV
2004-08-21 8:54 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Kalin KOZHUHAROV @ 2004-08-21 7:36 UTC (permalink / raw)
To: linux-kernel
Josan Kadett wrote:
> It is definetely impossible to use IPTables to handle packets with incorrect
> checksums since NAT would drop the connection right away, otherwise I would
> not have been asking this question here.
>
> -----Original Message-----
> From: Aidas Kasparas [mailto:a.kasparas@gmc.lt]
> Sent: Saturday, August 21, 2004 8:54 AM
> To: Josan Kadett
> Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
>
> How about setting up a separate box which would listen on that
> 192.168.77.1 address and MASQUERADE connections to your crazy box from
> 192.168.1.x address? Maybe then you would no longer need to break things
> in kernel?
Isn't rp_filter for this?
A chunk of my iptables firewall script is:
# Force route verification
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
So why don't you try:
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo "0" > $f; done
Kalin.
--
|| ~~~~~~~~~~~~~~~~~~~~~~ ||
( ) http://ThinRope.net/ ( )
|| ______________________ ||
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[not found] <4126F16D.1000507@gmc.lt>
@ 2004-08-21 8:02 ` Josan Kadett
2004-08-21 7:36 ` Kalin KOZHUHAROV
0 siblings, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 8:02 UTC (permalink / raw)
To: 'Aidas Kasparas'; +Cc: linux-kernel
It is definetely impossible to use IPTables to handle packets with incorrect
checksums since NAT would drop the connection right away, otherwise I would
not have been asking this question here.
-----Original Message-----
From: Aidas Kasparas [mailto:a.kasparas@gmc.lt]
Sent: Saturday, August 21, 2004 8:54 AM
To: Josan Kadett
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
How about setting up a separate box which would listen on that
192.168.77.1 address and MASQUERADE connections to your crazy box from
192.168.1.x address? Maybe then you would no longer need to break things
in kernel?
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 9:00 ` Josan Kadett
@ 2004-08-21 8:11 ` Denis Vlasenko
2004-08-21 9:18 ` Josan Kadett
2004-08-21 9:14 ` Vojtech Pavlik
1 sibling, 1 reply; 43+ messages in thread
From: Denis Vlasenko @ 2004-08-21 8:11 UTC (permalink / raw)
To: Josan Kadett, 'Aidas Kasparas'; +Cc: linux-kernel
On Saturday 21 August 2004 12:00, Josan Kadett wrote:
> The problem is that the interface 192.168.1.1 does not allow any
> tranmission to occur. An implementation error I think... We send packets to
> 192.168.1.1, we get no reply, but when we send packets to 192.168.77.1 we
> get the replies (that is where the abnormality begins). However; the
> replies are now sourced from 192.168.1.1 instead. That is, the blasted code
> in the device calculates the checksum using the wrong IP address which it
> thinks it is assigned to...
Maybe dust off some old Pentium 133 and replace that piece of electronic
crap with decent Linux machine?
--
vda
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 9:18 ` Josan Kadett
@ 2004-08-21 8:26 ` Lee Revell
2004-08-21 9:35 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Lee Revell @ 2004-08-21 8:26 UTC (permalink / raw)
To: Josan Kadett; +Cc: 'Denis Vlasenko', linux-kernel
On Sat, 2004-08-21 at 05:18, Josan Kadett wrote:
> That is not much of an intelligible idea. A way to hack the kernel could be
> found as I still presume. "Turn off checksums" but not by re-writing the
> whole tcp code in the kernel. Isn't that possible ? Linux is an operating
> system of infinite possibilities, right ? But only if you know how to hack
> it...
>
Can't you just go into the networking code, and find the part where it
checks the checksum, and just have it return success, even if the
checksum was bad? Seems like a quick copy and paste hack. Am I missing
something?
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
@ 2004-08-21 8:27 Denis Vlasenko
2004-08-21 8:41 ` Lee Revell
2004-08-21 9:39 ` Josan Kadett
0 siblings, 2 replies; 43+ messages in thread
From: Denis Vlasenko @ 2004-08-21 8:27 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
On Saturday 21 August 2004 12:18, Josan Kadett wrote:
> That is not much of an intelligible idea. A way to hack the kernel could be
> found as I still presume. "Turn off checksums" but not by re-writing the
> whole tcp code in the kernel. Isn't that possible ? Linux is an operating
> system of infinite possibilities, right ? But only if you know how to hack
> it...
Of course you can hack the kernel to do it.
However, by replacing that box with Linux device you
get one more Linux box and you will be capable of
doing whole slew of useful things, like traffic filtering, shaping,
accounting, Ethernet bridging, etc etc etc, if/when you will need it.
You can easily debug problems with tools like tcpdump and ethereal.
I simply cannot list everything Linux can do, I don't plan to write
a novel here ;]
I bet current 'crazy box' has nothing even vaguely resembling
these capabilities. Heck, it cannot do standard TCP properly.
So there is little reason to waste your time trying to work around it.
--
vda
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
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:39 ` Josan Kadett
1 sibling, 1 reply; 43+ messages in thread
From: Lee Revell @ 2004-08-21 8:41 UTC (permalink / raw)
To: Denis Vlasenko; +Cc: Josan Kadett, linux-kernel
On Sat, 2004-08-21 at 04:27, Denis Vlasenko wrote:
> On Saturday 21 August 2004 12:18, Josan Kadett wrote:
> > That is not much of an intelligible idea. A way to hack the kernel could be
> > found as I still presume. "Turn off checksums" but not by re-writing the
> > whole tcp code in the kernel. Isn't that possible ? Linux is an operating
> > system of infinite possibilities, right ? But only if you know how to hack
> > it...
>
> Of course you can hack the kernel to do it.
>
> However, by replacing that box with Linux device you
> get one more Linux box and you will be capable of
> doing whole slew of useful things, like traffic filtering, shaping,
> accounting, Ethernet bridging, etc etc etc, if/when you will need it.
> You can easily debug problems with tools like tcpdump and ethereal.
> I simply cannot list everything Linux can do, I don't plan to write
> a novel here ;]
>
> I bet current 'crazy box' has nothing even vaguely resembling
> these capabilities. Heck, it cannot do standard TCP properly.
> So there is little reason to waste your time trying to work around it.
He already stated that he was dealing with a very expensive, very broken
piece of hardware, and he needs a way to work around it. Many of us
have been in this situation, I will not name names ;-). Telling him to
just replace it is not helpful.
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 7:36 ` Kalin KOZHUHAROV
@ 2004-08-21 8:54 ` Josan Kadett
0 siblings, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 8:54 UTC (permalink / raw)
To: 'Kalin KOZHUHAROV'; +Cc: linux-kernel
I already have rp_filter to 0 for all interfaces. It is rather a
checksumming problem than a routing one. Only if there was such an easy way
to disable checksumming as there is for solaris, disabling both the
rp_filter and the checksums would finally end the problem. The poor system
still think that it is getting the packet from 192.168.1.1 because the IP
header tells as such, while the problematic network device computes the
TCP/UDP checksum as if it is still sending it via its 192.168.77.1 source
address. There is the kernel, and the code in it which handles checksumming.
But I doubt whether a simple patch would do...
> Isn't rp_filter for this?
> A chunk of my iptables firewall script is:
> # Force route verification
> for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
> So why don't you try:
> for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo "0" > $f; done
> Kalin.
--
|| ~~~~~~~~~~~~~~~~~~~~~~ ||
( ) http://ThinRope.net/ ( )
|| ______________________ ||
-
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/
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[not found] <1093078213.854.76.camel@krustophenia.net>
@ 2004-08-21 8:58 ` Lee Revell
2004-08-21 21:41 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Lee Revell @ 2004-08-21 8:58 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
On Sat, 2004-08-21 at 05:50, Josan Kadett wrote:
> Here is the very original linux-kernel mailing list, and if I cannot find an
> answer here, then nowhere on earth can this answer be found. I also saw some
> other messages regarding the same issue on the net. None of them is answered
> correctly; and also as if this is a very "forbidden" thing to disable the
> checksums, most replies are as if they are "unbreakable rules of god".
> Really, I am losing my patience with this. It is also very odd to write a
> low-level application in order to just disable a "feature" of the kernel to
> deal with a faulty piece of embedded firmware.
>
Try this. I have no idea whether it will work. If it breaks you get to
keep both halves.
--- net/ipv4/tcp_input.c 2004-08-20 16:37:12.000000000 -0400
+++ net/ipv4/tcp_input.c-new 2004-08-21 04:56:51.000000000 -0400
@@ -4234,8 +4234,7 @@
}
}
if (!eaten) {
- if (tcp_checksum_complete_user(sk, skb))
- goto csum_error;
+ tcp_checksum_complete_user(sk, skb);
/* Predicted packet is in window by definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
@@ -4291,7 +4290,7 @@
slow_path:
if (len < (th->doff<<2) || tcp_checksum_complete_user(sk, skb))
- goto csum_error;
+ ;
/*
* RFC1323: H1. Apply PAWS check first.
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[not found] <4126FDD8.1090101@gmc.lt>
@ 2004-08-21 9:00 ` Josan Kadett
2004-08-21 8:11 ` Denis Vlasenko
2004-08-21 9:14 ` Vojtech Pavlik
0 siblings, 2 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 9:00 UTC (permalink / raw)
To: 'Aidas Kasparas'; +Cc: linux-kernel
The problem is that the interface 192.168.1.1 does not allow any tranmission
to occur. An implementation error I think... We send packets to 192.168.1.1,
we get no reply, but when we send packets to 192.168.77.1 we get the replies
(that is where the abnormality begins). However; the replies are now sourced
from 192.168.1.1 instead. That is, the blasted code in the device calculates
the checksum using the wrong IP address which it thinks it is assigned to...
-----Original Message-----
From: Aidas Kasparas [mailto:a.kasparas@gmc.lt]
Sent: Saturday, August 21, 2004 9:47 AM
To: Josan Kadett
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
But will these checksums be incorect if crazy box would communicate with
address in 192.168.1.x only?
The whole idea was based on the fact, that if that box works well in
192.168.1.x networkd, then let it think it works in the network it knows
how to work!
Josan Kadett wrote:
> It is definetely impossible to use IPTables to handle packets with
incorrect
> checksums since NAT would drop the connection right away, otherwise I
would
> not have been asking this question here.
>
> -----Original Message-----
> From: Aidas Kasparas [mailto:a.kasparas@gmc.lt]
> Sent: Saturday, August 21, 2004 8:54 AM
> To: Josan Kadett
> Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
>
> How about setting up a separate box which would listen on that
> 192.168.77.1 address and MASQUERADE connections to your crazy box from
> 192.168.1.x address? Maybe then you would no longer need to break things
> in kernel?
>
>
>
--
Aidas Kasparas
IT administrator
GM Consult Group, UAB
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 9:50 ` Josan Kadett
@ 2004-08-21 9:06 ` Kalin KOZHUHAROV
2004-08-21 21:46 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Kalin KOZHUHAROV @ 2004-08-21 9:06 UTC (permalink / raw)
To: linux-kernel
Josan Kadett wrote:
> Here is the very original linux-kernel mailing list, and if I cannot find an
> answer here, then nowhere on earth can this answer be found. I also saw some
> other messages regarding the same issue on the net. None of them is answered
> correctly; and also as if this is a very "forbidden" thing to disable the
> checksums, most replies are as if they are "unbreakable rules of god".
> Really, I am losing my patience with this. It is also very odd to write a
> low-level application in order to just disable a "feature" of the kernel to
> deal with a faulty piece of embedded firmware.
OK, try this, not tested:
replace the return statements with "return 0;" in:
net/ipv4/udp.c, function __udp_checksum_complete, about line 759
net/ipv4/icp_input.c, function __tcp_checksum_complete_user, about line 4070
* line numbers above are for linux-2.6.7
Kalin.
--
|| ~~~~~~~~~~~~~~~~~~~~~~ ||
( ) http://ThinRope.net/ ( )
|| ______________________ ||
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 9:00 ` Josan Kadett
2004-08-21 8:11 ` Denis Vlasenko
@ 2004-08-21 9:14 ` Vojtech Pavlik
1 sibling, 0 replies; 43+ messages in thread
From: Vojtech Pavlik @ 2004-08-21 9:14 UTC (permalink / raw)
To: Josan Kadett; +Cc: 'Aidas Kasparas', linux-kernel
On Sat, Aug 21, 2004 at 11:00:27AM +0200, Josan Kadett wrote:
> The problem is that the interface 192.168.1.1 does not allow any tranmission
> to occur. An implementation error I think... We send packets to 192.168.1.1,
> we get no reply, but when we send packets to 192.168.77.1 we get the replies
> (that is where the abnormality begins). However; the replies are now sourced
> from 192.168.1.1 instead. That is, the blasted code in the device calculates
> the checksum using the wrong IP address which it thinks it is assigned to...
How about assigning an IP address that generates the same checksum to
the second interface? That'd solve your problem.
Or assign both interfaces the same IP address, maybe the device allows it.
>
> -----Original Message-----
> From: Aidas Kasparas [mailto:a.kasparas@gmc.lt]
> Sent: Saturday, August 21, 2004 9:47 AM
> To: Josan Kadett
> Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
>
> But will these checksums be incorect if crazy box would communicate with
> address in 192.168.1.x only?
>
> The whole idea was based on the fact, that if that box works well in
> 192.168.1.x networkd, then let it think it works in the network it knows
> how to work!
>
> Josan Kadett wrote:
> > It is definetely impossible to use IPTables to handle packets with
> incorrect
> > checksums since NAT would drop the connection right away, otherwise I
> would
> > not have been asking this question here.
> >
> > -----Original Message-----
> > From: Aidas Kasparas [mailto:a.kasparas@gmc.lt]
> > Sent: Saturday, August 21, 2004 8:54 AM
> > To: Josan Kadett
> > Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
> >
> > How about setting up a separate box which would listen on that
> > 192.168.77.1 address and MASQUERADE connections to your crazy box from
> > 192.168.1.x address? Maybe then you would no longer need to break things
> > in kernel?
> >
> >
> >
>
> --
> Aidas Kasparas
> IT administrator
> GM Consult Group, UAB
>
>
>
> -
> 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/
>
--
Vojtech Pavlik
SuSE Labs, SuSE CR
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 8:11 ` Denis Vlasenko
@ 2004-08-21 9:18 ` Josan Kadett
2004-08-21 8:26 ` Lee Revell
0 siblings, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 9:18 UTC (permalink / raw)
To: 'Denis Vlasenko'; +Cc: linux-kernel
That is not much of an intelligible idea. A way to hack the kernel could be
found as I still presume. "Turn off checksums" but not by re-writing the
whole tcp code in the kernel. Isn't that possible ? Linux is an operating
system of infinite possibilities, right ? But only if you know how to hack
it...
-----Original Message-----
From: Denis Vlasenko [mailto:vda@port.imtp.ilyichevsk.odessa.ua]
Sent: Saturday, August 21, 2004 10:11 AM
To: Josan Kadett; 'Aidas Kasparas'
Cc: linux-kernel@vger.kernel.org
Subject: RE: Entirely ignoring TCP and UDP checksum in kernel level
On Saturday 21 August 2004 12:00, Josan Kadett wrote:
> The problem is that the interface 192.168.1.1 does not allow any
> tranmission to occur. An implementation error I think... We send packets
to
> 192.168.1.1, we get no reply, but when we send packets to 192.168.77.1 we
> get the replies (that is where the abnormality begins). However; the
> replies are now sourced from 192.168.1.1 instead. That is, the blasted
code
> in the device calculates the checksum using the wrong IP address which it
> thinks it is assigned to...
Maybe dust off some old Pentium 133 and replace that piece of electronic
crap with decent Linux machine?
--
vda
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 8:26 ` Lee Revell
@ 2004-08-21 9:35 ` Josan Kadett
0 siblings, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 9:35 UTC (permalink / raw)
To: 'Lee Revell'; +Cc: linux-kernel
-----Original Message-----
From: Lee Revell [mailto:rlrevell@joe-job.com]
Sent: Saturday, August 21, 2004 10:26 AM
To: Josan Kadett
Cc: 'Denis Vlasenko'; linux-kernel
Subject: RE: Entirely ignoring TCP and UDP checksum in kernel level
On Sat, 2004-08-21 at 05:18, Josan Kadett wrote:
> That is not much of an intelligible idea. A way to hack the kernel could
be
> found as I still presume. "Turn off checksums" but not by re-writing the
> whole tcp code in the kernel. Isn't that possible ? Linux is an operating
> system of infinite possibilities, right ? But only if you know how to hack
> it...
>
>> Can't you just go into the networking code, and find the part where it
>> checks the checksum, and just have it return success, even if the
>> checksum was bad? Seems like a quick copy and paste hack. Am I missing
>> something?
>> Lee
Very well, it is what I really wish to do. The networking code is no simple
issue in linux. As I underlined, two c files, tcp_input.c and udp.c controls
how the checksum is done and the code looks very complicated. Perhaps you
have some idea about where in 100K source code to change in order to disable
checksumming but at the same time not to break normal operation. I can apply
a change in the code, recompile the kernel and test it. I have installed a
virtual machine running linux in order to experiment with the settings, but
the problem is that I do not have enough time to understand what the code is
all about. Perhaps it is in sock.h, perhaps skbuff.h, or any other file.
Each and every file seems to contain some function related to checksumming.
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 8:27 Denis Vlasenko
2004-08-21 8:41 ` Lee Revell
@ 2004-08-21 9:39 ` Josan Kadett
1 sibling, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 9:39 UTC (permalink / raw)
To: 'Denis Vlasenko'; +Cc: linux-kernel
You are misled. There are two machines in this scenario. One is our linux
box and the other is a 6000$ access concentrator which cannot be replaced
just for this reason. Embedded code in those network devices are often
bulky, so this is another problem the huge device is causing. Only "linux"
can do some hack in this case... So only way, hack the kernel...
In reply to the following;
--------------------------
Of course you can hack the kernel to do it.
However, by replacing that box with Linux device you
get one more Linux box and you will be capable of
doing whole slew of useful things, like traffic filtering, shaping,
accounting, Ethernet bridging, etc etc etc, if/when you will need it.
You can easily debug problems with tools like tcpdump and ethereal.
I simply cannot list everything Linux can do, I don't plan to write
a novel here ;]
I bet current 'crazy box' has nothing even vaguely resembling
these capabilities. Heck, it cannot do standard TCP properly.
So there is little reason to waste your time trying to work around it.
--
vda
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 8:41 ` Lee Revell
@ 2004-08-21 9:50 ` Josan Kadett
2004-08-21 9:06 ` Kalin KOZHUHAROV
0 siblings, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 9:50 UTC (permalink / raw)
To: 'Lee Revell'; +Cc: linux-kernel
Here is the very original linux-kernel mailing list, and if I cannot find an
answer here, then nowhere on earth can this answer be found. I also saw some
other messages regarding the same issue on the net. None of them is answered
correctly; and also as if this is a very "forbidden" thing to disable the
checksums, most replies are as if they are "unbreakable rules of god".
Really, I am losing my patience with this. It is also very odd to write a
low-level application in order to just disable a "feature" of the kernel to
deal with a faulty piece of embedded firmware.
In reply to;
------------
He already stated that he was dealing with a very expensive, very broken
piece of hardware, and he needs a way to work around it. Many of us
have been in this situation, I will not name names ;-). Telling him to
just replace it is not helpful.
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[not found] <1093120934.854.155.camel@krustophenia.net>
@ 2004-08-21 20:46 ` Lee Revell
2004-08-21 21:53 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Lee Revell @ 2004-08-21 20:46 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
On Sat, 2004-08-21 at 17:41, Josan Kadett wrote:
> I added the patch, indeed this was just one of the few modifications I tried
> before. The result is failure, the TCP/IP stack still does the checksum...
> Perhaps after this modification, the condition that the packet is not
> "eaten" may not be telling the system that there is a checksum error, but
> instead, just dropping packets by not igniting the TCP ACK function.
Please try Kalin's suggestion, instead of my patch. It's more generic,
plus my 'patch' didn't handle UDP.
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 8:58 ` Entirely ignoring TCP and UDP checksum in kernel level Lee Revell
@ 2004-08-21 21:41 ` Josan Kadett
0 siblings, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 21:41 UTC (permalink / raw)
To: 'Lee Revell'; +Cc: linux-kernel
I added the patch, indeed this was just one of the few modifications I tried
before. The result is failure, the TCP/IP stack still does the checksum...
Perhaps after this modification, the condition that the packet is not
"eaten" may not be telling the system that there is a checksum error, but
instead, just dropping packets by not igniting the TCP ACK function.
-----Original Message-----
From: Lee Revell [mailto:rlrevell@joe-job.com]
Sent: Saturday, August 21, 2004 10:58 AM
To: Josan Kadett
Cc: linux-kernel
Subject: RE: Entirely ignoring TCP and UDP checksum in kernel level
On Sat, 2004-08-21 at 05:50, Josan Kadett wrote:
> Here is the very original linux-kernel mailing list, and if I cannot find
an
> answer here, then nowhere on earth can this answer be found. I also saw
some
> other messages regarding the same issue on the net. None of them is
answered
> correctly; and also as if this is a very "forbidden" thing to disable the
> checksums, most replies are as if they are "unbreakable rules of god".
> Really, I am losing my patience with this. It is also very odd to write a
> low-level application in order to just disable a "feature" of the kernel
to
> deal with a faulty piece of embedded firmware.
>
Try this. I have no idea whether it will work. If it breaks you get to
keep both halves.
--- net/ipv4/tcp_input.c 2004-08-20 16:37:12.000000000 -0400
+++ net/ipv4/tcp_input.c-new 2004-08-21 04:56:51.000000000 -0400
@@ -4234,8 +4234,7 @@
}
}
if (!eaten) {
- if (tcp_checksum_complete_user(sk, skb))
- goto csum_error;
+ tcp_checksum_complete_user(sk, skb);
/* Predicted packet is in window by
definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
@@ -4291,7 +4290,7 @@
slow_path:
if (len < (th->doff<<2) || tcp_checksum_complete_user(sk, skb))
- goto csum_error;
+ ;
/*
* RFC1323: H1. Apply PAWS check first.
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 9:06 ` Kalin KOZHUHAROV
@ 2004-08-21 21:46 ` Josan Kadett
0 siblings, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 21:46 UTC (permalink / raw)
To: 'Kalin KOZHUHAROV'; +Cc: linux-kernel
Yes, I thought that just returning "0" from these function would
successfully disable checksumming, but now the situation is as such;
- TCP still does the checksum and seems as if no patch is applied at all
- UDP now does not do checksum if it should return a destination unreachable
error. (that means, when I inject a packet to a closed socket, regardless of
the checksum in the packet, the system now sends a destination unreachable
error). However this is the only change, still the application do not
receive UDP packets with wrong checksum. (Such as netcat or snmpget etc.)
Perhaps this is not the way?
-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of Kalin KOZHUHAROV
Sent: Saturday, August 21, 2004 11:07 AM
To: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
Josan Kadett wrote:
> Here is the very original linux-kernel mailing list, and if I cannot find
an
> answer here, then nowhere on earth can this answer be found. I also saw
some
> other messages regarding the same issue on the net. None of them is
answered
> correctly; and also as if this is a very "forbidden" thing to disable the
> checksums, most replies are as if they are "unbreakable rules of god".
> Really, I am losing my patience with this. It is also very odd to write a
> low-level application in order to just disable a "feature" of the kernel
to
> deal with a faulty piece of embedded firmware.
OK, try this, not tested:
replace the return statements with "return 0;" in:
net/ipv4/udp.c, function __udp_checksum_complete, about line 759
net/ipv4/icp_input.c, function __tcp_checksum_complete_user, about line 4070
* line numbers above are for linux-2.6.7
Kalin.
--
|| ~~~~~~~~~~~~~~~~~~~~~~ ||
( ) http://ThinRope.net/ ( )
|| ______________________ ||
-
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/
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-21 20:46 ` Lee Revell
@ 2004-08-21 21:53 ` Josan Kadett
0 siblings, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-21 21:53 UTC (permalink / raw)
To: 'Lee Revell'; +Cc: linux-kernel
Indeed I already had done that UDP and TCP patch before I posted this
thread. I think that is still not the way... I just tested the system using
the generic patch and the results are;
- I send a packet with wrong checksum to a closed UDP port, the kernel
replies it (It would seem that UDP checksum is gone but no)
- I send a packet with wrong checksum to a closed TCP port, the kernel drops
it (TCP will not budge)
- I send a packet with wrong checksum to an open UDP port, the kernel drops
it. (UDP checksum is still in effect somehow)
- I send an snmpget request to my client, intercept the packet, re-send it
to the linux machine which is pathced, snmpget gets the correct data
- I send an snmpget request to my client, intercept the packet, put arbitary
(wrong) checksum in it, re-send it to the linux machine which is patched,
snmpget does not even see the data coming in. (Still dropped by kernel)
Perhaps I should start another thread with another subject instead of
blindly trying to get rid of checksum?
-----Original Message-----
From: Lee Revell [mailto:rlrevell@joe-job.com]
Sent: Saturday, August 21, 2004 10:46 PM
To: Josan Kadett
Cc: linux-kernel
Subject: RE: Entirely ignoring TCP and UDP checksum in kernel level
On Sat, 2004-08-21 at 17:41, Josan Kadett wrote:
> I added the patch, indeed this was just one of the few modifications I
tried
> before. The result is failure, the TCP/IP stack still does the checksum...
> Perhaps after this modification, the condition that the packet is not
> "eaten" may not be telling the system that there is a checksum error, but
> instead, just dropping packets by not igniting the TCP ACK function.
Please try Kalin's suggestion, instead of my patch. It's more generic,
plus my 'patch' didn't handle UDP.
Lee
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[not found] <04Aug21.205911edt.41960@gpu.utcc.utoronto.ca>
@ 2004-08-22 2:08 ` Josan Kadett
2004-08-22 6:01 ` Brad Campbell
0 siblings, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 2:08 UTC (permalink / raw)
To: 'Chris Siebenmann'; +Cc: linux-kernel
Well, the device fails only in one type of operation, that is when it has to
receive packets from an internal port, it sends packets via its external IP
address.
I have managed to disable IP header checksumming by hacking the kernel (in
file ip_input.c). Now I have to do the same for tcp_input.c and udp.c .
Packet mangling will not be required because when I turn the rp_filter off,
the kernel does not care whether it is coming from the intended source or
not.
Now after disabling IP protocol checksumming, I passed to udp checksumming.
However; now the code is more complicated. And for the TCP there is 100K of
code. Well of course, with correct patch it would work, but as far as I can
see, there are many locations that needs to be changed in order to get this
work.
I also thought about packet mangling, but again something needs to be done
for checksums. By the way, it is not necessary to do as such. Perhaps, I
would later need it in case I see such errors in future but my current
problem has a rather easy solution.
I have received many replies about what to change in these codes. However;
none of them were correct at all. Either they disabled some part of
checksumming or cast the TCP/IP totally unavailable.
Any reference to code would be appreciated.
Regards...
-----Original Message-----
From: Chris Siebenmann [mailto:cks@utcc.utoronto.ca]
Sent: Sunday, August 22, 2004 2:59 AM
To: Josan Kadett
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
At least with TCP, I believe that if TCP is establishing a circuit
between (IP1, port1) and (IP2, port2), SYN+ACKs from (IP3, port2) will
generally be ignored. So it seems likely that you will not only have
to ignore the checksum failure but also mangle the IP packets that you
receive that claim to be from 'IP3' to claim to be from 'IP2' instead,
so that they match up with what the kernel expects.
(The alternative approach is to mangle on the outgoing path, such
that the Linux box at the high level thinks it's talking to IP3, but
IP3 is replaced by IP2 as each packet goes out.)
Has this particular chunk of hardware ever successfully talked to
anything via TCP/IP?
[And just to check: you are entirely 100% certain that the IP checksum
on incoming packets is incorrect?]
---
"I shall clasp my hands together and bow to the corners of the
world."
Number Ten Ox, "Bridge of Birds"
cks@utcc.toronto.edu
utgpu!cks
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 2:08 ` Josan Kadett
@ 2004-08-22 6:01 ` Brad Campbell
2004-08-22 7:06 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 6:01 UTC (permalink / raw)
To: Josan Kadett; +Cc: 'Chris Siebenmann', linux-kernel
Josan Kadett wrote:
> Well, the device fails only in one type of operation, that is when it has to
> receive packets from an internal port, it sends packets via its external IP
> address.
>
> I have managed to disable IP header checksumming by hacking the kernel (in
> file ip_input.c). Now I have to do the same for tcp_input.c and udp.c .
> Packet mangling will not be required because when I turn the rp_filter off,
> the kernel does not care whether it is coming from the intended source or
> not.
>
Just a completely random thought. What about re-calculating the checksum and correcting it when the
packet hits the IP layer prior to it being passed out to the relevant protocol handlers?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
@ 2004-08-22 6:17 Brad Campbell
2004-08-22 7:18 ` Josan Kadett
2004-08-22 7:24 ` Josan Kadett
0 siblings, 2 replies; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 6:17 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> That is certainly what I require but I need some guidelines; I investigated
> into the issue and fount out that;
>
> - By only changing the source address coded in the IP header
> - And by just applying checksum to IP header [Not TCP or UDP]
>
> The problem would be gone since when the source IP in the IP address field
> is validated, the checksum in the underlying protocol is automatically
> validated (because the sender system had already computed this CRC using the
> IP address which we want to write onto the packet)
>
> I do not have much time to build a code just for this purpose and thus I am
> looking for a simple app. or some other way...
So if we took any packet that came in from 192.168.1.1 and substituted 192.178.77.1 for the Source
address and then re-calculated the IP checksum you would be up and running?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 7:24 ` Josan Kadett
@ 2004-08-22 7:04 ` Brad Campbell
2004-08-22 8:12 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 7:04 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> **Indeed there is no longer such a need to recalculate the IP checksum
> because I have found a way to disable it by patching the kernel. So, only
> requirement is this;
>
> Change the source address of the packet before it reaches to the socket
> buffer aka skbuff.h. Because if it reaches that code with the wrong IP
> header, the csum will just drop it away.
The main reason I suggested correcting the checksum is if it was done that way, the kernel would
behave normally for all other IP traffic and simply do a dodgy on only traffic from 192.168.1.1
If nobody else jumps in, let me think about it for a day or so and I'll see what I can do. It's been
a couple of years since I last looked at the network code though.
What kernel are you running?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 6:01 ` Brad Campbell
@ 2004-08-22 7:06 ` Josan Kadett
0 siblings, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 7:06 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
That is certainly what I require but I need some guidelines; I investigated
into the issue and fount out that;
- By only changing the source address coded in the IP header
- And by just applying checksum to IP header [Not TCP or UDP]
The problem would be gone since when the source IP in the IP address field
is validated, the checksum in the underlying protocol is automatically
validated (because the sender system had already computed this CRC using the
IP address which we want to write onto the packet)
I do not have much time to build a code just for this purpose and thus I am
looking for a simple app. or some other way...
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 8:01 AM
To: Josan Kadett
Cc: 'Chris Siebenmann'; linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
Just a completely random thought. What about re-calculating the checksum and
correcting it when the
packet hits the IP layer prior to it being passed out to the relevant
protocol handlers?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 6:17 Brad Campbell
@ 2004-08-22 7:18 ` Josan Kadett
2004-08-22 7:24 ` Josan Kadett
1 sibling, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 7:18 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
Absolutely, that would correct the problem with the best possible
resolution.
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 8:17 AM
To: Josan Kadett
Cc: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
So if we took any packet that came in from 192.168.1.1 and substituted
192.178.77.1 for the Source
address and then re-calculated the IP checksum you would be up and running?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
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
1 sibling, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 7:24 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
**Indeed there is no longer such a need to recalculate the IP checksum
because I have found a way to disable it by patching the kernel. So, only
requirement is this;
Change the source address of the packet before it reaches to the socket
buffer aka skbuff.h. Because if it reaches that code with the wrong IP
header, the csum will just drop it away.
-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of Brad Campbell
Sent: Sunday, August 22, 2004 8:17 AM
To: Josan Kadett
Cc: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
So if we took any packet that came in from 192.168.1.1 and substituted
192.178.77.1 for the Source
address and then re-calculated the IP checksum you would be up and running?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 7:04 ` Brad Campbell
@ 2004-08-22 8:12 ` Josan Kadett
2004-08-22 8:29 ` Brad Campbell
0 siblings, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 8:12 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
Linux Kernel 2.4.18-14 [Redhat 8 standard installation]
As I underlined, I have been able to disable IP header checksumming for the
received packets, so the system will not drop the packets even after CRC
becomes invalid when the source address changes.
I have been asking this question over ten different mailing list and forums
and no one has come up with a "solid" solution. I would be exteremely glad
if I get a working source code.
I know the application will be so very simple, just changing some bits with
another and putting it back to userspace, but it requires some low-level
libraries and the knowledge to use them...
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 9:04 AM
To: Josan Kadett
Cc: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
The main reason I suggested correcting the checksum is if it was done that
way, the kernel would
behave normally for all other IP traffic and simply do a dodgy on only
traffic from 192.168.1.1
If nobody else jumps in, let me think about it for a day or so and I'll see
what I can do. It's been
a couple of years since I last looked at the network code though.
What kernel are you running?
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 8:12 ` Josan Kadett
@ 2004-08-22 8:29 ` Brad Campbell
0 siblings, 0 replies; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 8:29 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> Linux Kernel 2.4.18-14 [Redhat 8 standard installation]
>
> As I underlined, I have been able to disable IP header checksumming for the
> received packets, so the system will not drop the packets even after CRC
> becomes invalid when the source address changes.
>
> I have been asking this question over ten different mailing list and forums
> and no one has come up with a "solid" solution. I would be exteremely glad
> if I get a working source code.
>
> I know the application will be so very simple, just changing some bits with
> another and putting it back to userspace, but it requires some low-level
> libraries and the knowledge to use them...
This *MAY* do what you want.. (Compiled and tested on 2.4.26)
--- /usr/src/linux-2.4.26/net/ipv4/ip_input.c 2002-08-03 04:39:46.000000000 +0400
+++ net/ipv4/ip_input.c 2004-08-22 12:22:41.000000000 +0400
@@ -417,6 +417,10 @@
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
goto inhdr_error;
+ printk("Ip saddr %08x -- ",iph->saddr);
+ if (iph->saddr == 0x0101a8c0) // 192.168.1.1
+ iph->saddr = 0x014da8c0; // 192.168.77.1
+ printk("Ip saddr %08x\n",iph->saddr);
{
__u32 len = ntohs(iph->tot_len);
When you verify what it's doing, just remove the printk's.
I did it here using one of my local addresses (uml == 192.168.2.84)
And had the above addresses convert 192.168.2.85 to 192.168.77.1
bklaptop:/home/brad# tcpdump -i tap0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes
12:24:16.723748 IP 192.168.2.85 > uml: icmp 64: echo request seq 0
12:24:16.725119 arp who-has gateway tell uml
12:24:17.289458 arp reply gateway is-at 00:ff:14:7a:fe:66
12:24:17.290282 IP uml > 192.168.77.1: icmp 64: echo reply seq 0
12:24:17.720057 IP 192.168.2.85 > uml: icmp 64: echo request seq 256
12:24:17.723690 IP uml > 192.168.77.1: icmp 64: echo reply seq 256
12:24:18.720632 IP 192.168.2.85 > uml: icmp 64: echo request seq 512
12:24:18.724369 IP uml > 192.168.77.1: icmp 64: echo reply seq 512
Good luck.
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
@ 2004-08-22 9:19 Brad Campbell
0 siblings, 0 replies; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 9:19 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> It is certainly the solution to the issue. Indeed, everything works fine
> including NAT because the hack is in the kernel level. Your assistance is
> greatly appreciated. The first issue is complete but for now I think I will
> get into a lesser one. (I will write about it when I get have all the
> details)
Wicked! It's often the simple things.
Glad I could help.
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 10:25 ` Josan Kadett
@ 2004-08-22 9:36 ` Brad Campbell
2004-08-22 10:48 ` Josan Kadett
0 siblings, 1 reply; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 9:36 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> Bad news... NAT does not work, but it should have worked. Where might be the
> mistake ? I put another machine connected next to the patched linux server,
> I sniff the traffic and see that:
> (I enabled SNAT);
>
> Packet arrives from 192.168.0.30 (new machine to test nat)
> The packet is correctly translated and sent over the line
> With the patch, the new packet seems to arrive from correct source 77.1
>
> *But this is where the problem begins, the system does not send the received
> packet to the address which is SNATted. I thought, the ip_input.c code would
> work in the lowest level so IPTABLES would naively use the changed source
> address...
>
> I do not know if ever this problem will end...
>
>
>>
>>Client A 192.168.0.20 -- connects to patched linux server
>>Linux 192.168.1.1 -- translates the source address 192.168.x.x to
>
> 1.1(SNAT)
You have 192.168.0.x NAT to 192.168.1.1?
I thought you wanted to NAT to 192.168.77.1?
My understanding was you sent a packet to 192.168.77.1 and the device sent it back from 192.168.1.1
Can you send me your iptables configuration?
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[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
1 sibling, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 10:14 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
It is certainly the solution to the issue. Indeed, everything works fine
including NAT because the hack is in the kernel level. Your assistance is
greatly appreciated. The first issue is complete but for now I think I will
get into a lesser one. (I will write about it when I get have all the
details)
Best Regards...
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 10:48 AM
To: Josan Kadett
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
No.. this should work for you.. Try it and see anyway.
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
[not found] <41285DB3.6070605@wasp.net.au>
2004-08-22 10:14 ` Josan Kadett
@ 2004-08-22 10:25 ` Josan Kadett
2004-08-22 9:36 ` Brad Campbell
1 sibling, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 10:25 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
Bad news... NAT does not work, but it should have worked. Where might be the
mistake ? I put another machine connected next to the patched linux server,
I sniff the traffic and see that:
(I enabled SNAT);
Packet arrives from 192.168.0.30 (new machine to test nat)
The packet is correctly translated and sent over the line
With the patch, the new packet seems to arrive from correct source 77.1
*But this is where the problem begins, the system does not send the received
packet to the address which is SNATted. I thought, the ip_input.c code would
work in the lowest level so IPTABLES would naively use the changed source
address...
I do not know if ever this problem will end...
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 10:48 AM
To: Josan Kadett
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
Josan Kadett wrote:
> This does actually change the source IP address of the machine and allow
> NAT??
>
> Client A 192.168.0.20 -- connects to patched linux server
> Linux 192.168.1.1 -- translates the source address 192.168.x.x to
1.1(SNAT)
>
> And will NAT actually work with this patch, as far as I see, this code
gets
> the saddr and puts another one when the condition matches?
No.. this should work for you.. Try it and see anyway.
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
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
0 siblings, 2 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 10:48 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
I am still persistent on the fact that NAT should work with this sense.
I just enable NAT with the following command
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 192.168.1.5
This IP 192.168.1.5 is our patched linux server which is allowed to acccess
192.168.1.77
Now all protocols in the linux system is working fine as ever, and even ping
sent to 192.168.77.1 returns from 192.168.77.1 that is visible in the
presumably lowest layer of network stack (as tcpdump also sees it that way).
However; the client on the interface eth0 which has the IP address of
192.168.0.30 gets its IP address translated to 192.168.1.5, the ping is sent
and a response is received (tcpdump shows it)
But the patched linux system does not translate it back to the client that
requested that ping. That means, only our patched linux system can access to
the node, but nothing else.
I tested NAT for another interface (not eth1 whose connection is now somehow
patched) to send a request to google.com, the NAT ensuredly works for any
other IP but 192.168.77.1.
I am suspiciuous about the fact that IPTables might still see the wrong IP
address of the device before it is changed by the patch (192.168.1.1), thus
it drops the packet there. However; this event is rather odd...
BTW, the problem is at the edge of being resolved, since the hardest part is
now gone. But I could not believe all this would be gone by two lines of
code... The solution must be there;
*You could test the NAT to see whether it works for your configuration, this
time I am totally out of ideas...
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 11:36 AM
To: Josan Kadett
Cc: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
You have 192.168.0.x NAT to 192.168.1.1?
I thought you wanted to NAT to 192.168.77.1?
My understanding was you sent a packet to 192.168.77.1 and the device sent
it back from 192.168.1.1
Can you send me your iptables configuration?
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 10:14 ` Josan Kadett
@ 2004-08-22 11:48 ` James Courtier-Dutton
0 siblings, 0 replies; 43+ messages in thread
From: James Courtier-Dutton @ 2004-08-22 11:48 UTC (permalink / raw)
To: Josan Kadett; +Cc: 'Brad Campbell', linux-kernel
Josan,
Would you like to tell us the Make and Model of this problem box, so we
can all avoid them in future?
James
Josan Kadett wrote:
> It is certainly the solution to the issue. Indeed, everything works fine
> including NAT because the hack is in the kernel level. Your assistance is
> greatly appreciated. The first issue is complete but for now I think I will
> get into a lesser one. (I will write about it when I get have all the
> details)
>
> Best Regards...
>
> -----Original Message-----
> From: Brad Campbell [mailto:brad@wasp.net.au]
> Sent: Sunday, August 22, 2004 10:48 AM
> To: Josan Kadett
> Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
>
> No.. this should work for you.. Try it and see anyway.
>
> Regards,
> Brad
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 10:48 ` Josan Kadett
@ 2004-08-22 13:10 ` Brad Campbell
2004-08-22 13:13 ` Brad Campbell
1 sibling, 0 replies; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 13:10 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> I am still persistent on the fact that NAT should work with this sense.
>
> I just enable NAT with the following command
>
> iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 192.168.1.5
>
> This IP 192.168.1.5 is our patched linux server which is allowed to acccess
> 192.168.1.77
>
Ok.. Idea time..
Can you add another linux box in there. Something like
Client (192.168.0.30) ---> Box1Eth0(192.168.0.1) SNAT Box1Eth1(192.168.1.99) --->
Box2Eth0(192.168.1.100) () Box2Eth1(192.168.77.99) ---> HorridBuggyBox(192.168.77.1)
With Box 1 doing the NAT and Box 2 having the patch and just doing normal routing.
Have a route in Box 1 set to send 192.168.77.0/24 to the gateway at 192.168.1.100 which will know to
send anything destined for 192.168.77.1 out eth1.
If I try it, it's going to work fine as I don't have a box that munges IP's like yours does so I
can't provide a full test. (I guess I could butcher another UML to do it if I really had to)
Doing this stuff is so much easier when you have the faulty device in front of you. Your not in the
UAE by any chance ;p)
Regards,
Brad
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
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
1 sibling, 2 replies; 43+ messages in thread
From: Brad Campbell @ 2004-08-22 13:13 UTC (permalink / raw)
To: Josan Kadett; +Cc: linux-kernel
Josan Kadett wrote:
> I am still persistent on the fact that NAT should work with this sense.
>
> I just enable NAT with the following command
>
> iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 192.168.1.5
>
> This IP 192.168.1.5 is our patched linux server which is allowed to acccess
> 192.168.1.77
>
> Now all protocols in the linux system is working fine as ever, and even ping
> sent to 192.168.77.1 returns from 192.168.77.1 that is visible in the
> presumably lowest layer of network stack (as tcpdump also sees it that way).
>
> However; the client on the interface eth0 which has the IP address of
> 192.168.0.30 gets its IP address translated to 192.168.1.5, the ping is sent
> and a response is received (tcpdump shows it)
>
Are you trying to ping 192.168.77.1 from 192.168.0.30?
Can you give me an iptables -L -n -t nat, ifconfig and route -n from the patched box and also route
-n and ifconfig from the dummy client at 192.168.0.30 so I can try and get a handle on what you are
doing and how it all is supposed to work?
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-22 13:13 ` Brad Campbell
@ 2004-08-22 19:27 ` Josan Kadett
2004-08-22 20:28 ` Josan Kadett
1 sibling, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 19:27 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
Very well I am trying to ping this device from a host connected to our linux
box whose source IP is translated. I changed the IP numbers a bit so they
won't interfere with each ether in any way (absolutely different subnets)
Eth0 is connected the path where the problematic 192.168.77.1 is reached.
The IP number of assigned to eth1 interface is 192.168.1.5. Now with the
patch applied, any request to 192.167.77.1 seems to return from 192.168.77.1
Eth1 is connected to a private network with the IP address of 1.1.1.1, and
the IP address of the host whose connection will be SNATted is 1.1.1.30.
When I ping 192.168.77.1, everything seems correct now, but when I ping that
IP 1.1.1.30, indeed the transaction is made, but the linux box is somehow
"reluctant" to send te response back.
Iptables -L -n -t nat:
Chain POSTROUTING (policy ACCEPT)
Target prot opt source destination
SNAT all -- 0.0.0.0/0 0.0.0.0/0
to:192.168.1.2
0.0.0.0 means anywhere I presume...
Ifconfig of the patched box
Eth0: inet address 192.168.1.5, netmask 255.255.0.0 (external if)
Eth1: inet address 1.1.1.1, netmak 255.255.255.0 (internal if)
Routing tables:
Destination Gateway Genmaks Flags Metric Ref Use
Iface
192.168.77.1 192.168.1.2 255.255.255.0 UGH 0 0 0 eth0
1.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
192.168.0.0 0.0.0.0 255.255.0.0 U 0 0 0
eth0
NAT client uses IP address 1.1.1.30, with netmask of 255.255.255.0 with the
default gateway 1.1.1.1 (linux box).
Tcpdump[ eth0 / the address translation occurs correctly]
Ping request - 192.168.1.5 to 192.168.77.1
Ping reply - From 192.168.77.1 to 192.168.1.5
Ping request - 192.168.1.5 to 192.168.77.1
Ping reply - From 192.168.77.1 to 192.168.1.5
Ping request - 192.168.1.5 to 192.168.77.1
Ping reply - From 192.168.77.1 to 192.168.1.5
Tcpdump[ eth1 / no reply is sent by our linux system]
Ping request - 1.1.1.30 to 192.168.77.1
Ping request - 1.1.1.30 to 192.168.77.1
Ping request - 1.1.1.30 to 192.168.77.1
Both dumps are taken at the same time, I ensure that the linux box just does
not redirect the ping reply to the client 1.1.1.30 that requested it.
What can this be now? NAT still does not work in a way - or is there
something missing ?
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 3:14 PM
To: Josan Kadett
Cc: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
Are you trying to ping 192.168.77.1 from 192.168.0.30?
Can you give me an iptables -L -n -t nat, ifconfig and route -n from the
patched box and also route
-n and ifconfig from the dummy client at 192.168.0.30 so I can try and get a
handle on what you are
doing and how it all is supposed to work?
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
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
1 sibling, 1 reply; 43+ messages in thread
From: Josan Kadett @ 2004-08-22 20:28 UTC (permalink / raw)
To: 'Brad Campbell'; +Cc: linux-kernel
I have found the exact reason why NAT does not work;
- The patched linux box ignores IP checksum errors
- Since now the source address is mofidified without checksumming, NAT also
carries that wrong checksum
- Other boxes does not ignore the checksum and drop packets
I think the solution is here, I have done many different modifications to
get the system redirect packets with wrong checksum. Now all to be done, is
to correct this checksum by changing some code in ip_input.c so that it
recalculates the checksum when the packets seem to arrive from 192.168.1.1.
Where in the code then?
-----Original Message-----
From: Brad Campbell [mailto:brad@wasp.net.au]
Sent: Sunday, August 22, 2004 3:14 PM
To: Josan Kadett
Cc: linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
Are you trying to ping 192.168.77.1 from 192.168.0.30?
Can you give me an iptables -L -n -t nat, ifconfig and route -n from the
patched box and also route
-n and ifconfig from the dummy client at 192.168.0.30 so I can try and get a
handle on what you are
doing and how it all is supposed to work?
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Entirely ignoring TCP and UDP checksum in kernel level
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
0 siblings, 2 replies; 43+ messages in thread
From: David Meybohm @ 2004-08-23 3:38 UTC (permalink / raw)
To: Josan Kadett; +Cc: 'Brad Campbell', linux-kernel
On Sun, Aug 22, 2004 at 10:28:10PM +0200, Josan Kadett wrote:
> I have found the exact reason why NAT does not work;
>
> - The patched linux box ignores IP checksum errors
> - Since now the source address is mofidified without checksumming, NAT also
> carries that wrong checksum
> - Other boxes does not ignore the checksum and drop packets
>
> I think the solution is here, I have done many different modifications to
> get the system redirect packets with wrong checksum. Now all to be done, is
> to correct this checksum by changing some code in ip_input.c so that it
> recalculates the checksum when the packets seem to arrive from 192.168.1.1.
>
> Where in the code then?
The attached patch might work. It changes the IP source address from
192.168.1.1 to 192.168.77.1 and then recalculates the IP header
checksum. (I haven't tested it, though).
Do I understand you correctly that the IP checksum is calculated
correctly, but for the address 192.168.1.1, and the UDP and TCP
checksums are computed as if the address was 192.168.77.1? If so, I
think this should work...
Now, can you please oblige us with the name of the manufacturers of the
broken router (as someone else also previously requested), so they can
be properly publicly ridiculed? :-)
Hope it helps,
Dave
---
diff -puN net/ipv4/ip_input.c~ip-ignore-csum net/ipv4/ip_input.c
--- v2.6.8/net/ipv4/ip_input.c~ip-ignore-csum 2004-08-22 22:56:34.000000000 -0400
+++ v2.6.8-dym/net/ipv4/ip_input.c 2004-08-22 23:07:26.000000000 -0400
@@ -355,6 +355,27 @@ drop:
return NET_RX_DROP;
}
+static inline void mangle_addr_and_csum(struct iphdr *iph)
+{
+#define MANGLE_SADDR_IN htonl(0xc0a80101)
+#define MANGLE_SADDR_OUT htonl(0xc0a84d01)
+
+ if (iph->saddr != MANGLE_SADDR_IN)
+ return;
+
+ /* Change the source address from 192.168.1.1 to 192.168.77.1 and
+ * correct the checksum. */
+ iph->saddr = MANGLE_SADDR_OUT;
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
+
+ /* Make sure the checksum is correct now. */
+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) {
+ printk(KERN_ERR "checksum %08x -> %08x failed! (%04x)\n",
+ MANGLE_SADDR_IN, iph->saddr, iph->check);
+ }
+}
+
/*
* Main IP Receive routine.
*/
@@ -399,6 +420,9 @@ int ip_rcv(struct sk_buff *skb, struct n
iph = skb->nh.iph;
+ /* Take care of broken router. */
+ mangle_addr_and_csum(iph);
+
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
goto inhdr_error;
_
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-23 3:38 ` David Meybohm
@ 2004-08-23 5:26 ` Josan Kadett
2004-08-23 8:40 ` Josan Kadett
1 sibling, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-23 5:26 UTC (permalink / raw)
To: 'David Meybohm'; +Cc: linux-kernel
The device is a Cisco AS3640-T1 but it is not the fault of the device but
our enforcing an unusual configuration in order to connect two networks to
each other. This way we thought it would cut some extra work out, I
investigated the configuration and I believed in the fact that Linux can
handle this anomaly.
Indeed, we do try to connect two networks without the necessary equipment,
and it is at edge of a successful completion.
I tried another patch that is so similar to the code you submitted, indeed
now the linux machine can communicate with the device without any problem.
But there is only one thing left, I'd be extremely glad if you assist in
this last issue so that I will have completed what I started;
Now the system receives the packets from the correct source which is
192.168.77.1. But now, I am trying to establish a "destination nat" scheme,
which will enable this linux machine to act as a gateway to this device.
However; this gateway should have the exact IP number as the device itself
so that the link is not broken for hosts whose subnets are not in the subnet
to which the AC would respond. If we change these subnets with the correct
one, whole IP configuration would be screwed up.
So now the issue would seem simple;
We would just assign the exact IP number (192.168.77.1) to one of the
interfaces of the linux machine that has the uplink, and build a NAT table
using Iptables so that any request,
To 192.168.77.1 [IF 1] would be redirected to 192.168.77.1 [IF 2]**
Now the problem lies here, I cannot tell the linux machine not to route NAT
to its own loopback adapter. The machine is naturally thinking that this IP
address is its own and nothing works out this way.
I have come up with a solution that should do exactly what we wish;
Similar to the patch of ip_input.c, we could tell the machine that it should
send all IP data to 192.168.1.1 [dumb port of the AC - the source of all
problems]. Just before the system sends that packet, now its destination IP
address should be mangled with the correct one [192.168.77.1]. This way NAT
should work because the system will still think that it is sending a request
to 192.168.1.1, but it will be sent to 77.1 and data will be received from
77.1.
So the code I presume should be as follows;
1. Check if the outgoing packet is going to 192.168.1.1
2. If it is going there mangle it with 192.168.77.1 and checksum
3. TCP and UDP layer should also create their psuedo-headers with
192.168.77.1 because otherwise this time AC won't receive it
4. Receive data back from 192.168.77.1 and translate
** But if the NAT still would insist that it should get packets from the
address it intended to communicate [Hopefully not]; in that case;
5. The ip_input.c patch this time would not be used anyway
6. But now the TCP and UDP checksums would be voided as usual
7. Correct TCP and UDP checksums of the input packet
8. Put them on the socket
So this means we require a similar patch for ip_output.c. Regardless of
those seeminlgy impossible problems, I will persist on the fact that there
are always alternative ways to handle an issue...
Best Regards...
-----Original Message-----
From: David Meybohm [mailto:dmeybohm@bellsouth.net]
Sent: Monday, August 23, 2004 5:38 AM
To: Josan Kadett
Cc: 'Brad Campbell'; linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
The attached patch might work. It changes the IP source address from
192.168.1.1 to 192.168.77.1 and then recalculates the IP header
checksum. (I haven't tested it, though).
Do I understand you correctly that the IP checksum is calculated
correctly, but for the address 192.168.1.1, and the UDP and TCP
checksums are computed as if the address was 192.168.77.1? If so, I
think this should work...
Now, can you please oblige us with the name of the manufacturers of the
broken router (as someone else also previously requested), so they can
be properly publicly ridiculed? :-)
Hope it helps,
Dave
---
diff -puN net/ipv4/ip_input.c~ip-ignore-csum net/ipv4/ip_input.c
--- v2.6.8/net/ipv4/ip_input.c~ip-ignore-csum 2004-08-22
22:56:34.000000000 -0400
+++ v2.6.8-dym/net/ipv4/ip_input.c 2004-08-22 23:07:26.000000000 -0400
@@ -355,6 +355,27 @@ drop:
return NET_RX_DROP;
}
+static inline void mangle_addr_and_csum(struct iphdr *iph)
+{
+#define MANGLE_SADDR_IN htonl(0xc0a80101)
+#define MANGLE_SADDR_OUT htonl(0xc0a84d01)
+
+ if (iph->saddr != MANGLE_SADDR_IN)
+ return;
+
+ /* Change the source address from 192.168.1.1 to 192.168.77.1 and
+ * correct the checksum. */
+ iph->saddr = MANGLE_SADDR_OUT;
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
+
+ /* Make sure the checksum is correct now. */
+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) {
+ printk(KERN_ERR "checksum %08x -> %08x failed! (%04x)\n",
+ MANGLE_SADDR_IN, iph->saddr, iph->check);
+ }
+}
+
/*
* Main IP Receive routine.
*/
@@ -399,6 +420,9 @@ int ip_rcv(struct sk_buff *skb, struct n
iph = skb->nh.iph;
+ /* Take care of broken router. */
+ mangle_addr_and_csum(iph);
+
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
goto inhdr_error;
_
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Entirely ignoring TCP and UDP checksum in kernel level
2004-08-23 3:38 ` David Meybohm
2004-08-23 5:26 ` Josan Kadett
@ 2004-08-23 8:40 ` Josan Kadett
1 sibling, 0 replies; 43+ messages in thread
From: Josan Kadett @ 2004-08-23 8:40 UTC (permalink / raw)
To: 'David Meybohm'; +Cc: linux-kernel, linux-net
So to summarize the AC issue;
There is an AC whose "real" failure is a simple programming error. Normally
it had to have two different IP adresses, one for 192.168.77.0 subnet, the
other for 192.168.1.0 subnet. Indeed it has two addresses but the address at
192.168.1.1 is wrongly bound to TCP/IP socket.
If everything were correct, when I would ping 192.168.1.1, it would return a
ping from 192.168.1.1. But now when I ping 192.168.1.1, it just discards the
packet. That lies in the source of this trouble.
I am extremely glad to have got a solution for this issue in less than three
days by fanatical assistance from the linux-kernel mailing list. Everything
has been put on place and two networks are bound together perfectly.
Technically, this event shows what an open-source O/S can do in case of
network anomalies.
However; for now I wish to get deeper into the kernel networking code to
continue my started work even I resolved this issue. This way, I think I
will be able to handle possible future troubles much easier.
Today, I have discovered that NAT does not handle packets correctly if the
return address is different from the intended destination. That is, in a
complex network network, if a node is sending a packet through another
address (even if this packet is fully correct in checksums, unlike this
exceptional trouble, which is now a patched issue), NAT will not be able to
correctly translate packets. I thought it could have been resolved by
disabling rp_filter in /proc/../conf/*, but it was not correct.
So for now, I wish to implement another patch to be able to transparently
surpass this exceptional failure in the AC just to learn some more about the
kernel and packet mangling.
1. The system must think that it is sending the packet to 192.168.1.1 even
if it will be mangled by the kernel to be sent to 192.168.77.1. All three
checksums should be correct (IP, TCP and UDP) so that the remote node will
receive packets correctly.
2. The system must think that it is receiving packets from 192.168.77.1,
indeed before the kernel patch was applied, the packets had a source address
of 192.168.1.1, but they had incorrect checksums in the underlying protocols
(TCP and UDP) so that our system would drop all that was received. Now I
will have to update the CRC's in these corrupted packets with the correct
ones.
In order to establish the first;
- Ip_output.c should be patched so that, when the condition matches, the
system will mangle the destination address of the outgoing packet and append
correct checksums to the IP header.
- After that it should be ensured that the underlying protocols also compute
the correct checksum using the mangled destination address in their
psuedo-headers. [ Perhaps this is already done automatically by a call to a
function ]
In order to establish the second;
- Ip_input.c should be unpatched for now, since our aim is much different.
It will receive a packet from the 192.168.1.1, and leave the address and
checksum in it, unchanged.
- tcp_input.c and udp.c now would be in action to decode and put the data in
the socket buffer. They would naturally construct the psuedo-headers using
the destination address of 192.168.1.1, and as in the beginning, the
checksums will be voided.
- These two codes should be patched in such a way that they re-compute the
checksums whilst they are copying them in to the datagram buffer using the
function int skb_copy_and_csum_datagram_iovec(). This is not a normal
behaviour of operation, but simply ignoring checksums would cause other
clients to fail, even if the linux machine just ignores the wrong CRC's and
copies the data to the socket buffer.
This issue is not critical now because the "critical" part is gone, it is
just an experimentation with the code, but I would be glad to receive any
contribution from the mailing-list.
Best Regards...
-----Original Message-----
From: David Meybohm [mailto:dmeybohm@bellsouth.net]
Sent: Monday, August 23, 2004 5:38 AM
To: Josan Kadett
Cc: 'Brad Campbell'; linux-kernel@vger.kernel.org
Subject: Re: Entirely ignoring TCP and UDP checksum in kernel level
The attached patch might work. It changes the IP source address from
192.168.1.1 to 192.168.77.1 and then recalculates the IP header
checksum. (I haven't tested it, though).
Do I understand you correctly that the IP checksum is calculated
correctly, but for the address 192.168.1.1, and the UDP and TCP
checksums are computed as if the address was 192.168.77.1? If so, I
think this should work...
Now, can you please oblige us with the name of the manufacturers of the
broken router (as someone else also previously requested), so they can
be properly publicly ridiculed? :-)
Hope it helps,
Dave
---
diff -puN net/ipv4/ip_input.c~ip-ignore-csum net/ipv4/ip_input.c
--- v2.6.8/net/ipv4/ip_input.c~ip-ignore-csum 2004-08-22
22:56:34.000000000 -0400
+++ v2.6.8-dym/net/ipv4/ip_input.c 2004-08-22 23:07:26.000000000 -0400
@@ -355,6 +355,27 @@ drop:
return NET_RX_DROP;
}
+static inline void mangle_addr_and_csum(struct iphdr *iph)
+{
+#define MANGLE_SADDR_IN htonl(0xc0a80101)
+#define MANGLE_SADDR_OUT htonl(0xc0a84d01)
+
+ if (iph->saddr != MANGLE_SADDR_IN)
+ return;
+
+ /* Change the source address from 192.168.1.1 to 192.168.77.1 and
+ * correct the checksum. */
+ iph->saddr = MANGLE_SADDR_OUT;
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
+
+ /* Make sure the checksum is correct now. */
+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) {
+ printk(KERN_ERR "checksum %08x -> %08x failed! (%04x)\n",
+ MANGLE_SADDR_IN, iph->saddr, iph->check);
+ }
+}
+
/*
* Main IP Receive routine.
*/
@@ -399,6 +420,9 @@ int ip_rcv(struct sk_buff *skb, struct n
iph = skb->nh.iph;
+ /* Take care of broken router. */
+ mangle_addr_and_csum(iph);
+
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
goto inhdr_error;
_
^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2004-08-23 7:40 UTC | newest]
Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1093078213.854.76.camel@krustophenia.net>
2004-08-21 8:58 ` Entirely ignoring TCP and UDP checksum in kernel level Lee Revell
2004-08-21 21:41 ` Josan Kadett
[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
2004-08-22 9:19 Brad Campbell
-- strict thread matches above, loose matches on Subject: below --
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
[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
[not found] <1093120934.854.155.camel@krustophenia.net>
2004-08-21 20:46 ` Lee Revell
2004-08-21 21:53 ` 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
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] <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
2004-08-21 6:15 Josan Kadett
2004-08-21 7:10 ` Willy Tarreau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox