Search code examples
wireshark

Using Wireshark Field Occurrence in Display Filter


Using Wireshark 4.2.2, I can create a custom display column that displays the value from a certain field occurrence. I would like to be able to do something similar and use a field occurrence in a display filter, but I cannot find any reference as to how to do that.

Specifically, I am looking at a capture file that contains SIP messages which have a SDP body. In the SDP, there are multiple media lines for each media stream defined. I want to create a display filter that shows when the first media stream supports a certain format and the second media stream does not support that format.

I can create 2 custom custom display columns from the sdp.media field, one with Field Occurrence set to 1 and one with Field Occurrence set to 2; and the Wireshark table will properly show the two media streams, 1 in each column. I can inspect these manually for my conditions, but would prefer to create a display filter to help with the inspection.

I have tried something like sdp.media[1] contains "0" && !sdp.media[2] contains "0" or sdp.media#1 contains "0" && !sdp.media#2 contains "0". However, I understand that the slice operator ([1]) is operating on a byte array rather than field occurrence and the layer operator (#1) is operating on the network layer and also not on field occurrence.

Is this possible at all with Wireshark or must I perform manual inspection? Bonus points if I can use the sdp.media.format field instead of just sdp.media, something like sdp.media[1].format contains "PCMU" && !sdp.media[2].format contains "PCMU".


Solution

  • You could try to use a Lua post-dissector to achieve your goal. For example:

    local sdp_post = Proto("sdp_post", "SDP post-dissector")
    
    local sdp_media_formats = {
        [1] = ProtoField.string("sdp_post.media.format.1", "Media Format 1"),
        [2] = ProtoField.string("sdp_post.media.format.2", "Media Format 2"),
        [3] = ProtoField.string("sdp_post.media.format.3", "Media Format 3"),
        [4] = ProtoField.string("sdp_post.media.format.4", "Media Format 4"),
        [5] = ProtoField.string("sdp_post.media.format.5", "Media Format 5"),
        [6] = ProtoField.string("sdp_post.media.format.6", "Media Format 6"),
        [7] = ProtoField.string("sdp_post.media.format.7", "Media Format 7"),
        [8] = ProtoField.string("sdp_post.media.format.8", "Media Format 8"),
        [9] = ProtoField.string("sdp_post.media.format.9", "Media Format 9"),
        [10] = ProtoField.string("sdp_post.media.format.10", "Media Format 10")
    }
    sdp_post.fields = sdp_media_formats
    
    local sdp_media_format_f = Field.new("sdp.media.format")
    
    function sdp_post.dissector(tvb, pinfo, tree)
    
        local sdp_media_format = {sdp_media_format_f()}
        if sdp_media_format then
    
            local sdp_post_tree = tree:add(sdp_post, "SDP Postdissector: " .. #sdp_media_format .. " Media Formats")
    
            for i, v in pairs(sdp_media_format) do
                if sdp_media_formats[i] then
                    sdp_post_tree:add(sdp_media_formats[i], v.value)
                else
                    sdp_post_tree:append_text(" (Only showing the first " .. i-1 .. ")")
                    break
                end
            end
        end
    end
    
    register_postdissector(sdp_post)
    

    Save this to a file such as sdp-postdissector.lua and place it in your "Personal Lua Plugins" directory, which you can find from "Wireshark: Help -> About Wireshark -> Folders". Once you've done that, either restart Wireshark or use "Analyze -> Reload Lua Plugins (Ctrl+Shift+L)" to load it. Now you should be able to use the sdp_post.media.format.i postdissector display filters to achieve your goal. For example: sdp_post.media.format.1 contains "PCMA" will display packets 1 and 11 in your capture file.

    Note: If you want to work with other sdp fields besides just sdp.media.format, then you might want to refer to my answer to this related question: How to add an array of fields as a ProtoField in Lua Dissector