aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-10-09 21:18:41 +0000
committerGuy Harris <guy@alum.mit.edu>2003-10-09 21:18:41 +0000
commitdca567002efb225f415bc76d95ba4875a5770c77 (patch)
treea27758527e16bf5f2763303b6986ccce7ba520e3 /doc
parent33d2ce9a745bba94a4dc2d441ade54d490c2ca37 (diff)
From Lo�c Minier: information on how to do reassembly of PDUs atop TCP.
svn path=/trunk/; revision=8651
Diffstat (limited to 'doc')
-rw-r--r--doc/README.developer95
1 files changed, 92 insertions, 3 deletions
diff --git a/doc/README.developer b/doc/README.developer
index 9ff632c220..0d2582c993 100644
--- a/doc/README.developer
+++ b/doc/README.developer
@@ -1,4 +1,4 @@
-$Id: README.developer,v 1.80 2003/10/09 18:57:37 guy Exp $
+$Id: README.developer,v 1.81 2003/10/09 21:18:41 guy Exp $
This file is a HOWTO for Ethereal developers. It describes how to start coding
a Ethereal protocol dissector and the use some of the important functions and
@@ -231,7 +231,7 @@ code inside
is needed only if you are using the "snprintf()" function.
-The "$Id: README.developer,v 1.80 2003/10/09 18:57:37 guy Exp $"
+The "$Id: README.developer,v 1.81 2003/10/09 21:18:41 guy Exp $"
in the comment will be updated by CVS when the file is
checked in; it will allow the RCS "ident" command to report which
version of the file is currently checked out.
@@ -241,7 +241,7 @@ version of the file is currently checked out.
* Routines for PROTONAME dissection
* Copyright 2000, YOUR_NAME <YOUR_EMAIL_ADDRESS>
*
- * $Id: README.developer,v 1.80 2003/10/09 18:57:37 guy Exp $
+ * $Id: README.developer,v 1.81 2003/10/09 21:18:41 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -2152,6 +2152,95 @@ This will create preferences "beep.tcp.port" and
"beep.strict_header_terminator", the first of which is an unsigned
integer and the second of which is a Boolean.
+2.7 Reassembly/desegmentation for protocols running atop TCP
+
+There are two main ways of reassembling PDUs spanning across multiple
+TCP segmentss. The first one is simpler, but assumes you are running
+atop of TCP when this occurs (but your dissector might run atop of UDP,
+too, for example), and that your PDUs consist of a fixed amount of data
+that includes enough information to determine the PDU length, possibly
+followed by additional data. The second one is more generic but
+requires more code and is less efficient.
+
+For the first method, you register two different dissection methods, on
+for the TCP case, and one for the other cases. It is a good idea to
+have a dissect_PROTO_common function which will parse the generic
+content that you can find in all PDUs which is called from
+dissect_PROTO_tcp when the reassembly is complete and from
+dissect_PROTO_udp (or dissect_PROTO_other).
+
+To register the distinct dissector functions, consider the following
+example, stolen from packet-dns.c:
+
+ dissector_handle_t dns_udp_handle;
+ dissector_handle_t dns_tcp_handle;
+ dissector_handle_t mdns_udp_handle;
+
+ dns_udp_handle = create_dissector_handle(dissect_dns_udp,
+ proto_dns);
+ dns_tcp_handle = create_dissector_handle(dissect_dns_tcp,
+ proto_dns);
+ mdns_udp_handle = create_dissector_handle(dissect_mdns_udp,
+ proto_dns);
+
+ dissector_add("udp.port", UDP_PORT_DNS, dns_udp_handle);
+ dissector_add("tcp.port", TCP_PORT_DNS, dns_tcp_handle);
+ dissector_add("udp.port", UDP_PORT_MDNS, mdns_udp_handle);
+ dissector_add("tcp.port", TCP_PORT_MDNS, dns_tcp_handle);
+
+The dissect_dns_udp function does very little work and calls
+dissect_dns_common, while dissect_dns_tcp calls tcp_dissect_pdus with a
+reference to a callback which will be called with reassembled data:
+
+ static void
+ dissect_dns_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+ {
+ tcp_dissect_pdus(tvb, pinfo, tree, dns_desegment, 2,
+ get_dns_pdu_len, dissect_dns_tcp_pdu);
+ }
+
+(The dissect_dns_tcp_pdu function acts similarly to dissect_dns_udp.)
+The arguments to tcp_dissect_pdus are:
+
+ the tvbuff pointer, packet_info pointer, and proto_tree pointer
+ passed to the dissector;
+
+ a gboolean flag indicating whether desegmentation is enabled for
+ your protocol;
+
+ the number of bytes of PDU data required to determine the length
+ of the PDU;
+
+ a routine that takes as arguments a tvbuff pointer and an offset
+ value representing the offset into the tvbuff at which a PDU
+ begins and should return - *without* throwing an exception (it
+ is guaranteed that the number of bytes specified by the previous
+ argument to tcp_dissect_pdus is available, but more data might
+ not be available, so don't refer to any data past that) - the
+ total length of the PDU, in bytes;
+
+ a routine that's passed a tvbuff pointer, packet_info pointer,
+ and proto_tree pointer, with the tvbuff containing a
+ possibly-reassembled PDU, and that should dissect that PDU.
+
+The second method is to return a modified pinfo structure when
+dissect_PROTO is called. In this case, you have to check if you have
+collected enough bytes: if you have enough, you parse the PDU, and if
+don't have enough bytes, you return from the dissector supplying
+information to the caller on how many bytes you need to proceed. This
+is done by indicating the offset where you would like to start again and
+the number of bytes that you need in pinfo->desegment_*:
+
+ if (i_miss_five_bytes) {
+ pinfo->desegment_offset = offset;
+ pinfo->desegment_len = 5;
+ }
+
+You can repeat this procedure until you've got enough bytes; for
+example, you can request one byte more until you've got the byte you're
+searching for if the data to be dissected consists of a sequence of
+bytes ending with a particular byte value.
+
3. Plugins
See the README.plugins for more information on how to "pluginize"