mfontanini / libtins

High-level, multiplatform C++ network packet sniffing and crafting library.
http://libtins.github.io/
BSD 2-Clause "Simplified" License
1.91k stars 377 forks source link

Fix TCP option size calculation for options with empty payload #404

Open fxkr opened 4 years ago

fxkr commented 4 years ago

From https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml :

> Options 0 and 1 are exactly one octet which is their kind field.  All
> other options have their one octet kind field, followed by a one octet
> length field, followed by length-2 octets of option data.

Options affected by the libtins bug are those where length is listed as:

Without this fix, any affected packet can still be parsed, but trying to serialize the resulting PDU object again will fail in Tins::PDU::serialize -> Tins::TCP::write_serialization -> Tins::Memory::OutputMemoryStream::fill.

I'm attaching a PCAP with an affected packet. This packet is from a real world product. I mention this because Wireshark says "Illegal SCPS Extended Capabilities (2 bytes)". Wireshark still gets the length right, and what's "wrong" (but real) about the packet isn't relevant here (for the curious... SCPS extended capability opts (extended means length!=4) "must" be preceded by a normal SCPS capability opt (normal means length==4). CCSDS 714.0-B-2 section 3.2.5.2.1, available on the Internet Archive. Disclaimer: I'm not a SCPS expert.). But none of that weirdness is related to this libtins bug, and anyway the libtins bug is not specific to SCPS.

tcp ack with scps option without data.zip

(Unrelated note: I'd rather not even deal with the TCP layer and decode the IP payload, whatever that may be, as RawPDU, both for performance as well as the guarantee that any TCP/UDP/... and above headers will come out of tins unmodified, but it seems there's no good way to make libtins do that.)