[Jool-list] SIIT fragmentation header translation

Alberto Leiva ydahhrk at gmail.com
Wed Feb 15 10:49:40 CST 2017


Hello, Szymon

I believe this is the problem: SIITs cannot translate checksums within
fragmented ICMPv6 packets. Here's why:

Most of the time, layer 4 checksums include a pseudoheader:

https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation

TCP, UDP and ICMPv6 checksums all include pseudoheaders. The one
important exception is ICMPv4. Now, if you take a look at ICMPv6's
pseudoheader, you will notice that there is a field called "ICMPv6
length":

https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol_version_6#Message_checksum

This is the length of the whole ICMP message. It is not the length of
the ICMP payload in the current packet; it is the length of the ICMP
payload when all the fragments have been combined.

So, when translating an ICMPv6 fragment to ICMPv4, Jool faces a
problem: It needs to remove (subtract) the pseudoheader from the
checksum for it to be valid. Removing the addresses, zeroes and next
header is trivial because they can be inferred from the packet. But
how can it figure out the full length of the ICMP message so it can be
subtracted from the checksum? It's impossible. This information cannot
be found in any headers. The only way to know it would be to
reassemble the fragments and compute the length on the fly. However,
this is not viable because SIITs are supposed to be stateless and
having to reassemble would require storing the fragments for a while
(i.e. it would force the SIIT to store state).

So, because Jool cannot translate the checksum into something valid,
translating the packet would be pointless; the destination would drop
the packet because the checksum would not match. So instead of sending
an invalid packet, Jool drops it.

The same problem will happen in the ICMPv4->ICMPv6 direction; SIIT
Jool cannot compute the total length it needs to include in the
checksum's pseudoheader. TCP and UDP do not have this problem because
both original and translated packets include pseudoheader (and
therefore length as well), and the length does not change. Subtracting
a length from a checksum and adding the same amount again is
equivalent to not modify the checksum, so Jool does not need to know
the total length of the TCP/UDP message to yield a valid checksum.

We choose to live with this because fragmented pings are not very
important Internet traffic.

Here's Jool's validation:
https://github.com/NICMx/Jool/blob/v3.5.2/mod/common/packet.c#L256.
"If the translation is SIIT, the packet is fragmented and an ICMP
ping, then drop the packet."

Notice that you can enable logging
(https://www.jool.mx/en/logging.html), and Jool should give you hints
as to what is happening with packets. In this case, you should have
seen a message somewhat like this:

        Packet is a fragmented ping; its checksum cannot be translated.

Now, I'm not entirely sure because I wrote the code a long time ago,
but if you force the kernel to reassemble fragments, then SIIT Jool
might be able to compute the checksum. This might be the reason why
your translation from ICMPv4 to ICMPv6 seems to have worked. However,
note that this turns your box into something stateful and therefore
defeats the point of SIIT to some extent.

If it is really important to you, you can force defragmentation (until
the next reboot) by running:

        sudo modprobe nf_defrag_ipv4
        sudo modprobe nf_defrag_ipv6

If Jool still refuses to translate the checksum with that on, and you
really need those packets translated, then you would be welcomed to
upload a new issue and we would take care of it at some point:
https://github.com/NICMx/Jool/issues

I hope I wasn't too confusing. Let us know if you need anything else.
Alberto

On Tue, Feb 14, 2017 at 6:28 PM, Szymon Kałdonek
<uwagarobietosty at gmail.com> wrote:
> Dear Sir or Madam,
>
> I am an ICT student of Military University of Technology in Warsaw. I am
> writing my graduation work which is about limitations in comunication
> between IPv4 and IPv6 networks. I have a problem which I could not solve by
> reading documentation.
>
> I tried to connect two hosts in different networks by Stateless IP/ICMP
> translation using Jool 3.5.2 implementation. I was using yours tutorial
> about SIIT. The connection between computers in different networks was
> successful. I was sending prepared packets (ICMP, UDP and TCP) and also I
> was trying to do some functional tests. However I have a problem with
> sending ICMP packet which is fragmented. The problem appears when I send big
> ICMP packets from IPv6 network to IPv4 network. The size of these packets
> impose using fragmentation header in IPv6 packet. I check it in packet
> analyser and I noticed that this packet is generating and sending to
> translator's IPv6 interface but translator do nothing with it. I tried to
> find explanation of this issue in documentation but as I said before I can
> not find answer there.
>
> I also tried to send big ICMP packet from IPv4 computer to IPv6 computer and
> then translator had no problem to translate traffic and ICMP packet reached
> the destination although the fragmentation header was included.
>
> I would like to know if this is problem caused by my inappropriate
> configuration or this is correct action. I tried to configure translator
> properly more than twice and this problem appeared each time. Every
> additional information about it will be helpful for me.
>
>
> --
> Yours faithfully
> ,
> Szymon K.
> Military University of Technology (MUT)
>


More information about the Jool-list mailing list