This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

fetching multiple named values with lua

1

In working on a lua extension, I want to be able to extract multiple instances of a field within a single packet. For example, in DNS, it's not uncommon to have multiple responses to a query. As an example, in this dns capture file, there are multiple responses in packets 4, 24 and 29. What I would like to do is get all instances of a field such as dns.resp.name for those packets using lua. Here is what I have so far:

-- dns.lua
-- example of a tap that shows DNS answers when there are more than one returned

dns_tap = Listener.new(nil, "dns.count.answers > 1") msg = "" count = Field.new("dns.count.answers") dns_name = Field.new("dns.resp.name") bad = true

function dns_tap.packet(pinfo) msg = "Packet " .. pinfo.number .. " had " .. tostring(count()) .. " answers." debug(msg) if bad then for xx in dns_name() do debug(xx) end end end

However, this doesn’t work. If invoked with this command line:

tshark -X lua_script:dns.lua -r dns.cap > out.txt

all I get is the first dns_name infinitely repeated until I halt the program. What I want is just the finite list of actual answers. I am the using very latest SVN version (version 35289 from /trunk) on Windows, but I get the same result on Linux.

asked 01 Jan ‘11, 16:50

beroset's gravatar image

beroset
2261213
accept rate: 33%


One Answer:

3

OK, I finally got it. The key is that if there may be multiple values, one must use a lua table as { dns_name() } instead of the singular dns_name().

The working version of this code sample is this:

-- dns.lua
-- example of a tap that shows DNS answers when there are more than one returned
dns_tap = Listener.new(nil, "dns.count.answers > 1")
msg = ""
count = Field.new("dns.count.answers")
dns_name = Field.new("dns.resp.name")
function dns_tap.packet(pinfo)
    msg = "Packet " .. pinfo.number .. " had " .. tostring(count()) .. " answers."
    debug(msg)
    local answers = {dns_name()}  -- this is how to do it
    for i in pairs(answers) do    -- iterate through all of the values returned
       debug(answers[i])
    end
end
There may some merit in adding a bit more text to the auto-generated documentation to make this point clearer. I'll look into doing that.

answered 02 Jan '11, 06:04

beroset's gravatar image

beroset
2261213
accept rate: 33%