title: Wireshark: display filters vs nested dissectors
body: <p>I have an application that sends JSON objects over AMQP, and I want to inspect the network traffic with Wireshark.  The AMQP dissector gives the payload as a series of bytes in the field <code>amqp.payload</code>, but I'd like to extract and filter on specific fields in the JSON object, so I'm trying to write a plugin in Lua for that.</p>
  
  <p>Wireshark already has a dissector for JSON, so I was hoping to piggy-back on that, and not have to deal with JSON parsing myself.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>local amqp_json_p = Proto("amqp_json", "AMQP JSON payload")
  local amqp_json_result = ProtoField.string("amqp_json.result", "Result")
  amqp_json_p.fields = { amqp_json_result }
  register_postdissector(amqp_json_p)
  
  local amqp_payload_f = Field.new("amqp.payload")
  local json_dissector = Dissector.get("json")
  
  local json_member_f = Field.new("json.member")
  local json_string_f = Field.new("json.value.string")
  
  function amqp_json_p.dissector(tvb, pinfo, tree)
     local amqp_payload = amqp_payload_f()
     if amqp_payload then
        local payload_tvbrange = amqp_payload.range
        if payload_tvbrange:range(0,1):string() == "{" then
           json_dissector(payload_tvbrange:tvb(), pinfo, tree)
           -- So far so good.  Let's look at what the JSON dissector came up with.
           local members = { json_member_f() }
           local strings = { json_string_f() }
           local subtree = tree:add(amqp_json_p)
           for k, member in pairs(members) do
              if member.display == 'result' then
                 for _, s in ipairs(strings) do
                    -- Find the string value inside this member
                    if not (s &lt; member) and (s &lt;= member) then
                       subtree:add(amqp_json_result, s.range)
                       break
                    end
                 end
              end
           end
        end
     end
  end
  </code></pre>
  
  <p>(To start with, I'm just looking at the <code>result</code> field, and the payload I'm testing with is <code>{"result":"ok"}</code>.)</p>
  
  <p>It gets me halfway there.  The following shows up in the packet dissection, whereas without my plugin I only get the AMQP section:</p>
  
  <pre><code>Advanced Message Queueing Protocol
      Type: Content body (3)
      Channel: 1
      Length: 15
      Payload: 7b22726573756c74223a226f6b227d
  JavaScript Object Notation
      Object
          Member Key: result
              String value: ok
              Key: result
  AMQP JSON payload
      Result: "ok"
  </code></pre>
  
  <p>Now I want to be able to use these new fields as display filters, and also to add them as columns in Wireshark.  The following work for both:</p>
  
  <ul>
  <li><code>json</code> (shows up as <code>Yes</code> when added as a column)</li>
  <li><code>json.value.string</code> (I can also filter with <code>json.value.string == "ok"</code>)</li>
  <li><code>amqp_json</code></li>
  </ul>
  
  <p>But <code>amqp_json.result</code> doesn't work: if I use it as a display filter, Wireshark doesn't show any packets, and if I use it as a column, the column is empty.</p>
  
  <p>Why does it behave differently for <code>json.value.string</code> and <code>amqp_json.result</code>?  And how can I achieve what I want?  (It seems like I do need a custom dissector, as with <code>json.value.string</code> I can only filter on <em>any</em> member having a certain value, not necessarily <code>result</code>.)</p>
  
  <hr>
  
  <p>I found <a href="http://wireshark-dev.wireshark.narkive.com/qMnA5KPY/lua-post-dissector-not-getting-field-values" rel="nofollow noreferrer">a thread on the wireshark-dev mailing list</a> ("Lua post-dissector not getting field values", 2009-09-17, 2009-09-22, 2009-09-23), that points to the <code>interesting_hfids</code> hash table, but it seems like the code has changed a lot since then.</p>
  
  <p>If you'd like to try this, here is my PCAP file, base64-encoded, containing a single packet:</p>
  
  <pre><code>1MOyoQIABAAAAAAAAAAAAAAABAAAAAAAjBi1WfYOCgBjAAAAYwAAAB4AAABgBMEqADcGQA
  AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB/tcWKO232y46mkSqgBgxtgA/AAAB
  AQgKRjDNvkYwzb4DAAEAAAAPeyJyZXN1bHQiOiJvayJ9zg==
  </code></pre>
  
  <p>Decode with <code>base64 -d</code> (on Linux) or <code>base64 -D</code> (on OSX).</p>