The Clever Use of Postdissectors to Analyze Layer 2 Protocols

Share This

In a recent blog about dissecting unusual protocols when troubleshooting OT security issues, we used the Cisco Nexus protocol as a use case to show how Wireshark plugins can help during the reverse engineering process.

In this post, we’re focusing on another interesting Layer 2 protocol related to a peculiar set of features that can be leveraged to instruct our tool to properly dissect the targeted communication scheme.

During our journey we had to analyze an unknown protocol used between Ruggedcom switches and their provisioning tools to ensure proper configuration. This protocol is known as RUGGEDCOM Discovery Protocol (RCDP).

Due to the popularity of such devices in the industrial sector, we decided to dive in and analyze the Layer 2 proprietary protocol used by the Ruggedcom ROS devices. In particular, we focused not on its inner structure (we don’t want to spoil the funny part, or do we?!) but on how we can instruct Wireshark to properly detect it and begin the dissection process.

Postdissectors can be used to start dissection after all the “normal” dissectors have done their jobs, and help us fully understand the protocol’s Data content.
Postdissectors can be used to start dissection after all the “normal” dissectors have done their jobs, and help us fully understand the protocol’s Data content.

Why Postpone the Dissection?

The setup we used for our analysis was:

  • Ruggedcom Switch RS910
  • RCDP discovery tool

Through the discovery tool we were able to trigger some key functionalities, and as a consequence, collect Pcaps for our deep dive analysis. This is what the protocol looked like over the wire:

As you can see, this time Wireshark doesn’t have complete knowledge of the communication taking place.

The last decoded frame shows the well-known LLC frame, normally seen as a link between the MAC (Layer 2) layer and the Network layer.

Our goal was to fully understand the Data content.

I won’t drill into the reverse engineering process we went through to fully dissect the RCDP protocol here. Instead, I’ll take you through how we analyzed the unknown protocol and gathered the indicators needed to develop the plugin.

By looking inside the LLC frame, we uncovered initial evidence that leads us to assume that the tool was not completely inaccurate on the dissection of this specific layer.

RCDP Protocol ID

The seems to be quite a reliable indicator for tagging the protocol. But one question remained: how we can access the Data field without overlapping with the current dissection?

The Use of Postdissectors

An interesting concept that can help us a lot is related to so-called postdissectors. We can leverage this type of plugin to start our dissection after all the “normal” dissectors have done their jobs. This allows us to append the results at the bottom of the dissection tree.

TIP: In case you find yourself stuck trying to understand some complex mechanisms, remember that Wireshark has its own version of the well-known stackoverflow, called: ask.wireshark. Here’s an example.

The easiest way to call a postdissector is to use the register_postdissector() function at the bottom of the script, rather than the standard Dissector.Table.get().

-- initialize protocol fields
rcdp_proto = Proto("RCDP", "Siemens RCDP")

local RCDP_PID = 0x01e6

-- main function
function rcdp_proto.dissector(buffer, pinfo, tree)

if length == 0 then return end


-- Register RCDP postdissector

Next, we need to instruct the current script to bind itself every time it spots the custom LLC Protocol ID (0x01e6). In order to do this, we have to initialize two variables that are going to reference the Protocol ID and Data section of the upper frame.

TIP: Wireshark’s filters are also quite useful in the context of your dissector!

With the reference we can easily add the condition needed to add tagging for the RCDP protocol.

At this stage we just have to register our buffer to the LLC Data section. We can then start to add our dissection as usual.

-- initialize protocol fields
rcdp_proto = Proto("RCDP", "Siemens RCDP")

local RCDP_PID = 0x01e6

-- reference LLC frame
local llc_pid ="")
local data_data ="")

-- main function
function rcdp_proto.dissector(buffer, pinfo, tree)

if length == 0 then return end

-- get current Protocol ID value and check if it's the RCDP one
local llc_pid_ex = llc_pid()

if llc_pid_ex == nil or llc_pid_ex.value ~= RCDP_PID
then return

pinfo.cols.protocol =
-- set buffer at the right location
local buf = data_data().range()
local buf_len = buf:len()
local subtree = tree:add(rcdp_proto, buf(0, buf:len()), "RCDP Protocol Data")

-- register RCDP postdissector

Instructing Wireshark to Dissect Our Protocol

Using this approach, we can properly instruct Wireshark to dissect our protocol right after the standard parsing that we saw previously. This is how a post-dissector works, and shows how we can apply its logic in a real use case, such as with the RCDP protocol.

At this point, we can start digging inside the inner protocol structure, while also playing with the Ruggedcom Explorer utility. As an example, let’s try to extract some key asset details.

To do this, we need to trigger the autodiscovery function within the diagnostic tool and start analyzing the traffic generated.

TIP: Tools’ UI can be a good friend when you need to deepen your understanding of an unknown protocol.

As soon as the tool is able to discover the switch set up in the Nozomi Networks Lab, it can also gather some interesting details about it.

After gaining some understanding of the retrieved communication, we can easily improve the dissector to allow us to extract the visualized product information in a structured way. The end result is a complete parsing of the entire communication.

Autodiscovery completed

Nozomi Networks Labs: Supporting the Global Research Community

In this second blog on protocol dissectors, we discussed how to leverage the concept of postdissector in plugins and instruct Wireshark to bind our dissection to the protocol used between Ruggedcom switches and its monitoring tool, known as RUGGEDCOM Discovery Protocol (RCDP).

We were able to use the custom Protocol ID exposed within the LLC frame, and start the dissection in the right offset location.

To reach our goal of fully understanding the Data content, we used some key functions for triggering the postdissector and calling upper-level frames, including:

  • register_postdissector(v1)
  • ExtractedField.value
  • ExtractedField.range()

We hope that the global security community can use our suggestions and techniques to further their own analysis and research projects. Stay tuned for our next Nozomi Networks Labs blog. In the meantime, check out our new OT/IoT Security Report July 2021, and the related on-demand webinar below, for insights on ransomware, ICS and IoT vulnerabilities and much more.


OT/IoT Security Report

What You Need to Know to Fight Ransomware and IoT Vulnerabilities – July 2021

  • Why ransomware is a formidable threat
  • Analysis of DarkSide, the malware that attacked Colonial Pipeline
  • Latest ICS and medical device vulnerability trends
  • Why P2P security camera architecture threatens confidentiality
  • How security cameras are vulnerable
  • Ten measures to take immediately to defend your systems

Investigating the Ransomware and IoT Vulnerabilities Landscape

Cybercrime continues to rise sharply as threat actors go after industrial targets that can be worth millions in ransomware payments.

Join us for a discussion on:

  • Ransomware
  • New research findings on ICS and medical device vulnerabilities
  • How security camera vulnerabilities threaten business confidentiality and open the door to malware

Let's get started

Discover how easy it is to anticipate, diagnose and respond to cyber threats by automating your IoT and OT asset discovery, inventory, and management.