From Mike Duigou:

A few doxygen updates and an improved section on 
writing dissectors that don't use tcp_dissect_pdus().

svn path=/trunk/; revision=14538
This commit is contained in:
Anders Broman 2005-06-03 06:36:07 +00:00
parent f01b2b6197
commit d656e253db
1 changed files with 92 additions and 20 deletions

View File

@ -310,10 +310,10 @@ be written portably without #ifdefs.
1.1.2 Robustness.
Ethereal is not guaranteed to read only network traces that contain
correctly-formed packets; in fact, one of the reasons why Ethereal is
used is to track down networking problems, and the problems might be due
to a buggy protocol implementation sending out bad packets.
Ethereal is not guaranteed to read only network traces that contain correctly-
formed packets. Ethereal is commonly used is to track down networking problems,
and the problems might be due to a buggy protocol implementation sending out
bad packets.
Therefore, protocol dissectors not only have to be able to handle
correctly-formed packets without, for example, crashing or looping
@ -457,7 +457,9 @@ the files in Ethereal tend to use 2-space or 4-space indentation. You are
encouraged to write a short comment on the indentation logic at the beginning
of this new file.
When editing an existing file, try following the existing indentation logic.
When editing an existing file, try following the existing indentation logic and
even if it very tempting, never ever use a restyler/reindenter utility on an
existing file.
1.2 Skeleton code.
@ -2737,6 +2739,8 @@ fixed amount of data that includes enough information to determine the PDU
length, possibly followed by additional data. The second method is more
generic but requires more code and is less efficient.
2.7.1 Using tcp_dissect_pdus()
For the first method, you register two different dissection methods, one
for the TCP case, and one for the other cases. It is a good idea to
also have a dissect_PROTO_common function which will parse the generic
@ -2798,23 +2802,91 @@ The arguments to tcp_dissect_pdus are:
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_*:
2.7.2 Modifying the pinfo struct
if (i_miss_five_bytes) {
pinfo->desegment_offset = offset;
pinfo->desegment_len = 5;
}
The second reassembly mode is prefered when the dissector cannot determine
how many bytes it will need to read in order to determine the size of a PDU.
For this mode it is reccommended that your dissector be the newer dissector
type which returns "int" rather than the older type which returned "void".
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.
This reassembly mode relies on Ethereal's mechanism for processing multiple PDUs
per frame. When a dissector processes a PDU from a tvbuff the PDU may not be
aligned to a frame of the underlying protocol. Ethereal allows dissectors to
process PDUs in an idempotent way--dissectors only need to consider one PDU at a
time. If your dissector discovers that it can not process a complete PDU from
the current tvbuff the dissector should halt processing and request additional
bytes from the lower level dissector.
Your dissect_PROTO will be called by the lower level dissector whenever
sufficient new bytes become available. Each time your dissector is called it is
provided a different tvbuff, though the tvbuffs may contain data that your
dissector declined to process during a previous call. When called a dissector
should examine the tvbuff provided and determine if an entire PDU is available.
If sufficient bytes are available the dissector processes the PDU and returns
the length of the PDU from your dissect_PROTO.
Completion of a PDU is signified by dissect_PROTO returning a positive value.
The value is the number of bytes which were processed from the tvbuff. If there
were insufficient bytes in the tvbuff to complete a PDU then the dissect_PROTO
returns a negative value requesting additional bytes. The negative return value
indicates how many additional bytes are required. Additionally dissect_PROTO
must update the pinfo structure to indicate that more bytes are required. The
desegment_offset field is the offset in the tvbuff at which the dissector will
continue processing when next called. The desegment_len field should contain the
estimated number of additional bytes required for completing the PDU. The
dissect_PROTO will not be called again until the specified number of bytes are
available. pinfo->desegment_len may be set to -1 if dissect_PROTO cannot
determine how many additional bytes are required. Dissectors should set the
desegment_len to a reasonable value when possible rather than always setting
-1 as it will generally be more efficient.
static hf_register_info hf[] = {
{&hf_cstring,
{"C String", "c.string", FT_STRING, BASE_NONE, NULL, 0x0,
"C String", HFILL}
}
};
/**
* Dissect a buffer containing a C string.
*
* @param tvb The buffer to dissect.
* @param pinfo Packet Info.
* @param tree The protocol tree.
* @return Number of bytes from the tvbuff_t which were processed or a negative
* value indicating more bytes are needed.
**/
static int dissect_cstr(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
guint offset = 0;
gint available = tvb_reported_length_remaining(tvb, offset);
gint len = tvb_strnlen( tvb, offset, available );
if( -1 == len ) {
/* No '\0' found, ask for another byte. */
pinfo->desegment_offset = offset;
pinfo->desegment_len = 1;
return -1;
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_str(pinfo->cinfo, COL_INFO, "C String");
}
len += 1; /* Add one for the '\0' */
if (tree) {
proto_tree_add_item(tree, hf_cstring, tvb, offset, len, FALSE);
}
return len;
}
This simple dissector will repeatedly return -1 requesting one more byte until
the tvbuff contains a complete C string. The C string will then be added to the
protocol tree. Unfortunately since there is no way to guess the size of C String
without seeing the entire string this dissector can never request more than one
additional byte.
3. Plugins