Ask Your Question

Lua dissector is not processing the full TCP payload.

asked 2020-04-02 14:52:02 +0000

updated 2020-04-03 02:53:55 +0000

Guy Harris gravatar image


function acses_protocol.dissector(tvb, pinfo, tree)

    -- tvb is the data buffer that contains all of the message information. Reference the information with tvb(x, y) 
    -- where x is the starting position and y is the length to read (in bytes). Therefore, if the frame has no length, 
    -- then exit the dissector
    local frame_len = tvb:len()
    if frame_len == 0  then return end

    -- Create the GIU tab for ACSES information
    _G.subtree = tree:add(acses_protocol, tvb(), "ACSES Protocol Data")

    -- Add ACSES to the "Protocol" column in Wireshark
    pinfo.cols.protocol = ..":"

    --check for the weird split message
    if frame_len == 6 then 
        if (tvb(0, 4):uint() == 0xfff555ff) then 
            acsesHeader = tvb(0, 4):uint()
            acsesLength = tvb(4, 2):uint()
            subtree:add(f.isSplitMessage, true)
            pinfo.cols.protocol = tostring(pinfo.cols.protocol) .. " [SPLIT MESSAGE]" 

    -- Process the payload from beginning to end looking for ACSES messages
    -- since there may be more than 1 in a message.
    local msg_cnt = 0

    for i = 0, frame_len - 4, 1 do
        -- Determine if the message is an ACSES Message
        if tvb(i, 4):uint() == 0xfff555ff or (acsesHeader == 0xfff555ff and tvb(i, 4):uint() ~= 0xfff555ff and i == 0) then
            -- Add a separator between messages when there is more than 1 
            -- submessage embedded in a larger message
            if (msg_cnt > 0) then
                subtree:add(f.test_s, "###", "**************************************************", " ")

            -- get the message length from the buffer or get it from the previous message buffer
            if acsesLength ~= 0 and tvb(i, 4):uint() ~= 0xfff555ff and i == 0 then
                msg_len = acsesLength
                i = i-6
                --reset the previous message buffers
                acsesLength = 0
                acsesHeader = 0
                bufferFlag_ResetI = 1
                splitFlag = 1
                msg_len = tvb(i + 4, 2):uint()

            -- Determine if the message is a Maintience Train Alarm or Maintience Train Ack
            -- because they have the message label in a different location. For some unearthly reason.
            -- Also, check to see if the source address is 0, because if it is, that means it's a tsr response, but structured differently
            local msg_index = 0
            if ((msg_len == 36) or (msg_len == 58)) then
                msg_index = i + 27
            elseif tvb(i+8, 4):uint() == 0x00000a14 then
                msg_index = i + 20
                msg_index = i + 25

            -- It seems that the only defining feature of a self addressed message is its length
            -- otherwise, use the label. 
            if (msg_len == 15) then
                msg_lbl = 0
                msg_type = "Self_Addressed_Message"
                subtree:add(f.isSelfAddrMsg, true)
                msg_lbl = tvb(msg_index, 2):uint()
                msg_type = label_msg_type(msg_lbl)

            --Add the message type to the protocol column
            pinfo.cols.protocol = tostring(pinfo.cols.protocol) .. " " .. msg_type .. " (" .. msgtocode(msg_lbl) .. ")" 

            -- Output the message type to the top of the tree before dissecting the rest of the message
            subtree:append_text(" (" .. msg_type .. ") ")

            --[[Functions located in ixl.lua]]--
            if (msg_type == "IXL_Status_Request") then 
                ixl.ixl_request(tvb(i + 6, msg_len))

            --[[Functions located in wiu.lua]]--
            elseif (msg_type == "WIU_Response_w_LoMA") then
                wiu_resp_w_loma(tvb(i + 6, msg_len))
            elseif (msg_type == "WIU_Response_wo_LoMA") then
                wiu_resp_wo_loma(tvb(i + 6, msg_len))
            elseif (msg_type == "WIU_Error_Response") then
                wiu_error(tvb(i + 6, msg_len))

            --[[Functions located in tsr.lua]]--
            elseif tvb(i+8, 4):uint() == 0x00000a14 then
                tsr.tsr_answer_alt(tvb(i + 6, msg_len))
            elseif ...
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2020-04-02 22:26:32 +0000

cmaynard gravatar image

You should have a look at either dissect_tcp_pdus(), described in Section of the Wireshark Developer's Guide, or if you're unable to make use of that function, you may have to handle segments more "manually", in which case I'll refer you to the TCP reassembly section of the Lua/Dissectors wiki page and the excellent fpm.lua example found on the Lua/Examples wiki page.

edit flag offensive delete link more


Thank you for the quick response. So I have been trying to use the dissect_tcp_pdus(), however I get the "[TCP segment of a reassembled PDU] message rather than the message being dissected. I don't understand why?

Amandalorian gravatar imageAmandalorian ( 2020-04-03 14:46:45 +0000 )edit

When I wrote my first TCP-based Lua dissector, dissect_tcp_pdus() wasn't available, and so I based my work on the methods illustrated in the fpm.lua file. Later, I attempted to use dissect_tcp_pdus() on another TCP-based protocol, but I found it wanting in terms of edge cases, so I simply reverted back to the previous methodology, which I find to work quite well. My suggestion would be to do the same. It's only slightly more complicated to implement, but the example provided is excellent and rather straightforward to follow. I think you'll end up with much better results.

cmaynard gravatar imagecmaynard ( 2020-04-03 16:47:20 +0000 )edit

I am working on that implementation now. I will update you on how it goes. But it does seem promising. Thank you!!

Amandalorian gravatar imageAmandalorian ( 2020-04-03 16:49:20 +0000 )edit

I got it!!! Thank you so much!! :)

Amandalorian gravatar imageAmandalorian ( 2020-04-03 19:30:14 +0000 )edit

Nice. I'm glad I could help. Of course, most of the credit goes to @Hadriel, who wrote the fpm.lua file and shared it with the Wireshark community.

cmaynard gravatar imagecmaynard ( 2020-04-03 19:37:40 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2020-04-02 14:52:02 +0000

Seen: 53 times

Last updated: Apr 03