The 6LoWPAN dissector manages to correctly assemble consecutive 6LoWPAN fragments into the upper layer protocol packet (not counting the IEEE 802.15.4 acks). However, if a fragment with different source and/or destination comes in between, the dissector can sometimes assemble it with the first fragment if some of the other parameters match.The attached capture shows the problem. First the encryption configuration needs to be settled, along with other Thread protocol parameters: - 6LoWPAN context: fd00:db8::/64 - CoAP port number: 61631 - IEEE 802.15.4 decryption key: 00112233445566778899aabbccddeeff - IEEE 802.15.4 decryption key index: 1 - IEEE 802.15.4 key hash: Thread hashIn the capture, the packet #99 is not acked, and is retransmitted in #102 (both with sequence number 157, source 0x0401 and destination 0x0400). In the meantime, #100 arrives (with sequence number 172, source 0x0400 and destination 0x0000). But the result is that #102 is shown as a CoAP message from 0x0401 to 0x0400.The correct situation should has been assembling #100 together with #104 to form a CoAP message from 0x0400 to 0x0000.
Testing with (without -2V, with -2 and with -V):tshark -r 6lowpan-dissector-problem.pcap \ -o6lowpan.context0:fd00:db8::/64 -dudp.port==61631,coap \ -ouat:ieee802154_keys:'"00112233445566778899aabbccddeeff","1","Thread hash"'
"pinfo->dst" is documented as being either "pinfo->net_dst" (or if that is missing, "pinfo->dl_dst"). This works well for IP ("net_dst") over Ethernet ("dl_dst") where the lower layer address (Ethernet address) can be different when IP packets are routed over different links.
Is this different for 6LoWPAN over IEEE 802.11.5? Are 6LoWPAN packets always bound to the same 802.15.4 address?
With this proposed change, higher-level protocols that expect "src" to be the network address might break.
The problem here is that the 802.15.4 source and destination are being overwritten with the mesh header source and destination, which are not the same when multiple hops are needed.
Ah, that was some crucial information that I missed. In that case, shouldn't the mesh src/dst addresses be ignored? Then:- the 802.15.4 src/dst addresses are the link layer addresses- the 6LoWPAN src/dst addresses are the network addressesSearch for "hf_6lowpan_source", there are two places where this field is added. Wouldn't this be a more appropriate "network address"? (And if this is missing, perhaps then it could fallback to the mesh address.)
Some guidance from https://tools.ietf.org/html/rfc4944#page-12> The recipient of link fragments SHALL use (1) the sender's 802.15.4 > source address (or the Originator Address if a Mesh Addressing field > is present), (2) the destination's 802.15.4 address (or the Final > Destination address if a Mesh Addressing field is present), (3) > datagram_size, and (4) datagram_tag to identify all the link > fragments that belong to a given datagram.
That guidance is perfect for the *recipient* of the fragments, the problem comes for the analyzer of the fragments when multiple hops exist. In that case the 802.15.4 src/dst addresses should be taken into account as well, in my opinion.
Probably this issue hasn't arisen before because most implementations do cache the fragments until the datagram has fully arrived before forwarding them to the next hop. But there is nothing wrong in forwarding fragments as they arrive, and currently the dissector gets confused with the forwarded fragments seen in between the original fragments.
The only problem I see when matching the 802.15.4 src/dst addresses is the case when fragments from the same datagram take different routes, which is a rare situation but I guess it could happen.In that case I think fragments could be assembled by the dissector ONLY when the following parameters match:- Mesh source address.- Mesh destination address.- Datagram size.- Datagram tag.- Link destination address.That would solve the current issue.
The datagram tag is already used as ID to group fragments for reassembly, see "fragment_add_check" in packet-6lowpan.c. The datagram size should be the same for a given tag (unless it is reused), so it might not be more useful than the datagram tag.
Using mesh originator/destination addresses (when available) seems like a good idea. Whether to use it in addition or to replace the 802.15.4 addresses remains an open question (which you can probably answer better than I do).
What I am not sure about, though, is why changing pinfo->dst/src would help fixing your original issue. It is not used in the reassembly API (epan/reassembly.c), so somehow it is indirectly having some influence (perhaps through a "conversation" in the IP dissector?).
(In reply to Peter Wu from comment #12) > The datagram tag is already used as ID to group fragments for reassembly, > see "fragment_add_check" in packet-6lowpan.c. The datagram size should be > the same for a given tag (unless it is reused), so it might not be more > useful than the datagram tag. > > Using mesh originator/destination addresses (when available) seems like a > good idea. Whether to use it in addition or to replace the 802.15.4 > addresses remains an open question (which you can probably answer better > than I do). > > What I am not sure about, though, is why changing pinfo->dst/src would help > fixing your original issue. It is not used in the reassembly API > (epan/reassembly.c), so somehow it is indirectly having some influence > (perhaps through a "conversation" in the IP dissector?). Well, maybe my proposed patch is not valid since it might affect other non-Thread protocols. What I wanted to point out in my previous comment is the fact that the 6LoWPAN dissector is not taking forwarding into account. My proposal to solve the wrong reassemblies consists of taking into account the 802.15.4 destination address before assuming several fragments with matching datagram tag and mesh addresses belong to the same 1-hop datagram.Maybe a new variable should be added instead of overwriting pinfo->dst, but I guess I'll leave the coding for someone who is more familiar with the project.
This problem is also present when capturing from multiple interfaces on an Ethernet bridge with TCP/IP packets. In that case, packets are wrongly identified as TCP Out-of-Order/Retransmission/Dup ACK/..., but data is reassembled correctly due to availability of a sequence number.
To fix reassembly here, I guess it could incorporate the Mesh Destination address in the 32-bit reassembly ID (e.g. "(mesh_dest_id << 16) | datagram_tag"). Could that work?
(In reply to Peter Wu from comment #14)
> To fix reassembly here, I guess it could incorporate the Mesh Destination
> address in the 32-bit reassembly ID (e.g. "(mesh_dest_id << 16) |
> datagram_tag"). Could that work?
Too bad, in this case the 6LoWPAN addresses are the same (not surprising since these are just being forwarded)... Unconditionally using the link layer address instead might work though.
As far as I can see, there is no 'incorrect' re-assembly happening here: in frame 102, the reassembled packet consists of 2 fragments. The fragments are in the right order and belong to the packet in the sense of matching datagram tag, etc. The addresses are also correct fd00:db8::ff:fe00:401 -> fd00:db8::ff:fe00:0. As has been noted, as an external observer in contrast to the recipient, it is hard to define 'correct' re-assembly, especially in the multi-hop case.
I think taking the link-layer destination address into account would make the re-assembly less surprising and is a good idea, but I would not consider it 'more correct'. I think Peter's patch is a nice implementation.
Well, I can't agree that the re-assembly is not incorrect. Those 00:00:00:ff:fe:00:04:01 and 00:00:00:ff:fe:00:00:00 don't look like something very right to be shown as source and destination to me. Anyway, I agree that the Peter's approach is good.