A dissector showing the protocol fields and interpretation of their values is very informative. It can be even more helpful if the dissector can draw your attention to fields where something noteworthy can be seen. This can be something as simple as the start flag of a session, or something more severe as an invalid value.
Here we take our dissector for FOO
and add an expert item for the sequence
number being zero (assuming that’s a noteworthy thing for this protocol).
Expert item setup.
#include <epan/expert.h> static expert_field ei_foo_seqn_zero = EI_INIT; /* ... */ void proto_register_foo(void) { /* ... */ expert_module_t* expert_foo; /* ... */ static ei_register_info ei[] = { { &ei_foo_seqn_zero, { "foo.seqn_zero", PI_SEQUENCE, PI_CHAT, "Sequence number is zero", EXPFILL } } }; /* ... */ expert_foo = expert_register_protocol(proto_foo); expert_register_field_array(expert_foo, ei, array_length(ei)); }
Let’s go through this step by step. The data structures and functions needed for expert items are found in epan/expert.h, so we have to include that file.
Next we have to allocate an expert_field
structure for every type of expert item
we would like to add to the dissection. This structure is initialised with EI_INIT
.
Now we have to register with the protocol we are providing expert info for. Since
we already have a function to register our protocol, we add the expert info
registration there too. This is done by calling expert_register_protocol()
with
the handle for the protocol we received earlier in this function.
Next we need to register an array of definitions of expert items that we would like to add to the dissection. This array, not unlike the array of header fields before, contains all the data the dissection engine needs to create and handle the expert items.
The expert item definition consists of a pointer to the expert_field
structure
we defined before and a structure with data elements of the expert item itself.
We’ll ignore the rest of the structure for now.
To keep an overview of lots of expert items it helps to categorize them into groups.
Currently there are several types of groups defined, e.g. checksum
, sequence
,
protocol
, etc. All these are defined in the epan/proto.h header file.
Not every noteworthy field value is of equal severity. The start of a session
is nice to know, while an invalid value may be significant error in the protocol.
To differentiate between these severties the expert item is assigned one of them:
comment
, chat
, note
, warn
or error
. Try to choose the lowest one which
is suitable. The topic you’re currently working on seems probably more important
than it will look like in a few weeks.
With the expert item array setup, we add this to the dissection engine with a
call to expert_register_field_array()
.
Now that all information of the expert item is defined and registered it’s time to actually add the expert item to the dissection.
Expert item use.
static int dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { guint32 sequenceno = 0xFFFF; /* ... */ ti = proto_tree_add_item_ret_uint(foo_tree, hf_foo_sequenceno, tvb, offset, 2, ENC_BIG_ENDIAN, &sequenceno); if (sequenceno == 0) { expert_add_info(pinfo, ti, &ei_foo_seqn_zero); } /* ... */ }
There’s been a slight alteration to the function used to add the sequence number
dissection. First the proto_item created by the function is saved in previously
defined variable ti
, and the actual value of the field is stored in the variable
sequenceno
. We can now use the value of this field to determine wether to add
the expert item.
Adding the expert item is simply done by calling expert_add_info()
with reference
to the packet_info
structure, the proto item ti
to add the expert item to and
the previously defined and registered expert item information.