The main goal of this tutorial is to briefly explain the process of dissector creation for Wireshark (from version 1.12.5).

Introduction

Dissectors are meant to analyze some part of a packet’s data. We can also say, a protocol dissector for Wireshark is what translates the bytes of a network packet into a human readable form. These dissectors can either be written in C or in the Lua scripting language. Each dissector decodes its part of the protocol, and then hands off decoding to subsequent dissectors for an encapsulated protocol. Every dissection starts with the “Frame Dissector” which dissects the packet details of the capture file itself (e.g. time stamps). From there it passes the data on to the lower-level data dissector, e.g. the Ethernet dissector for the Ethernet header. The payload is then passed on to the next dissector (e.g. IP) and so on. At each stage, details of the packet will be decoded and displayed. Dissection can be implemented in two possible ways. One is to have a dissector module compiled into the main program, which means it’s always available. Another way is to make a plugin (a shared library or DLL) that registers itself to handle dissection. There is little difference at run-time in having your dissector as either a plugin or built-in. On the Windows platform you have limited function access through the exposed ABI in libwireshark.def, but that is mostly enough. The big plus is that your rebuild cycle for a plugin is much shorter than for a built-in one. So starting with a plugin makes initial development simpler, while the finished code may make more sense as a built-in dissector.

Prerequisites

  • Install the following packages:

Adding a Basic Dissector

Let’s step through adding a basic dissector. I will start with the made up “myproto” message. It consists of the following basic items.

myproto message
Field Type Description
PDU TYPE uint8_t Represents PDU type. 1 – PDU TYPE 1 2 – PDU TYPE 2
Padding uint8_t One byte padding
Length uint16_t Represents length of the PDU
Sequence Number uint16_t Represents PDU Sequence Number

 

PDU Type 1 message
Field Type Description
Length uint16_t Represents length of the PDU 1
Value uint16_t Represents PDU 1 Value

Download and Modify Template

It is easy to create something if we have a template. So follow the wireshark dissector template that can be found here. Download this template directory myproto and place it in plugins directory of wireshark source code. There are several steps that need to be completed in order to integrate a new dissector into Wireshark. The first step is to add your modification comments. Remember that Wireshark is open-source code, so the main comments identifies not only what you have created, but also includes information about the original contributor of Wireshark. When working with the template, you need to replace certain text with your information. For example in packet-myproto.c, for line 1, you would replace myproto with your protocol/message name. Change line 2 (packet-myproto.c) with packet-yourprotocolname.c. Line 3 should be modified with the copyright date, your name, and your e-mail address. The rest of the comments should remain intact to reflect the original author (Gerald Combs) and the GPL information.

Add Your Includes

The next portion of the template defines includes for the dissector. Those includes are needed for global functions called from this dissector. Wireshark defines a number of global functions that can be used within your protocol dissector. Of course, you may need to add some standard header files from your compiler or standard library.

The following list displays some of the most common includes that define the global functions that might be needed by your dissector:

  • prefs.h – Structure and functions for manipulating system preferences.
  • tap.h – Functions for utilizing the built-in TAP interface.
  • expert.h – Structure and functions to call the expert TAP.
  • epan/column-info.h – Structure of Summary window column data.
  • epan/framedata.h – Structure of frame data.
  • epan/packet-info.h – Structure of packet information.
  • epan/value_string.h – Functions to locate strings based on numeric values.

Add Protocol PORT

Choose a unique port number for your protocol and define it to the macro. Add necessary function declarations followed by port number

Register the protocol with Wireshark

This step describes the function which register the protocol dissector with Wireshark.

The first part of the proto_register_myproto function sets up the hf array fields of the dissection. Although, these are not required for packet dissection, they are recommended to take advantage of the full-featured display filter capabilities of the Wireshark software. Each item that is defined within the hf array will be an individual item that can be filtered within Wireshark. The next part of the registration process is to define the array for the subtree called ett.The ett variables keep track of state of the tree branch in the GUI protocol tree (e.g., whether the tree branch is open [expanded] or closed). The protocol is registered with both short and long naming conventions within Wireshark by calling the proto_register_protocol function (this causes the protocol to be displayed in the Wireshark’s Enabled Protocols window). The final step is to register the hf and ett arrays with the proto_register_field_array and the proto_register_subtree_array.

  • PROTONAME: The name of the protocol; this is displayed in the top-level protocol tree item for that protocol.
  • PROTOSHORTNAME: An abbreviated name for the protocol; this is displayed in the “Preferences” dialog box if your dissector has any preferences, in the dialog box of enabled protocols, and in the dialog box for filter fields when constructing a filter expression.
  • PROTOABBREV: A name for the protocol for use in filter expressions; it shall contain only lower-case letters, digits, and hyphens.
  • FIELDNAME: The displayed name for the header field.
  • FIELDABBREV: The abbreviated name for the header field. (NO SPACES)
  • FIELDTYPE: FT_NONE, FT_BOOLEAN, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_UINT64, FT_INT8, FT_INT16, FT_INT24, FT_INT32, FT_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_EUI64, FT_UINT_STRING, FT_ETHER, FT_BYTES, FT_UINT_BYTES, FT_IPv4, FT_IPv6, FT_IPXNET, FT_FRAMENUM, FT_PROTOCOL, FT_GUID, FT_OID
  • FIELDDISPLAY: For FT_UINT{8,16,24,32,64} and FT_INT{8,16,24,32,64): BASE_DEC, BASE_HEX, BASE_OCT, BASE_DEC_HEX, BASE_HEX_DEC, or BASE_CUSTOM, possibly ORed with BASE_RANGE_STRING or BASE_EXT_STRING
  • FIELDCONVERT: VALS(x), RVALS(x), TFS(x), NULL
  • BITMASK: Used to mask a field not 8-bit aligned or with a size other than a multiple of 8 bits
  • FIELDDESCR: A brief description of the field, or NULL. [Please do not use “”].

Link Dissector to Wireshark

How could the Wireshark know when to pass the data stream from a specific type of packet to our new dissector? Wireshark requires from each dissector when it should be called. For example, suppose you have a dissector which decode packets that are transported on the top of TCP on port 250. So how to instruct Wireshark to pass all packets that meet this criteria to your new dissector?

The proto_reg_handoff_xxx function is the answer. The create_dissector_handle function passes the function that Wireshark will call to dissect the packets and the proto_xxx value that was registered as the protocol in the proto_register_protocol function.The dissector_add function allows you to specify the criteria when the data are forwarded to your dissector.

Packet Dissection

This function is called to dissect the packets presented to it. The packet data is held in a special buffer referenced here as tvb. We shall become fairly familiar with this as we get deeper into the details of the protocol. The packet info structure contains general data about the protocol, and we can update information here. The tree parameter is where the detail dissection takes place. For the data display function proto_tree_add_xxx is used. There are several functions available for programmer which can display either protocol or field label:

  • tree: where the item is to be added.
  • id: is the hf_PROTOABBREV_FIELDABBREV field which is registered in register_info.
  • tvb: The tvbuff to mark as the source code data.
  • offset: The offset in the tvb where the data is located.
  • length: the length of the value (in bytes) in the tvb.
  • encoding: the data value displayed via the printf format.

  • proto_tree_add_item is used when you do not need some special formatting. The item is added to the GUI tree with its name and value.
  • proto_tree_add_uint function can be used to display the data already stored in the request_reply variable. If the value had not already been stored in a variable, the proto_tree_add_item function would be the most efficient to use.
  • proto_tree_add_text is used to display text
  • proto_tree_add_boolean is used to display bitfields

In packet-myproto.c packet dissection is done with respect to the myproto structures. So here you need to change as per your protocol structure members.

Improving the dissection information

We can certainly improve the display of the protocol with a bit of extra data. The first step is to add some text labels. Let’s start by labeling the packet types. There is some useful support for this sort of thing by adding a couple of extra things. First we add a simple table of type to name.

This is a handy data structure that can be used to look up a name for a value. There are routines to directly access this lookup table, but we don’t need to do that, as the support code already has that added in. We just have to give these details to the appropriate part of the data, using the VALS macro.

Compiling newly added Dissector

Modify Plugin Makefile

To compile the new added plugin you need to modify some of the files with respect to auto make. In the myproto template plugin directory you will find the following list of files:

In these files find all occurrences of “myproto” and replace with your protocol/dissector name. For example in moduleinfo.h:

Add to Main Makefile

In the previous section we modified files with respect to plugin. Now we need to add this new plugin to wireshark main Makefile. To do that first locate the following files in wireshark source code from top level directory.

Inside plugins Directory

  • plugins/Makefile.am: Open this file and search for SUBDIRS and add your new plugin directory as follows:

  • plugins/Makefile.in: Open this file and search for SUBDIRS and add your new plugin directory as follows:

  • plugins/Makefile.nmake: Open this file and search for PLUGIN_LIST and add your new plugin directory as follows:

Inside epan Directory

  • epan/Makefile.am: Open this file and search for plugin_src and add your new dissector plugin source file as follows:

  • epan/Makefile.in: Open this file and search for plugin_src and add your new dissector plugin source file as follows:

Inside wireshark Directory

  • ./configure: Open this file and search for ac_config_files and add your new dissector plugin makefile near plugins as follows:

  • ./configure: Open this file and search for ac_config_target add your new dissector plugin make file near plugins as follows:

  • ./configure.ac: Open this file and search for AC_OUTPUT and add your new dissector plugin makefile near plugins as follows:

  • ./Makefile.in: Open this file and search for dftest_OBJECTS and add your new dissector plugin as follows:

  • ./Makefile.in: Open this file and search for CUSTOM_plugin_ldadd and add your new dissector plugin as follows:

  • ./Makefile.am: Open this file and search for plugin_ldadd and add your new dissector plugin as follows:

Compile and Install Wireshark

To compile and install wireshark just run the following commands in root mode inside wireshark directory:

Capture and Filter packets with new Dissector

Packet Filter

Run wireshark and start capturing the packets on the interface which you want to capture. And just type your newly added plugin name in the filter as follows:

Dissection Information

To see the dissect information of the packet, just click on the MYPROTO packet and expand the tree as follows:

References

Thanks for reading and spending a good time with me to learn something new. For more updates subscribe here. Your comments and feedback are always welcome.