Wireshark-dev: Re: [Wireshark-dev] lua and ss7 mtp2
From: Hadriel Kaplan <HKaplan@xxxxxxxxxxxxxx>
Date: Sat, 16 Mar 2013 22:46:10 +0000
> From: Cristian Constantin <const.crist@xxxxxxxxxxxxxx> > Date: Fri, 15 Mar 2013 19:24:39 +0100 > > I am trying to access from a lua script the length indictator field of > the mtp2 protocol. > > 1. yes, I am sure that the capture contains ss7 mtp2 traffic > 2. yes, I am sure that the filter selects the ss7 mtp2 traffic. > 3. I am using wireshark: > > wireshark -v > wireshark 1.8.2 I suggest you upgrade to a newer Wireshark. There were some bugs with Lua-based Fields which were fixed in newer releases, like 1.9.0. I don't think you've hit one of those bugs, but it may help you avoid hitting them in the future. :) > does anyone here know why for example this snippet: > > local mtp2_li_field = Field.new("mtp2.li") > > function tap.packet(pinfo, tvb) > local mtp2_len = mtp2_li_field() > print("mtp2 len:", tostring(mtp2_len)) > print("mtp2 len:", tostring(mtp2_len.value)) > end > > dumps something like: > > mtp2 len: nil > [string "get_isup.lua"]:187: attempt to index local 'mtp2_len' (a nil value) > > ?? A Lua Listener tap will be executed against every packet/frame that it's registered the type for, which by default is every frame. So if there's even a single packet in your pcap file without a 'mtp2.li' field, your mtp2_len variable will be nil for that execution of tap.packet() for that packet. Therefore my guess is you've got one or more packets in the capture that don't have such a field. When you do this: print("mtp2 len:", tostring(mtp2_len.value)) You're trying to access the 'value' field of the 'mtp2_len' object, and 'mtp2_len' isn't an object but instead nil for a packet that doesn't have such a field, and thus errors. So you should do this instead: function tap.packet(pinfo, tvb) local mtp2_len = mtp2_li_field() if mtp2_len then print("mtp2 len:" .. tostring(mtp2_len)) print("mtp2 len:" .. tostring(mtp2_len.value)) else print("packet #" .. pinfo.number .. " didn't have a mtp2.li field") end end Another possibility is that you're parsing an Annex A MTP2 packet, or you have "Use extended sequence numbers" enabled for the "mtp2" protocol in your Wireshark preferences. In that case, I think it may be possible your mtp2_len field will always be nil, because there are *two* "mtp2.li" fields really: one using 8-bit numbering, and a second using 16-bit numbering. Internally they're really two separate fields, and which one gets populated depends on whether the packet is an Annex A or not, or if the preferences dictate it or not. When you do this: local mtp2_len = mtp2_li_field() I'm pretty sure Wireshark will correctly return the appropriate one as the one and only value; but it's possible it is returning either just nil because the first one is not filled in, or it's returning both - and if it's returning both, then setting the value of variable 'mtp2_len' to the first returned value from 'mtp2_li_field()' means you're getting the 8-bit one and thus probably nil. > otoh this one: > > local mtp2_field = Field.new("mtp2") > > function tap.packet(pinfo, tvb) > local mtp2 = mtp2_field() > local l = string.byte(mtp2.value,3); > end > > barks like this: > > [string "get_isup.lua"]:189: bad argument #1 to 'byte' (string > expected, got userdata) "mtp2" is a protocol field, I think - not a "normal" value field. Therefore, when you do this: local l = string.byte(mtp2.value,3); the 'mtp2.value' retrieves a ByteArray object (one of the object types defined by Wireshark's Lua), as opposed to a Lua string. Since the string.byte() function expects a Lua string for its first argument, this will fail. Lua's error message is a bit opaque because all Lua knows about the ByteArray object is that it's a Lua userdata type, as opposed to for example a Lua number or table type. Since it's a ByteArray object, you can call some methods against it to get values. See this: http://www.wireshark.org/docs/wsug_html_chunked/lua_module_Tvb.html#lua_class_ByteArray For example: function tap.packet(pinfo, tvb) local mtp2 = mtp2_field() local mtp2val = mtp2 and mtp2.value -- gets the value if mtp2 is not nil/false if mtp2val then local l = mtp2val:get_index(3) -- gets the decimal number of third byte print("The third byte of the mtp2 protocol section is: " .. l) end end > on a more general note, how to use lua in wireshark with binary > protocols when lua > lacks built-in support for working with binary values (i.e. > pack/unpack, oct a la perl)??? > > I mean I have found and I have used the "struct" package from here: > http://www.inf.puc-rio.br/~roberto/struct/ > > but in this case it does not seem to be enough… See above - I think those might solve the problem. If there's something you need from ByteArray that doesn't exist, or have a use-case for byte handling that can't be solved with the current Lua API, please submit a enhancement request bug. I wouldn't be surprised to find there will be some such cases, but I haven't hit one myself yet. :) -hadriel
- Follow-Ups:
- Re: [Wireshark-dev] lua and ss7 mtp2
- From: Cristian Constantin
- Re: [Wireshark-dev] lua and ss7 mtp2
- Prev by Date: Re: [Wireshark-dev] Automatic update USB Vendor ID / Product ID
- Next by Date: [Wireshark-dev] Drop sql-oracle dissector?
- Previous by thread: [Wireshark-dev] lua and ss7 mtp2
- Next by thread: Re: [Wireshark-dev] lua and ss7 mtp2
- Index(es):