Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: Re: [Wireshark-dev] Intro and lua question

From: "Maynard, Chris" <Christopher.Maynard@xxxxxxx>
Date: Mon, 24 Oct 2016 14:55:35 +0000
> -----Original Message-----
> From: wireshark-dev-bounces@xxxxxxxxxxxxx [mailto:wireshark-dev-
> bounces@xxxxxxxxxxxxx] On Behalf Of Peter Wu
> Sent: Friday, October 21, 2016 5:48 PM
> To: Developer support list for Wireshark <wireshark-dev@xxxxxxxxxxxxx>
> Subject: Re: [Wireshark-dev] Intro and lua question
> 
> On Fri, Oct 21, 2016 at 01:24:52PM -0700, Jerry White wrote:
> > Hi,
> [..]
> > Advanced packet
> > <tcp header stuff>
> > <MyProto fixed length header><MyProto variable length data> <MyProto
> > fixed length header><MyProto variable length data> <MyProto fixed
> > length header><MyProto variable length data>
> >
> > This packet has three application transactions in it. The first 8
> > bytes of the MyProto header are always the same, and I can count from
> > there into the packet to parse out the fields I need. The problem is,
> > since the data section is variable length, I don't know where to look for the
> next header.
> > How do I do that in lua?
> 
> As Michael noted, if the length can be derived from the header, then you can
> use the dissect_tcp_pdus Lua function (in the C library code it is called
> tcp_dissect_pdus instead. It is documented at
> https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Proto.
> html
> 
> Here is an example of using dissect_tcp_pdus, it has abirtrary numbers, but it
> should show the idea. Read mgi.dissector first, then get_mgi_length, then
> dissect_mgi for a better understanding.
> Documentations link follow, here is the code:
> 
>     function get_mgi_length(tvb, pinfo, offset)
>         -- Note: tvb(...) and tvb:range(...) both create a TvbRange,
>         -- prefer the former since it is more efficient (it saves a
>         -- method lookup)
> 
>         -- When you access a TvbRange as string, then the __tostring
>         -- method will be used which is typically not what you want.
>         -- Therefore invoke int, string, etc. for as appropriate
>         local msgid = tvb(offset, 4):uint()
> 
>         if msgid == 1234 then
>             -- Assume this field contains the length following the header
>             local datalen = tvb(offset + 4, 4):uint()
> 
>             return 19 + datalen
>         elseif msgid == 4567 then
>             -- Example that shows what to do if you need more bytes to
>             -- know the actual length: the real length is stored in four
>             -- bytes at offset 20.
> 
>             if tvb:reported_len() < offset + 20 + 4 then
>                 -- special value (supported since 2.0) that indicates
>                 -- that more bytes are needed to know PDU length
>                 return 0
>             end
> 
>             -- Length is definitely valid, so can safely read length now
>             local datalen = tvb(offset + 20, 4):uint()
>             return 19 + datalen
>         else
>             -- In other cases, assume just the fixed-length header
>             return 19
>         end
>     end
> 
>     function dissect_mgi(tvb, pinfo, tree)
>         pktinfo.cols.info:set("MSGID=")
> 
>         -- note: changed from tvb:range() to tvb()
>         local info_mgi_msg_id = tvb(9, 10)
>         -- example of using :string() to print a hex string instead of
>         -- some hexadecimal representation
>         pktinfo.cols.info:append(info_mgi_msg_id:string())
> 
>         -- etc.
>     end
> 
>     function mgi.dissector(tvb, pinfo, tree)
>         -- Assume that you need to know at least 19 bytes for retrieving
>         -- the length. Then when at least 19 bytes are available, call
>         -- get_mgi_length to find the real length. If the full data is
>         -- available, call dissect_mgi to handle it.
>         dissect_tcp_pdus(tvb, tree, 19, get_mgi_length, dissect_mgi)
>     end
> 
> The full reference manual of the Lua interface exposed by Wireshark is
> available at
> https://www.wireshark.org/docs/wsdg_html_chunked/wsluarm_modules.h
> tml
> 
> The dissect_tcp_pdus function is documented in the "Global Functions"
> section at
> https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Proto.
> html
> --
> Kind regards,
> Peter Wu
> https://lekensteyn.nl
> __________________________________________________________


You might also want to take a look at Hadriel Kaplan's fpm.lua example posted at https://wiki.wireshark.org/Lua/Examples.  It solves this problem without using dissect_tcp_pdus().
- Chris




-- 

CONFIDENTIALITY NOTICE: This message is the property of International Game Technology PLC and/or its subsidiaries and may contain proprietary, confidential or trade secret information.  This message is intended solely for the use of the addressee.  If you are not the intended recipient and have received this message in error, please delete this message from your system. Any unauthorized reading, distribution, copying, or other use of this message or its attachments is strictly prohibited.