Examples

Using Lua to register protocols to more ports

-- register http to handle ports 4888-4891
do
        local tcp_port_table = DissectorTable.get("tcp.port")
        local http_dissector = tcp_port_table:get_dissector(80)
        for i,port in ipairs{4888,4889,4890,4891} do
                tcp_port_table:add(port,http_dissector)
        end
end

dumping to multiple files

-- Create a file named by_ip/''ip_addess''.cap with all ip traffic of each ip host. (works for tshark only)
-- Dump files are created for both source and destination hosts
do
        local dir = "by_ip"
        local dumpers = {}
        local function init_listener()
                local tap = Listener.new("ip")
                -- we will be called once for every IP Header.
                -- If there's more than one IP header in a given packet we'll dump the packet once per every header
                function tap.packet(pinfo,tvb,ip)
                        local ip_src, ip_dst = tostring(ip.ip_src), tostring(ip.ip_dst)
                        local src_dmp, dst_dmp
                        src_dmp = dumpers[ip_src]
                        if not src_dmp then
                                src_dmp = Dumper.new_for_current( dir .. "/" .. ip_src .. ".pcap" )
                                dumpers[ip_src] = src_dmp
                        end
                        src_dmp:dump_current()
                        src_dmp:flush()
                        dst_dmp = dumpers[ip_dst]
                        if not dst_dmp then
                                dst_dmp = Dumper.new_for_current( dir .. "/" .. ip_dst .. ".pcap"  )
                                dumpers[ip_dst] = dst_dmp
                        end
                        dst_dmp:dump_current()
                        dst_dmp:flush()
                end
                function tap.draw()
                        for ip_addr,dumper in pairs(dumpers) do
                                 dumper:flush()
                        end
                end
                function tap.reset()
                        for ip_addr,dumper in pairs(dumpers) do
                                 dumper:close()
                        end
                        dumpers = {}
                end
        end
        init_listener()
end

editing columns

/!\ Inacurate and outdated, to be refactored to reflect current state of WSLUA API.

-- The following exaple inverts the src and dst columns in wireshark extracting the values with FieldExtractor
do
    local ip_src = FieldExtractor.new("ip.src")
    local ip_dst = FieldExtractor.new("ip.dst")
    local stupid_joke_tap = Tap.new("stupid_joke")
    stupid_joke_tap:use_fields(ip_src,ip_dst)
    stupid_joke_tap:register()
        function per_packet.stupid_joke(pinfo)
                col_src = pinfo:col.src
                col_dst = pinfo:col.dst
                col_src:set(ip_dst:get())
                col_dst:set(ip_src:get())
        end
end

dialogs an TextWindows

/!\ Inacurate and outdated, to be refactored to reflect current state of WSLUA API.

--  This Example will add a menu "Lua Dialog Test" that when selected will pop a dialog prompting the user for input that when accepted will pop a window with a result.

if gui_enabled() then
   local splash = TextWindow.new("Hello!");
   splash:set("This time wireshark has been enhanced with an useles feature.\n")
   splash:append("Go to Statistics->Useless Feature and check it out!")
end
function dialog_menu()
    function dialog_func(person,eyes,hair)
        local win = TextWindow.new("The Person");
        win:set(person)
        win:append(" with " .. eyes .." eyes and")
        win:append(" " .. hair .. " hair.");
    end

    new_dialog("Dialog Test",dialog_func,"A Person","Eyes","Hair")
end
register_menu("Useless Feature",dialog_menu)

Packet counter

do
    packets = 0;
    local function init_listener()
        local tap = Listener.new("frame","ip.addr == 10.0.0.0/8")
        function tap.reset()
            packets = 0;
        end
        function tap.packet(pinfo,tvb,ip)
            packets = packets + 1
        end
        function tap.draw()
            print("Packets to/from 10.0.0./8",packets)
        end
    end
    init_listener()
end

Dump VoIP calls into separate files

-- voip.lua
-- Written by: Jason Garland <jgarland@jasongarland.com>

print("Starting voip.lua script.")


rex = require "rex_pcre"

--MySQL database connection
require "luasql.mysql"
env = assert (luasql.mysql())
con = assert (env:connect("voiper","voiper","password"))


do
        local voiperdir = os.getenv("voiperdir")
        local capturesdir = os.getenv("voiperdir") .. "/captures"
        dumpers = {}
        local frames = {}
        local rtp = {}
        last_packet = {}
        timeout = 300
        inin_callid = {}
        closed = {}
        files = {}
        files_path = {}
        --local tcp_src_f = Field.new("tcp.srcport")
        --local tcp_dst_f = Field.new("tcp.dstport")
        local udp_src_f = Field.new("udp.srcport")
        local udp_dst_f = Field.new("udp.dstport")
        local rtp_ssrc_f = Field.new("rtp.ssrc")
        local rtp_setup_frame_f = Field.new("rtp.setup-frame")
        local t38_setup_frame_f = Field.new("t38.setup-frame")
        local rtcp_setup_frame_f = Field.new("rtcp.setup-frame")
        local rtcp_ssrc_jitter_f = Field.new("rtcp.ssrc.jitter")
        local rtcp_ssrc_fraction_f = Field.new("rtcp.ssrc.fraction")
        local rtcp_ssrc_identifier_f = Field.new("rtcp.ssrc.identifier")
        local sip_callid_f = Field.new("sip.Call-ID")
        local sip_cseq_method_f = Field.new("sip.CSeq.method")
        local sip_status_code_f = Field.new("sip.Status-Code")

        local sip_contact_addr_f = Field.new("sip.contact.addr")
        local sip_request_line_f = Field.new("sip.Request-Line")
        local sip_from_addr_f = Field.new("sip.from.addr")

        local sdp_connection_info_address_f = Field.new("sdp.connection_info.address")
        local raw_sip_line_f = Field.new("raw_sip.line")
        local function init_listener()
                local tap = Listener.new("ip", "(rtp or rtcp or t38) or (sip and ((sip.CSeq.method != REGISTER) and (sip.CSeq.method != OPTIONS))) ")
                -- we will be called once for every IP Header.
                -- If there's more than one IP header in a given packet we'll dump the packet once per every header
                function tap.packet(pinfo,tvb,ip)
                        local ip_src, ip_dst = tostring(ip.ip_src), tostring(ip.ip_dst)
                                                                                                --local rtp_ssrc, rtp_setup_frame = rtp_ssrc_f(), rtp_setup_frame_f()
                                                                                                local rtp_setup_frame,rtp_ssrc = rtp_setup_frame_f(), rtp_ssrc_f()
                                                                                                local t38_setup_frame = t38_setup_frame_f()
                                                                                                local sip_cseq_method, sip_status_code, sip_callid, sdp_connection_info_address, raw_sip_line = sip_cseq_method_f(), sip_status_code_f(), sip_callid_f(), sdp_connection_info_address_f(), raw_sip_line_f()
                                                                                                local sip_contact_addr, sip_request_line, sip_from_addr = sip_contact_addr_f(), sip_request_line_f(), sip_from_addr_f() 
                                                                                                local rtcp_setup_frame, rtcp_ssrc_jitter, rtcp_ssrc_fraction, rtcp_ssrc_identifier = rtcp_setup_frame_f(), rtcp_ssrc_jitter_f(), rtcp_ssrc_fraction_f(), rtcp_ssrc_identifier_f()
                                                                                                local frame = tostring(pinfo.number)
                                                                                                local src_dmp, dst_dmp, rtp_dmp, sip_dmp
                                                
                                                                                                if sdp_connection_info_address then
                                                                                                        --print("Frame: " .. frame .. " = " .. tostring(sip_callid))
                                                                                                        frames[frame] = tostring(sip_callid)
                                                                                                end
                                                                        
                                                                                                if rtcp_setup_frame then
                                                                                                        if not (frames[tostring(rtcp_setup_frame)] == nil) then
                                                                                                                sip_callid = frames[tostring(rtcp_setup_frame)]
                                                                                                        end
                                                                                                end
                                                                        
                                                                                                if t38_setup_frame then
                                                                                                        if not (frames[tostring(t38_setup_frame)] == nil) then
                                                                                                                sip_callid = frames[tostring(t38_setup_frame)]
                                                                                                        end
                                                                                                end
                                                                                                
                                                                                                --if rtp_setup_frame then
                                                                                                        if not (frames[tostring(rtp_setup_frame)] == nil) then
                                                                                                                sip_callid = frames[tostring(rtp_setup_frame)]
                                                                                                                rtp[tostring(rtp_ssrc)] = sip_callid
                                                                                                        -- else
                                                                                                        --      rtp_dmp = dumpers[tostring(rtp_ssrc)]
                                                                                                        --      if not rtp_dmp then
                                                                                                        --              rtp_dmp = Dumper.new_for_current( capturesdir .. "/rtp/" .. tostring(rtp_ssrc) .. ".pcap" )
                                                                                                        --              dumpers[tostring(rtp_ssrc)] = rtp_dmp
                                                                                                        --      end
                                                                                                        --      rtp_dmp:dump_current()
                                                                                                        --      rtp_dmp:flush()
                                                                                                        end
                                                                                                --end
                        
                                                                                                if (sip_callid == nil) then
                                                                                                        if (rtp_ssrc) then
                                                                                                                sip_callid = rtp[tostring(rtp_ssrc)]
                                                                                                          --if not (sip_callid == nil) then print("SSRC: " .. tostring(rtp_ssrc) .. " = " .. sip_callid) end
                                                                                                        end
                                                                                                end
                                                                        
                                                                                                if sip_callid then
                                                                                                        if not ((closed[tostring(sip_callid)] == true)) then
                                                                                                                --check_age()
                                                                                                                if (files[tostring(sip_callid)] == nil) then
                                                                                                                        files_path[tostring(sip_callid)] = os.date("%Y", pinfo.abs_ts) .. "/" .. os.date("%m", pinfo.abs_ts) .. "/" .. os.date("%d", pinfo.abs_ts) .. "/" .. os.date("%H", pinfo.abs_ts) .. "/"
                                                                                                                        os.execute("mkdir -p " .. capturesdir .. "/" .. files_path[tostring(sip_callid)])
                                                                                                                        files[tostring(sip_callid)] = os.date("%Y%m%d%H%M%S", pinfo.abs_ts) .. "-" .. tostring(sip_callid) .. ".pcap"
                                                                                                                        -- print("Creating: " .. files_path[tostring(sip_callid)] .. files[tostring(sip_callid)])
                                                                                                                        res = assert (con:execute(string.format([[
                                                                                                                                INSERT INTO calls
                                                                                                                                (filepath, filename, callid, state)
                                                                                                                                VALUES ('%s', '%s', '%s', '%s')
                                                                                                                                ]], files_path[tostring(sip_callid)], files[tostring(sip_callid)], tostring(sip_callid), "open")
                                                                                                                                ))
                                                                        
                                                                                                                end
                                                                        
                                                                                                                -- print(tostring(sip_callid))
                                                                                                                sip_dmp = dumpers[tostring(sip_callid)]
                                                                                                                if not sip_dmp then
                                                                                                                                print("Opening: " .. files_path[tostring(sip_callid)] .. files[tostring(sip_callid)])
                                                                                                                                sip_dmp = Dumper.new_for_current( capturesdir .. "/" .. files_path[tostring(sip_callid)] .. files[tostring(sip_callid)] )
                                                                                                                                dumpers[tostring(sip_callid)] = sip_dmp
                                                                                                                end
                                                                                                                sip_dmp:dump_current()
                                                                                                                sip_dmp:flush()
                                                                                                                last_packet[tostring(sip_callid)] = os.clock()
                                                                                                                if (tostring(sip_cseq_method) == "BYE" and tostring(sip_status_code) == "200") then
                                                                                                                        sip_dmp:close()
                                                                                                                        sip_dmp = nil
                                                                                                                        mark_closed(sip_callid)
                                                                                                                end
                                                                                                                if (tostring(sip_cseq_method) == "INVITE" and tostring(sip_status_code) == "487") then
                                                                                                                        sip_dmp:close()
                                                                                                                        sip_dmp = nil
                                                                                                                        mark_closed(sip_callid)
                                                                                                                end
                                                                                                        else
                                                                                                                print("Ignoring packet after " .. tostring(sip_callid) .. " was closed.")
                                                                                                        end
                                                                                                end
                                                                        
                                                                        
                                                                                                if raw_sip_line_f() then
                                                                                                        local line = {raw_sip_line_f()}
                                                                                                        for i=1,#line do
                                                                                                                line[i] = tostring(line[i])
                                                                                                                local inin_callid_start, inin_callid_stop, inin_callid_header, inin_callid_value = rex.find(line[i], '^(ININCrn|x-inin-crn): ([0-9]*)\\\\r\\\\n$')
                                                                                                                if inin_callid_value then
                                                                                                                        if not inin_callid[tostring(sip_callid)] then
                                                                                                                                inin_callid[tostring(sip_callid)] = inin_callid_value
                                                                                                                                -- print(inin_callid_header .. ": " .. inin_callid_value)
                                                                                                                                res = assert (con:execute(string.format([[
                                                                                                                                        UPDATE calls
                                                                                                                                        SET `inin_callid` = '%s' WHERE `callid` = '%s']], inin_callid[tostring(sip_callid)], tostring(sip_callid))
                                                                                                                                ))
                                                                                                                        end
                                                                                                                        break
                                                                                                                end
                                                                                                        end
                                                                                                end
                end


                                                                                        function check_age()
                                                                                                for item in pairs(last_packet) do
                                                                                                        local age = os.difftime(os.clock(), last_packet[tostring(item)])
                                                                                                        if ( age >= timeout ) then
                                                                                                                print("Timeout: " .. item .. " because age is " .. age .. " seconds.")
                                                                                                                --return true
                                                                                                                mark_closed(item)
                                                                                                                --dumper = dumpers[tostring(item)]
                                                                                                                --print("Dumper: " .. tostring(dumper))
                                                                                                                --dumper:flush()
                                                                                                                --dumper:close()
                                                                                                                --dumpers[tostring(item)] = nil

                                                                                                                --dumpers[tostring(item)]:close()
                                                                                                                --dumpers[tostring(item)] = nil
                                                                                                        end
                                                                                                end
                                                                                        end

                                                                                        function mark_closed(sip_callid)
                                                                                                print("Closing: " .. files_path[tostring(sip_callid)] .. files[tostring(sip_callid)])
                                                                                                res = assert (con:execute(string.format([[
                                                                                                        UPDATE calls
                                                                                                        SET `state` = 'closed' WHERE `callid` = '%s' AND `filepath` = '%s' AND `filename` = '%s']], tostring(sip_callid), files_path[tostring(sip_callid)], files[tostring(sip_callid)])
                                                                                                ))
                                                                                                closed[tostring(sip_callid)] = true
                                                                                                inin_callid[tostring(sip_callid)] = nil
                                                                                                last_packet[tostring(sip_callid)] = nil
                                                                                                files[tostring(sip_callid)] = nil
                                                                                                files_path[tostring(sip_callid)] = nil
                                                                                        end

                                                                                        function tap.draw()
                                                                                                -- The show is over. Close the database connection and flush the buffers.
                        for item in pairs(closed) do
                                                                                                        print("cleaning up: " .. item)
                                                                                                        dumpers[tostring(item)] = nil
                                                                                                end

                                                                                                for item,dumper in pairs(dumpers) do
                                                                                                        print("Flushing: " .. files_path[tostring(item)] .. files[tostring(item)])
                                                                                                        dumper:flush()
                                                                                                        mark_closed(item)
                                                                                                end

                                                                                                -- Close the database connection
                                                                                                con:close()
                                                                                                env:close()
                                                                                        end

                                                                                        function tap.reset()
                        for item,dumper in pairs(dumpers) do
                                                                                                        mark_closed(item)
                                                                                                        dumper:close()
                                                                                                        print("Tap reset")
                                                                                                end
                        dumpers = {}
                                                                                        end
                                end
                                init_listener()
end

Lua/Examples (last edited 2009-07-10 15:05:51 by BogdanHarjoc)