As one of the world’s best network packet capture tools, Wireshark allows you to attain specific data packets so you can analyze them both offline and in real time. Think of the app as a way to closely examine the data flowing through your network, allowing you to catch issues and irregularities.

You can use dissectors if you want to analyze a specific part of a packet’s data. As the name implies, this process “dissects” the code, allowing you to cut out certain aspects that need your attention. This tutorial explains how to create and use dissectors in Wireshark using the Lua scripting language.
Before You Start – What You Need to Know About Dissectors
Though dissectors offer a quick way to analyze portions of a data packet in Wireshark, they have to follow some protocols to work effectively. These protocols include the following:
- Every dissector you create has to be registered to handle a set type of payload from a different protocol. To complete this registration, you must assign a “Proto” object to your dissector, which you’ll see below.
- When you call a dissector via Wireshark, it receives three things from the app:
- TVB Object – A TVB buffer from the data packet.
- TreeItem Object – A tree root that represents a single node in a data tree.
- Pinfo Object – A packet information record.
- You can only call a dissector if your data packet matches the DissectorTable that you set to your “Proto” object.
- You can work around this requirement by forcing the use of a dissector via the “Decode As” function. But even then, you can only force the dissector if the DissectorTable you set to your “Proto” object is of the correct type.
Setting Up Your Dissector Using LUA
As Wireshark is both written in and uses the C programming language, most dissectors are similarly written in C. However, you may wish to use Lua. This scripting language is simpler than C and thus more accessible to coding newcomers or those who simply want to create a dissector using a more lightweight language.
Though your code will be simpler, the dissector you get when using Lua is usually slower than the one you’d create using C. Nevertheless, these are the steps to follow if you want to create a Wireshark dissector using Lua.
Step 1 – Set Up Lua in Wireshark
You’ll need to set up Lua if you haven’t used it in Wireshark before:
- Click “Help,” followed by “About Wireshark.”
- Click “Folders.”
- Choose one of the following to create an active Lua script:
- Global Lua Plugins
- Personal Lua Plugins
- Personal
Once activated, your script will be ready whenever you start Wireshark. Every time you make a change to that script, you either need to restart Wireshark to register the change or press “Ctrl + Shift + L” to reload all of your Lua scripts to make your changes active.
Step 2 – The Basic Steps for Creating Your Dissector
If you’re already familiar with Lua, you can use the following steps to create your own dissector script that will work in Wireshark:
- Declare the protocol for your dissector, which requires you to set both a long name for use in the protocol tree and a short name that serves as the dissector’s display filter name.
- Create the following three fields, with their appropriate types:
- Question – Shows the question type.
- Answer – Shows the answer type.
- MessageType – Demonstrates if your packet requests a question or an answer.
- Register your fields so that Wireshark knows how to display them. Without registered fields, you’ll receive a “Lua Error” message, usually telling you that your Tree Item ProtoField is invalid.
- Create a dissection function that includes the previously mentioned Pinfo (containing data about your packet) and Tree Item (creating the tree you’ll append to a subtree). You must also create a “buffer,” which sits on top of your TCP.
- Specify both the protocol and port for which Wireshark must use the dissector. For example, you can set the protocol to “TCP” and the port number to whichever you want to use.
Step 3 – Add Your Dissector to Wireshark
Right now, your dissector is like a light bulb without electricity. It exists, but it’s of no use to you until you can run some power through it. In other words, your dissector isn’t added to Wireshark yet, so you have to add it manually to get it running by using these steps:
- Click on “Help” and head to the “About Wireshark” menu.
- Select the “Folder” tab to find a list of paths for your Lua file.
- Choose “Personal Lua Plugins.” Create a directory if necessary.
- Copy and paste the Lua file you created into the “Personal Lua Plugins” directory. Reload Wireshark to turn on the dissector.
It’s a good idea to run a test on your new dissector by opening some of the packets you’ve captured. Wireshark should deliver a message that shows the long name you chose for your dissector, along with information about the message type (question or answer) and the result of your check.
Some Sample Code
If you haven’t created a dissector before (or you’re new to Lua), Wireshark offers a handy example dissector for you to try out:
local p_multi = Proto("multi", "MultiProto");
local vs_protos = {
[2] = "mtp2",
[3] = "mtp3",
[4] = "alcap",
[5] = "h248",
[6] = "ranap",
[7] = "rnsap",
[8] = "nbap"
}
local f_proto = ProtoField.uint8("multi.protocol", "Protocol", base.DEC, vs_protos)
local f_dir = ProtoField.uint8("multi.direction", "Direction", base.DEC, { [1] = "incoming", [0] = "outgoing"})
local f_text = ProtoField.string("multi.text", "Text")
p_multi.fields = { f_proto, f_dir, f_text }
local data_dis = Dissector.get("data")
local protos = {
[2] = Dissector.get("mtp2"),
[3] = Dissector.get("mtp3"),
[4] = Dissector.get("alcap"),
[5] = Dissector.get("h248"),
[6] = Dissector.get("ranap"),
[7] = Dissector.get("rnsap"),
[8] = Dissector.get("nbap"),
[9] = Dissector.get("rrc"),
[10] = DissectorTable.get("sctp.ppi"):get_dissector(3), -- m3ua
[11] = DissectorTable.get("ip.proto"):get_dissector(132), -- sctp
}
function p_multi.dissector(buf, pkt, tree)
local subtree = tree:add(p_multi, buf(0,2))
subtree:add(f_proto, buf(0,1))
subtree:add(f_dir, buf(1,1))
local proto_id = buf(0,1):uint()
local dissector = protos[proto_id]
if dissector ~= nil then
-- Dissector was found, invoke subdissector with a new Tvb,
-- created from the current buffer (skipping first two bytes).
dissector:call(buf(2):tvb(), pkt, tree)
elseif proto_id < 2 then
subtree:add(f_text, buf(2))
-- pkt.cols.info:set(buf(2, buf:len() - 3):string())
else
-- fallback dissector that just shows the raw data.
data_dis:call(buf(2):tvb(), pkt, tree)
end
end
local wtap_encap_table = DissectorTable.get("wtap_encap")
local udp_encap_table = DissectorTable.get("udp.port")
wtap_encap_table:add(wtap.USER15, p_multi)
wtap_encap_table:add(wtap.USER12, p_multi)
udp_encap_table:add(7555, p_multi)
Postdissectors and Chained Dissectors
You may want to go a little more in-depth with your dissector usage once you’ve mastered creating them in Lua. Wireshark offers two additional types of dissectors – postdissectors and chained dissectors – that offer more functionality.
A postdissector is a lot like a final check of all dissectors that you’ve run for a packet. You register it to get notified once Wireshark has called every other dissector you want it to use, and you can use it to filter the “Protocol” and “Info” columns. This feature is especially useful if you want to filter out multiple packets in a session where you’ve had a long gap between data sets and can’t recall each one individually.
Chaining dissectors serves a similar function (at least in terms of filtering through previously-used dissectors) by giving you access to a single dissector’s data. The key advantage here is that the chained dissector doesn’t have to run through every packet again, giving you a result without forcing you to wait for the original dissector to run again.
Dissect in Lua
Given that Wireshark already offers the ability to create dissectors in C (its natural language), you may not see the need to create them in Lua as well. Still, those who aren’t comfortable with C, as well as those who’ve already mastered Lua, may find that the lightweight scripting of Lua makes it easier to create their dissectors. Granted, you have to trade off a longer loading time when you run the process compared to C-based dissectors, but it’s helpful to have the option regardless.
With that said, we want to hear from you. How often do you use dissectors in Wireshark? Have you tried creating them in C before, and what benefits do you think making dissectors in Lua delivers? Let us know in the comments section below.
Disclaimer: Some pages on this site may include an affiliate link. This does not effect our editorial in any way.