Wireshark-dev: Re: [Wireshark-dev] Doku
From: Gerhard Gappmeier <gerhard.gappmeier@xxxxxxxxxxx>
Date: Thu, 13 Jul 2006 19:00:10 +0200
Hi Jaap and Ulf

I have added a new chapter about tcp_dissect_pdu
to WSDG_chapter_dissection.xml (revision 18722). 
Can you please review that and check it in.

regards,
Gerhard

On Wednesday 12 July 2006 14:44, Jaap Keuter wrote:
> Hi Gerhard,
>
> On Mon, 31 Jul 2006, Gerhard Gappmeier wrote:
> > Hi Jaap
> >
> > I'm not a wireshark expert yet, but I will try to add a basic chapter
> > that you can review before committing it to svn.
> > I will post a patch when I finished it.
>
> Cool, this is the stuff Open Source projects are made of.
>
[SNIP]
Index: WSDG_chapter_dissection.xml
===================================================================
--- WSDG_chapter_dissection.xml	(revision 18722)
+++ WSDG_chapter_dissection.xml	(working copy)
@@ -982,6 +982,86 @@
    The other variables are used for flagging up errors.
    </para>
 	</section>
+	<section id="TcpDissectPdus">
+		<title>How to reassemble split TCP Packets</title>
+		<para>	
+			A dissector gets a tvbuff_t pointer which holds the payload
+			of a TCP packet. This payload contains the header and data
+			of your application layer protocol.
+		</para>
+		<para>
+			When dissecting an application layer protocol you cannot assume
+			that each TCP packet contains exactly one application layer message.
+			One application layer message can be split into several TCP packets.
+		</para>
+		<para>
+			You also cannot assume the a TCP packet contains only one application layer message
+			and that the message header is at the start of your TCP payload.
+			More than one messages can be transmitted in one TCP packet,
+			so that a message can start at an abitrary position.
+			
+		</para>
+		<para>
+			This sounds complicated, but there is a simple solution.
+			<methodname>tcp_dissect_pdus()</methodname> does all this tcp packet reassembling for you.
+			This function is implemented in <filename>epan/dissectors/packet-tcp.h</filename>.
+		</para>
+		<example>
+			<title>Reassembling TCP fragments</title>
+			<programlisting>
+<![CDATA[
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gmodule.h>
+#include <epan/packet.h>
+#include <epan/emem.h>
+#include <epan/dissectors/packet-tcp.h>
+#include <epan/prefs.h>
+
+...
+
+#define FRAME_HEADER_LEN 8
+
+/* The main dissecting routine */
+static void dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+    tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
+                     get_foo_message_len, dissect_foo_message);
+}
+
+/* This method dissects fully reassembled messages */
+static void dissect_foo_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+    /* TODO: implement your dissecting code */
+}
+
+/* determine PDU length of protocol foo */
+static guint get_opcua_message_len(tvbuff_t *tvb, int offset)
+{
+    /* TODO: change this to your needs */
+    guint iLen = tvb_get_ntohl(tvb, offset+4); /* e.g. length is at offset 4 */
+}
+
+...
+]]>
+		 	</programlisting>
+		</example>
+		<para>
+			As you can see this is really simple. Just call <function>tcp_dissect_pdus()</function> in
+			your main dissection routine and move you message parsing code into another function.
+			This function gets called whenever a message has been reassembled.
+		</para>
+		<para>
+			The parameters <parameter>tvb</parameter>, <parameter>pinfo</parameter> and <parameter>tree</parameter> are just handed over
+			to <function>tcp_dissect_pdus()</function>.
+			The 4th parameter is a flag to indicate if the data should be reassebled or not. That's why we are using this function.
+			Parameter 5 indicates how much data has to be read at least to be able to determine the length of the foo message.
+			Parameter 6 is a function pointer to a method the returns this length.
+			Parameter 7 is a function pointer to your real message dissector.
+		</para>
+	</section>
   </section>
   <section id="ChDissectTap">
 	<title>How to tap protocols</title>