Wireshark-dev: Re: [Wireshark-dev] Malformed packet New dissector

From: "your highness" <zanash@xxxxxxxxx>
Date: Mon, 19 Feb 2007 16:05:06 +0100
On 2/19/07, your highness <zanash@xxxxxxxxx> wrote:
On 2/16/07, Guy Harris <guy@xxxxxxxxxxxx> wrote:
>
> On Feb 16, 2007, at 7:06 AM, your highness wrote:
>
> > Hi everyone,
> >
> > I managed to write a dissector for a new protocol (Condor) and it
> > works most of the time ; ) ... Thanks to Jaap Keuter and the README
> > files. I am starting a new thread for a new problem.
> >
> > The problem is that I get errors for packets that are spread over
> > multiple TCP packets.
> >
> > Condor runs on top of TCP. In the header of each condor packet the
> > length of the whole packet is given by a 3-octets field, thus as
> > suggested in the README.developer I used tcp_dissect_pdus() for
> > reassembling condor packets that span across more than one TCP
> > packets.
>
> It also handles multiple packets in *one* TCP segment.
>
> > The skeleton of my code that is relevant to this issue is as follows:
> >
> > static guint
> > get_condor_pdu_len(tvbuff_t *tvb, int offset)
> > {
> > // total packet length in 2nd, 3rd and 4th octets of a Condor packet
> > return tvb_get_ntoh24(tvb, offset+1);
> > }
>
> So it's a 3-octet field at an offset of 1 octet into the packet, so
> you have to have at least 4 bytes of the packet in order to get the
> length field?
>
> If so, then:
>
> > static void
> > dissect_condor_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree
> > *tree)
> > {
> > tcp_dissect_pdus(tvb, pinfo, tree, condor_desegment, 3,
> > get_condor_pdu_len,
> >    dissect_condor_tcp_pdu);
> > }
>
> ...that should be
>
>         tcp_dissect_pdus(tvb, pinfo, tree, condor_desegment, 4,
> get_condor_pdu_len,
>            dissect_condor_tcp_pdu);
>
> as you need the first *4* bytes of the packet in order to get the
> packet length.

That is correct, the first 4 bytes are needed for the reason you
mentioned. I have modified this and it resolves the "Malformed packet"
error, but now it gives "TCP segment of a reassemebled PDU". Please
read further in this email for more details about this message.

>
> > I first got the error message [Packet size limited during capture]
> > when I sent a number of packets together (the length of the packets
> > together was more than 1024 bytes).
>
> "Packet size limited during capture" usually means that the capture
> was done with a "snapshot length" shorter than the maximum packet
> length.  tcpdump, by default, has a "snapshot length" of 68 or 96.
>
> However, there are some cases where that error is incorrectly given
> for malformed or un-reassembled packets.
>
> > But must be caused by the
> > segmentation by the Data Link Layer.
>
> Probably not.
>
> Most data link layers either don't do segmentation (e.g., Ethernet and
> PPP), or do the reassembly on the adapter or in the adapter driver, so
> that the host doesn't see the segments (802.11, ATM AAL5).
>
> Some Wireshark dissectors for data link layers that do fragmentation
> also support data link layer reassembly, for cases where the capture
> doesn't have reassembled packets (because, for example, the adapter
> was told not to do reassembly, or because the capture mechanism is
> supplied with raw packets rather than reassembled packets if the
> driver's doing reassembly); the 802.11 dissector can do that.  We
> don't have that for ATM.
>
> However, data link layers also have a maximum packet size that they'll
> *accept* from a higher layer - they might internally fragment, at the
> data link layer, packets at or below that maximum packet size, or they
> might not (Ethernet, for example, doesn't).  This means that if a
> higher-layer protocol needs to send a packet larger than that,
> segmentation needs to be done at *that* layer.
>
> That segmentation isn't done by the data link layer, even though it's
> caused by a limitation of the data link layer.  It might be done at
> the network layer (IP or CLNP fragmentation, for example), or it might
> be done at the transport layer (TCP breaking the data stream into TCP
> segments, COTP breaking a COTP PDU into segments).
>
> If, for example, you send a 16K Condor packet, that won't fit into
> most link-layer packets.  The segmentation for that is done at the TCP
> layer, *not* by the data link layer.
>
> > Using tcp_dissect_pdus() solved
> > this problem. I don't understand how this happens because I supposed
> > that when a protocol runs on top of TCP, the tcp dissector itself
> > would take care of reassembly of the Data Link Layer packets. Is my
> > reasoning correct?
>
> No.
>
> When a protocol runs on top of TCP, the TCP implementation on the
> machine receiving packets will not reassemble all the data for a
> packet for that protocol and only hand a reassembled packet to the
> implementation of that higher-level protocol.  That's because TCP has
> no idea when a packet for that protocol starts or ends; the service
> TCP provides to protocols running on top of it is a stream of bytes,
> with *NO* packet boundaries.
>
> That's why Condor - and many other protocols running on top of TCP -
> need to put a length at the beginning of their packets.  That way, the
> implementation of that protocol on the receiving side knows how big
> the packet is, and keeps reading from TCP until it has all the bytes
> of that packet.
>
> The TCP dissector in Wireshark has the same problem, so it has to be
> told by the dissector for the protocol how big the packet is.  That
> can be done by hand, but tcp_dissect_pdus() can do it for you in many
> cases.
>
>
> > So the problem that I get now appears when I send more than 8192 bytes
> > (8K). In that case some Condor packets will span accross different TCP
> > packets, right?
>
> If you're running atop Ethernet, the number is more like 1460 bytes,
> assuming IPv4 with no options and TCP with no options (1514 bytes of
> Ethernet header plus data = 14 bytes of header + 1500 bytes of data;
> 1500 bytes of IPv4 header with no options + data = 20 bytes of IPv4
> header with no options plus 1480 bytes of data; 1480 bytes of TCP
> header with no options + data = 20 bytes of TCP header with no options
> plus 1460 bytes of data).

Right. My assumption was thus wrong and I was interpreting things
wrong. I am running atop Ethernet and it seems that the maximum on my
network is 1024 bytes of TCP data under the mentioned assumptions,
except that 12 bytes of TCP options are used.

>
> Unless you're dealing with a link layer that handles packets with 8232
> bytes of data (8192 bytes of TCP payload + 20 bytes of TCP header + 20
> bytes of IP header; that 8232 does *NOT* count the link-layer header,
> so it's 8232 + link-layer header size), or whatever the appropriate
> value would be for IPv6 (or with IP or TCP options), you're going to
> see segmentation before you get to 8192-byte packets.

What I still don't understand is that I get problems *only* if I send
more than 8192 bytes. So when I send 195 packets of 42 bytes (a total
of 8190 bytes) dissection is ok and I see 8 TCP packets:
 - Each of the TCP packets 1 through 7 contain 1024 bytes of Condor
packets, which is 24 whole packets +  parts of 1 or 2 segmented
packets
 - The last TCP packet contains 1022 bytes of Condor packets

But when I add one packet, so I send 196 packets (total of 8232 bytes)
things go wrong. As I mentioned above, after changing the 5th
parameter of tcp_dissect_pdus() from 3 to 4 I now get "TCP segment of
a reassemebled PDU" for the 9th TCP packet and the last Condor packet
is not dissected.

>
> > Only condor packets in the first TCP packet are
> > recognized as valid. The other ones are tagged "Malfored packet".
> >
> > I am using netcat to send files that contain Condor packets for my
> > tests. Attached is a captured file that contains condor packets of 42
> > bytes. The first packet that is tagged Malformed has 2 bytes in the
> > first TCP packets (0x20 and 0x00) and 40 bytes in the second TCP
> > packet.

I forgot to mention that the files are not sent over the network; I
send and receive the file on the same machine using the loop back
interface. I had to disable the checksum validation of TCP as proposed
in section "Viewing traffic" of the FAQ, because of "TCP checksum
offloading".

I am going to test whether using the same interface of a machine for
sending and receiving has any effect on this issue.

And it *has*! Sending the same file of more than 8192 bytes with
netcat from one machine to the one where wireshark runs results in
correct dissection.

Any explanation for the following?
- why things might go wrong when more than 8192 bytes are sent
- why only when the receiver and the sender use the same machine (the
same interface)


>
> I'll take a look at that later.
> _______________________________________________
> Wireshark-dev mailing list
> Wireshark-dev@xxxxxxxxxxxxx
> http://www.wireshark.org/mailman/listinfo/wireshark-dev
>