9.3. How to add an expert item
Prev | Chapter 9. Packet Dissection | Next

## 9.3. How to add an expert item

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;

    /* ... */

    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. We typically declare these right after the `ett_…​` tree handle declarations.

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.

- "foo.seqn_zero" - The display filter for the expert item
- PI_SEQUENCE - The group to which the expert item belongs
- PI_CHAT - The severity of the expert item
- "Sequence number is zero" - The text string added to the dissection

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_)
    {
        uint32_t 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. Firstly, `proto_tree_add_item()` has changed to `proto_tree_add_item_ret_uint()` so we can store the actual value of the field in the variable `sequenceno`. We can now use the value of this field to determine whether to add the expert item.

Secondly, the `proto_item` returned by the function is saved in previously defined variable `ti`.

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.

Prev | Up | Next
9.2. Adding a basic dissector | Home | 9.4. How to handle transformed data