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] Extracting multiple FieldInfo values from a Field in Lua

From: Eloy Paris <peloy@xxxxxxxxxx>
Date: Tue, 11 May 2010 10:32:10 -0400
Hi Gerald,

On 05/10/2010 09:00 PM, Gerald Combs wrote:

I'm trying to extract the "outer" and "inner" ip.src fields in an ICMP
time-to-live exceeded packet using Lua. If I create a listener that runs
the following:

     ip_src_f = Field.new("ip.src")
     local ip_src = ip_src_f()
     local src = tostring(ip_src.value)

I can only see the lowest-layer ip.src field. According to the User's
Guide, calling a field's method obtains *all* of the FieldInfo values
for that field. Adding a debug printf to Field__call in wslua_field.c
shows it pushing two ip.src values into the stack for each ICMP packet,
so Lua is presumably receiving them. Does anyone know how to access them
within the script?

The Lua API also provides a all_field_infos() function which returns the
entire dissection tree. Are there any examples that show how to use it?

Sorry, I don't know anything about the Lua stuff in Wireshark, but I thought I'd share my experience in this, somehow related, area:

I faced similar challenges when making dissection results available to the Tcl world in the Network Expect framework. The issue is that of "flattening" a dissection tree into a "flat" namespace for easy access from the scripting language. After trying a couple of different things I settled on an approach that manipulates a bit the names of dissection fields. In other words, instead of ending up with "ip.src" as the name of the Tcl variable, I end up with "xxx.ip.src", where "xxx" is determined by traversing the tree from that node and all the way up to the root.

Here is an example:

netexpect> set pkt [packet new ip(dst = 192.168.1.1)/ \
>   icmp-timeexceed()/ \
>   ip(src = 172.16.0.1, dst = 10.10.10.1, ttl = 1)/ \
>   icmp-echo()/data(data = '123456') ]
10.116.188.50 -> 192.168.1.1 ICMP Time-to-live exceeded (Time to live exceeded in transit)
netexpect>

This creates a "packet" object (don't worry about the netexpect technicalities) that represents an ICMP error message generated in response to an ICMP echo request with a TTL that expired. So there two "ip.src" after dissection, the source IP of the outer layer (192.168.1.1) and the source IP of the original, embedded ICMP message (172.16.0.1).

After dissection, these two "ip.src" fields end up in two Tcl variables, one called "ip.src" (outer IP source) and "icmp.ip.src":

netexpect> packet dissect pkt
netexpect> set ip.src
10.116.188.50
netexpect> set icmp.ip.src
172.16.0.1

Same thing for other fields, i.e. there are "ip.ttl" and "icmp.ip.ttl", etc.

While Tcl data structures are probably as flexible as those in Lua and other scripting languages, I thought that having variables named like "xxx.ip.src" makes it easier to access them from the realm of the scripting language (Tcl, in the case of Network Expect), as opposed to accessing element #2 in an array called "ip.src".

Cheers,

Eloy Paris.-
netexpect.org