Hi, I am new to Lua. I need to parse packets like below ETHERNET HEADER + PRIVATE HEADER (14 bytes) + ETHERNET HEADER + PAYLOAD I have a lua script to parse the PRIVATE HEADER, but don't know how to parse the remaining... Can someone please help? Here is my script.
asked 29 Jan '16, 22:18 yacare |
One Answer:
What exactly is unclear in this part of Lua API description? The first pass of eth dissector processes the first ethernet header and calls your dissector for the payload because you've hooked your dissector into the ethertype table, handing over to you the rest of the packet in the tvb parameter (referred to as Your dissector processes your private header and invokes the eth dissector, handing the rest of the packet to it in the So the result would be:
You may also want to define the individual proto.fields rather than just place the text names of the fields and their values into the dissection tree; if you do so, you can use the field names as display filters, e.g. To do so, you would just add the definition of the protocol fields next to your Proto definition:
And then, you would replace
by
answered 30 Jan '16, 01:38 sindy edited 30 Jan '16, 06:29 showing 5 of 10 show 5 more comments |
Thanks Sindy. This really helps.
Running into another issue. The script works fine when the inner eth-type is not 0x0800. When the inner ethernet frame has 0x0800, it carries the normal IP payload. For instance,
The scripts interpret the IP-header as private header. I know this is expected, but wonder any way to handle such scenario. Note that private-header is never present in the inner ethernet frames.
Thanks!
Well, I was hoping that the
ether_table:add(2048,foo_proto)
was just a bad example, not that you really misuse the ethertype value assigned to IP for your private header. Have you given a thought to what happens if, by mistake, someone connects your equipment sending such packets to a network which interprets this ethertype the normal way?From the point of view of Lua dissector it is not that complex, though. As you have told the eth dissector to invoke your one when(ever) it finds ethertype 2048, it is then your dissector's responsibility to choose between "foo" and "ip" dissection, through keeping track about how many times it has already been invoked on that particular frame. You also have to bear in mind that the same frame may get dissected several times in a row.
So your code might look as follows:
Another method to stop the recursion might be to check some values in the pinfo argument, although I’m not sure what’s exposed to Lua, e.g. the curr_layer_num member of pinfo shows how “deep” in the packet tree you are.
Also, the line
pinfo.cols.protocol = “foo”
, if used alone, only has a practical effect on theProtocol
column in the packet list iffoo
is the highest layer available in the frame. The reason is that normally each dissector sets this column to its own value - the goal is that always only the highest-layer protocol is shown. This is usually not an issue because by usingfoo
in your display filter, you can visualize only packets which do contain the “foo” layer.If you would really insist to see “foo” in the
Protocol
column although there is more data in the frame after “foo”, you would have to useafter setting the value. However, it does not prevent the subsequent dissectors from adding their own texts; it only keeps your one in front of them.
@grahamb, as
pinfo.curr_layer_num
is currently missing in the list of pinfo fields made available to Lua, one might wonder whether it has actually been?A quick test on 2.0.1 proves that your doubt was justified as it hasn’t:
yields
Lua Error: [string “C:\Users\JohnDoe\AppData\Roaming\Wireshark\p…"]:15: No such ‘curr_layer_num’ getter attribute/field for object type ‘Pinfo’
Also, just to make it 100% clear if someone adds the wrapper for Lua in future, does this pinfo attribute indicate a “layer” in terms of how many dissectors have already done their job in the current run over the frame, or “layer” in terms of the OSI model?
It’s the number of times a dissector has indicated it will try to handle the data in the packet. However, dissectors can explicitly ask for the count not to be incremented via the
add_pro_name
parameter todissector_try_uint_new()
anddissector_try_guid_new()
.The value should track the number of entries in the pinfo->layers list, however if the dissector didn’t handle any data in the packet its name is removed from the layers list, but the count isn’t decremented. This looks like a bug to me.
The comment for the commit (319bf245) that added
curr_layer_num
states:Thanks Sindy and Grahamb.
I modified my script as below. I want the foo_proto.dissector interpret the foo header only on the outer ethernet frame. However, I got an error saying “attempt to index global ‘dis_orig’ (a nil value)” at line 30 (that is “dis_orig:call(buffer,pinfo,tree)"). Somehow, we can’t get the dissector for 2048 from ether_table….
Changed to dis_orig = ether_table:get_dissector(0x0800). Still no luck. As a test, 0x0806 (ARP) made the error go away… dis_orig = ether_table:get_dissector(0x0806)
I have to use following and it works!
dis_orig = Dissector.get(“ip”)
Of course it did, because the error is reported when the script attempts to use the value, not when it fetches it. So unless there was an ARP payload in the inner Ethernet, the script never needed to use the pointer. So this provides a useful debug information only if you do have packets with ARP payload.
The reason why I’ve suggested to mine the dissector from the ethertype table rather than directly choose the “ip” one from the dissector table was that this is a Q&A site and someone else reading the answer may not want to replace/augment the dissection of IP but of some other protocol. So my audacious guess (because it does work for me the way I’ve suggested it) is that you have either disabled dissection of IP at some moment in the past, i.e. removed the row from the ethertype table (try to open a capture file of regular traffic to check that) or that you have two versions of Lua script in place, one of which destroys the pointer before the second one can access it.
The last point: I haven’t introduced the recursion tracking counter just for fun. Try to double-click the packet in the packet list pane, so that it opens in a separate window. In such case, the same packet is dissected twice in a row, so without the recursion counter, the second pass of the dissector uses ip dissection also on the private header. You cannot anticipate in what other use scenario the same packet may be dissected twice in a row, so even if you never open packets in separate windows, you should still stay on the safe side.
Thanks Sindy. Understand your last point now. It makes perfect sense. Just modified my script accordingly.