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

Hi,

I'm fascinated about Lua, after I had some time to learn a bit of Lua, on a longer travel by train yesterday (also inspired by this question and the code provided by @helloworld). The language is pretty simple but powerful and apparently (sometimes) faster than other scripting languages (I use Perl a lot).

Now my question: Is there a detailed description available about the Lua integration into wireshark? I know the wiki articles, the API documentation (merely a documentation of the function calling interface, which is O.K. as a reference) and some sharkfest presentations. However that does not fully explain all the details, necessary to write a dissector or a listener. The available sample code does help a bit, however (currently) it is not enough for me to fully understand the integration.

Sample code of a large (real world) dissector or listener would be really helpful. Can anyone here provide such an example?

Regards
Kurt

asked 25 May '12, 04:20

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237
accept rate: 15%

edited 29 May '12, 05:32

I don't have enough uninterrupted time to formulate a decent answer, but I'll get back to you later. I hope someone beats me to it though. :)

(25 May '12, 11:13) helloworld

O.K. I'm looking forward to it.

BTW: Who has implemented the Lua integration?

(25 May '12, 11:23) Kurt Knochner ♦

I'm not sure I understand the context of "Lua integration". Are you asking who originally implemented the Wireshark Lua bindings? I believe it was Luis Ontanon and Ulf Lamping.

(25 May '12, 14:28) helloworld

Yes I mean the Lua binding.

(25 May '12, 15:37) Kurt Knochner ♦

I hope someone beats me to it though. :)

beat/bump ;-)

(29 May '12, 05:31) Kurt Knochner ♦

Introduction

In Wireshark Lua, there are two types of packet processors: dissectors and listeners.


Dissector Listener
  • called for each frame that occurs at a particular dissector table (e.g., UDP port 5000)
  • called for each frame that matches a particular display filter
  • used to parse raw frame data into human-friendly named fields
  • useful for extracting information from a capture file (including the named fields)
  • can be invoked multiple times per frame
  • invoked only once per frame
  • optionally adds protocol fields as tree items (in the Packet Details Pane)
  • cannot add protocol fields

  • There are also post-dissectors:

    • a special type of Dissector that is called for every frame and runs after all other non-post-dissectors
    • useful for adding tree items that assist in traffic analysis (e.g., using an expert-info tree item to flag high traffic volume between two endpoints)
    • example post-dissector

    How to write a Lua dissector

    1. Create a Lua file (named proto_foo.lua) at one of the following directories:

      • C:\Program Files\Wireshark\plugins\1.6.8\ (Windows)
      • C:\Users\johndoe\AppData\Roaming\Wireshark\plugins\ (Windows)
      • $HOME/.wireshark/plugins/ (UN*X)
    2. In proto_foo.lua, do the following:

      • Declare the protocol with Proto().
      • Declare the protocol's fields with ProtoField.XXX().
      • (OPTIONAL) Declare the protocol's preferences with Pref.XXX().
      • Declare the protocol's dissector(Tvb, Pinfo, TreeItem) function (called for each frame).
      • (OPTIONAL) Declare the protocol's init() function (called whenever prefs are set or a pcap is loaded)
      • Register the protocol with a DissectorTable (inside init() if it exists).

      See example implementation of proto_foo.lua

    3. Start tshark or Wireshark. If the Lua script contained any syntax errors, an error message appears, and you'll have to edit the file and restart the program.

    4. To quickly verify whether Foo was properly registered, enter foo in Wireshark's Display Filter Textbox, and confirm that it turns green.

    5. To test your Foo dissector, start a Wireshark capture session, and generate traffic on the corresponding network interface. If using the example implementation of Foo, you can use netcat to generate a 21-byte UDP payload on port 3456 (assumes default network interface):

    $ echo "123456789012345678901" | nc -w 1 -u 1.1.1.1 3456

    How to write a Lua listener

    1. Create a Lua file (named tap_foo.lua) at one of the following directories:

      • C:\Program Files\Wireshark\plugins\1.6.8\ (Windows)
      • C:\Users\johndoe\AppData\Roaming\Wireshark\plugins\ (Windows)
      • $HOME/.wireshark/plugins/ (UN*X)
    2. In tap_foo.lua, do the following:

      • Declare the tap with the Listener(BuiltInTapName, DisplayFilter) function. You can use one of the built-in taps or create a new one that uses the specified display filter. The names of the built-in taps are: ip, udp, http, bacapp, h225, actrace, ansi_a, ansi_map, eth, tcp, wlan, frame

      • (OPTIONAL) Declare field extractors (with the Field.new(FieldName) function) to pull values of named fields from the current packet. These cannot be declared inside the packet function.

      • Declare the tap's packet(Pinfo, Tvb, BuiltInTapData) function. This function is notified with every packet that matches the tap's filter. The function is passed the packet info (pinfo), buffer (Tvb), and built-in tap data (only if a built-in tap was specified during tap declaration). For better performance, avoid any calls that would cause GUI repainting (e.g., adding items to a listview) in this function; reserve those for the draw function.

      • (OPTIONAL) Declare the tap's draw() function. This function is called periodically to notify any external GUI programs to draw the results (which were accumulated in the packet function). This is where you would do any fancy GUI stuff with Wireshark's GUI calls or with, e.g., wxWidgets (via wxLua) or Qt (via lqt).

      • (OPTIONAL) Declare the tap's reset() function. This function is called at the beginning and end of a capture run, where any initialization should be done if necessary to prepare for a new session. If your tap doesn't have any local state, then you don't need to implement this function.

      See example implementation of tap_foo.lua (requires proto_foo.lua above).

    3. Start tshark or Wireshark. If the Lua script contained any syntax errors, an error message appears, and you'll have to edit the file and restart the program.

    4. To test your Foo listener, start a Wireshark capture session, and generate traffic on the corresponding network interface. Alternatively, open a pcap file that contains packets of interest. If using the example implementation of Foo, you can use tshark as follows:

    $ tshark -q -r foo.pcap -R foo

    This opens the file foo.pcap and filters for Foo packets. Assuming tap_foo.lua exists in one of the directories from Step 1, tshark automatically loads the listener, which processes the foo packets from foo.pcap. The example listener prints the value(s) of a specific field for each packet, so you can easily confirm that from the Wireshark Lua console (Tools > Lua > Console).


    Loading a Lua script

    There are actually multiple ways to load a Wireshark Lua script. In the steps above, we used Option 2 described below (mostly because it's convenient).

    Option 1: Use -Xlua_script:filename

    You can use the -X command-line parameter, specifying lua_script as the variable name and the path to the script as the variable value. For example, the following command loads the Lua script foo.lua from the current directory. Note that path can be relative or absolute, and the filename does not need to have the .lua extension.

    $ wireshark -X lua_script:foo.lua
    

    Option 2: Put the Lua script in the Lua initialization path

    You can put the Lua file in one of the directories that Wireshark/TShark scans at startup, and restart Wireshark/TShark.

    UN*X

    • /share/wireshark/plugins/foo.lua (global)
    • $HOME/.wireshark/plugins/foo.lua (user-specific)

    Windows

    • %PROGRAMFILES%\Wireshark\plugins\%WIRESHARK_VERSION%\foo.lua (global)
    • %APPDATA%\Roaming\Wireshark\plugins\foo.lua (user-specific)

    Option 3: Modify init.lua to load the file

    You can edit the global init.lua or the user-specific $HOME/.wireshark/init.lua.

    For example, add the following to the end of init.lua:

    -- load the Foo module
    dofile('/path/to/foo.lua')
    

    This method allows the highest control during initialization (in case you need to control the load order); and allows putting the Lua files anywhere in the system. However, these files must not be in the Lua initialization path (where they'd automatically be loaded) or else you may encounter a registration error (e.g., from registering a protocol dissector with the same name twice).


    Debugging a Lua script

    It's mostly a trial-and-error process: You edit the Lua script, load it in Wireshark/TShark, and troubleshoot any errors with print-outs or with Lua debug. The print-outs can be seen either from the Lua console in Wireshark (Tools > Lua > Console) or from the terminal that started Wireshark/TShark.

    The Lua debug library provides an API that can be helpful. WSLua actually hides the debug symbol (likely unintentionally) with its own debug() function that prints to the Lua console (or stdout) at the DEBUG level. However, you can still access Lua debug by using the require keyword:

    local d = require 'debug'
    
    -- print our traceback (like a stacktrace)
    print(d.traceback())
    
    -- enter the Lua debugger, which has this prompt:  lua_debug>
    -- (to exit, type 'cont')
    d.debug()
    
    permanent link

    answered 05 Jun '12, 14:51

    helloworld's gravatar image

    helloworld
    3.1k42041
    accept rate: 28%

    edited 05 Jun '12, 15:28

    VERY nice !! Thank you.

    (08 Jun '12, 03:28) Kurt Knochner ♦

    To me Lua in wireshark is one of it's most powerful features yet it's feels like best kept secret. It's difficult to find useful working samples

    Here are some links I've found online overtime

    http://paperlined.org/apps/wireshark/ArchivedLuaExamples/

    http://code.google.com/p/lua-bitstring/wiki/ExplainFastDissect

    I also thinks helloworld's code snippets on this portal are little gems that tought me quite a bit.

    Checkout posts with lua tags on them.

    permanent link

    answered 25 May '12, 16:53

    izopizo's gravatar image

    izopizo
    2024714
    accept rate: 0%

    I also thinks helloworld's code snippets on this portal are little gems that tought me quite a bit.

    I agree and I'm waiting for some "uninterrupted time to formulate a decent answer" :-)

    (27 May '12, 02:02) Kurt Knochner ♦
    Your answer
    toggle preview

    Follow this question

    By Email:

    Once you sign in you will be able to subscribe for any updates here

    By RSS:

    Answers

    Answers and Comments

    Markdown Basics

    • *italic* or _italic_
    • **bold** or __bold__
    • link:[text](http://url.com/ "title")
    • image?![alt text](/path/img.jpg "title")
    • numbered list: 1. Foo 2. Bar
    • to add a line break simply add two spaces to where you would like the new line to be.
    • basic HTML tags are also supported

    Question tags:

    ×431
    ×5

    question asked: 25 May '12, 04:20

    question was seen: 13,537 times

    last updated: 24 Oct '12, 21:15

    p​o​w​e​r​e​d by O​S​Q​A