/!\ Examples in this page need to be updated to the current WSLUA API

dissectors

To be registered they have assigned to a Protocol.

-- trivial protocol example
-- declare our protocol
trivial_proto = Proto("trivial","Trivial Protocol")
-- create a function to dissect it
function trivial_proto.dissector(buffer,pinfo,tree)
    pinfo.cols.protocol = "TRIVIAL"
    local subtree = tree:add(trivial_proto,buffer(),"Trivial Protocol Data")
    subtree:add(buffer(0,2),"The first two bytes: " .. buffer(0,2):uint())
    subtree = subtree:add(buffer(2,2),"The next two bytes")
    subtree:add(buffer(2,1),"The 3rd byte: " .. buffer(2,1):uint())
    subtree:add(buffer(3,1),"The 4th byte: " .. buffer(3,1):uint())
end
-- load the udp.port table
udp_table = DissectorTable.get("udp.port")
-- register our protocol to handle udp port 7777
udp_table:add(7777,trivial_proto)

postdissectors

A postdissector is a dissector registered to be called after every other dissector has been called already. These are handy as all protocol fields are already there so they can be accessed and they can add items to the dissection tree.

-- trivial postdissector example
-- declare some Fields to be read
ip_src_f = Field.new("ip.src")
ip_dst_f = Field.new("ip.dst")
tcp_src_f = Field.new("tcp.srcport")
tcp_dst_f = Field.new("tcp.dstport")
-- declare our (pseudo) protocol
trivial_proto = Proto("trivial","Trivial Postdissector")
-- create the fields for our "protocol"
src_F = ProtoField.string("trivial.src","Source")
dst_F = ProtoField.string("trivial.dst","Destination")
conv_F = ProtoField.string("trivial.conv","Conversation","A Conversation")
-- add the field to the protocol
trivial_proto.fields = {src_F, dst_F, conv_F}
-- create a function to "postdissect" each frame
function trivial_proto.dissector(buffer,pinfo,tree)
    -- obtain the current values the protocol fields
    local tcp_src = tcp_src_f()
    local tcp_dst = tcp_dst_f()
    local ip_src = ip_src_f()
    local ip_dst = ip_dst_f()
    if tcp_src then
       local subtree = tree:add(trivial_proto,"Trivial Protocol Data")
       local src = tostring(ip_src) .. ":" tostring(tcp_src)
       local dst = tostring(ip_dst) .. ":" tostring(tcp_dst)
       local conv = src  .. "->" .. dst
       subtree:add(src_F,src)
       subtree:add(dst_F,dst)
       subtree:add(conv_F,conv)
    end
end
-- register our protocol as a postdissector
register_postdissector(trivial_proto)

chained dissectors

Chaining dissectors similarly allows you to have access to one dissector's data, but doesn't have to run against every packet.

-- works as of Wireshark v0.99.7
do
        local http_wrapper_proto = Proto("http_extra", "Extra analysis of the HTTP protocol");
        -- (to confirm this worked, check that this protocol appears at the bottom of the "Filter Expression" dialog)
        -- our new fields
        local F_newfield1 = ProtoField.uint16("http.newfield1", "Our new field, #1", base.DEC)
        local F_newfield2 = ProtoField.uint16("http.newfield2", "Our new field, #2", base.DEC)
        -- add the fields to the protocol
        -- (to confirm this worked, check that these fields appeared in the "Filter Expression" dialog)
        http_wrapper_proto.fields = {F_newfield1, F_newfield2}          -- NOT ProtoFieldArray, that stopped working a while ago
        -- declare the fields we need to read
        local f_set_cookie = Field.new("http.set_cookie")
        local f_referer    = Field.new("http.referer")
        local original_http_dissector
        function http_wrapper_proto.dissector(tvbuffer, pinfo, treeitem)
                -- we've replaced the original http dissector in the dissector table,
                -- but we still want the original to run, especially because we need to read its data
                original_http_dissector:call(tvbuffer, pinfo, treeitem)
                if f_set_cookie() then
                        -- this has two effects:
                        --      1. makes it so we can use "http_extra" as a display filter
                        --      2. displays a new header in the tree pane for our protocol
                        local subtreeitem = treeitem:add(http_wrapper_proto, tvbuffer)
                        field1_val = 42
                        subtreeitem:add(F_newfield1, tvbuffer(), field1_val)
                                   :set_text("Don't panic: " .. field1_val)
                        -- (now "http.newfield1 == 42" should work as a display filter)
                        field2_val = 616
                        subtreeitem:add(F_newfield2, tvbuffer(), field2_val)
                                   :set_text("The REAL number of the beast: " .. field2_val)
                end
        end
        local tcp_dissector_table = DissectorTable.get("tcp.port")
        original_http_dissector = tcp_dissector_table:get_dissector(80) -- save the original dissector so we can still get to it
        tcp_dissector_table:add(80, http_wrapper_proto)                 -- and take its place in the dissector table
end

Lua/Dissectors (last edited 2011-12-23 23:59:01 by GuyHarris)