Network‎ > ‎

Packet analyzer

My aim is to send a smiley at least once every 10 min of gameplay

Wireshark can be used to look at the packages sent between nodes in a game. There are two steps, capture and analyze.

Capture
Capturing can be done by running Wireshark on the node where we wish to capture all the data. By adding a filter we only see the packages that we care about. A simple filter is by adding the port we care about only.

port 28000

Analyze
There are two ways to make it more easy to understand what is going on with the packages in wireshark and that are dissectors and custom UI's.

Dissectors
To make sense of the packets we can add custom dissectors. Wireshark already dissect the IP and UDP/TCP part of the package so a custom only need to focus on the data payload. Dissectors can be written in C or lua. They need to be placed in the local plugin directory and that can be found by Help/About Wireshark and look at the folders tab.

-- 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)

Custom UI


-- This program will register a menu that will open a window with a count of occurrences
-- of every address in the capture

local function menuable_tap()
    -- Declare the window we will use
    local tw = TextWindow.new("Address Counter")

    -- This will contain a hash of counters of appearances of a certain address
    local ips = {}

    -- this is our tap
    local tap = Listener.new();

    function remove()
        -- this way we remove the listener that otherwise will remain running indefinitely
        tap:remove();
    end

    -- we tell the window to call the remove() function when closed
    tw:set_atclose(remove)

    -- this function will be called once for each packet
    function tap.packet(pinfo,tvb)
        local src = ips[tostring(pinfo.src)] or 0
        local dst = ips[tostring(pinfo.dst)] or 0

        ips[tostring(pinfo.src)] = src + 1
        ips[tostring(pinfo.dst)] = dst + 1
    end

    -- this function will be called once every few seconds to update our window
    function tap.draw(t)
        tw:clear()
        for ip,num in pairs(ips) do
            tw:append(ip .. "\t" .. num .. "\n");
        end
    end

    -- this function will be called whenever a reset is needed
    -- e.g. when reloading the capture file
    function tap.reset()
        tw:clear()
        ips = {}
    end
end

-- using this function we register our function
-- to be called when the user selects the Tools->Test->Packets menu
register_menu("Test/Packets", menuable_tap, MENU_TOOLS_UNSORTED)



Comments