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

I'm writing a Lua chained dissector on top of the standard HTTP dissector to extract information from the HTTP payload. However, when I chain my dissector with the original HTTP dissector, reassembly is failing. I stripped down the Lua dissector to the bare minimum but still have the issue. Here is the stripped down dissector:

do
        local http_wrapper_proto = Proto("http_extra", "Extra analysis of the HTTP protocol");
        local original_http_dissector
        function http_wrapper_proto.dissector(tvbuffer, pinfo, treeitem)
            original_http_dissector:call(tvbuffer, pinfo, treeitem)
        end

        local tcp_dissector_table = DissectorTable.get("tcp.port")
        original_http_dissector = Dissector.get("http")
        tcp_dissector_table:add(80, http_wrapper_proto)
        tcp_dissector_table:add(8888, http_wrapper_proto)
end

Without the dissector, reassembly works fine:

$ tshark -r li.buienradar.nl.pcapng -Y http
  5 0.028009000 192.168.0.17 -> 192.168.0.18 HTTP 294 POST http://li.buienradar.nl/api/Publication HTTP/1.1  (application/json)
 11 0.463406000 192.168.0.18 -> 192.168.0.17 HTTP 217 HTTP/1.1 200 OK  (application/json)
 24 116.487852000 192.168.0.17 -> 192.168.0.18 HTTP 294 POST http://li.buienradar.nl/api/Publication HTTP/1.1  (application/json)
 28 116.628794000 192.168.0.18 -> 192.168.0.17 HTTP 217 HTTP/1.1 200 OK  (application/json)
$

But when the Lua dissector is used, reaassembly fails:

$ tshark -r li.buienradar.nl.pcapng -Y http -X lua_script:http3.lua
  4 0.028009000 192.168.0.17 -> 192.168.0.18 HTTP 428 POST http://li.buienradar.nl/api/Publication HTTP/1.1 
  9 0.437610000 192.168.0.18 -> 192.168.0.17 HTTP 523 HTTP/1.1 200 OK 
 22 116.484815000 192.168.0.17 -> 192.168.0.18 HTTP 428 POST http://li.buienradar.nl/api/Publication HTTP/1.1 
 26 116.535529000 192.168.0.18 -> 192.168.0.17 HTTP 523 HTTP/1.1 200 OK 
$

Am I doing something wrong? Is this a bug? Or is reassembly functionality somehow not implemented yet for chained Lua dissectors?

asked 28 Nov '16, 15:02

SYN-bit's gravatar image

SYN-bit ♦♦
17.1k957245
accept rate: 20%


So what you're doing is inserting another dissector between TCP and HTTP, right?

The problem, I think, (having not tried anything) comes down to what's explained in this comment in epan/packet.c:

    /*
     * can_desegment is set to 2 by anyone which offers the
     * desegmentation api/service.
     * Then everytime a subdissector is called it is decremented
     * by one.
     * Thus only the subdissector immediately on top of whoever
     * offers this service can use it.
     * We save the current value of "can_desegment" for the
     * benefit of TCP proxying dissectors such as SOCKS, so they
     * can restore it and allow the dissectors they call to use
     * the desegmentation service.
     */

The important part is the Thus only the subdissector immediately on top of whoever offers this service can use it bit.

(pinfo->can_desegment, which is set here, is checked by the req_resp_hdrs.c code which is used by the HTTP dissector.)

You should (if the LUA API allows you) be able to solve this by incrementing can_desegment in your dissector (before calling the HTTP dissector). It appears that's what the SSL dissector does.

permanent link

answered 04 Dec '16, 07:47

JeffMorriss's gravatar image

JeffMorriss ♦
6.2k572
accept rate: 27%

Thanks Jeff, that did the trick, here is the alteration for future reference:

do
        local http_wrapper_proto = Proto("http_extra", "Extra analysis of the HTTP protocol");
        local original_http_dissector
        function http_wrapper_proto.dissector(tvbuffer, pinfo, treeitem)
            local can_desegment_saved = pinfo.can_desegment
            if pinfo.can_desegment > 0 then
                pinfo.can_desegment = 2
            end

            original_http_dissector:call(tvbuffer, pinfo, treeitem)

            -- my extra diseector code is inserted here

            pinfo.can_desegment = can_desegment_saved
        end

        local tcp_dissector_table = DissectorTable.get("tcp.port")
        original_http_dissector = Dissector.get("http")
        tcp_dissector_table:add(80, http_wrapper_proto)
        tcp_dissector_table:add(8888, http_wrapper_proto)
end
(04 Dec '16, 14:33) SYN-bit ♦♦
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:

×637
×431
×293
×78

question asked: 28 Nov '16, 15:02

question was seen: 1,325 times

last updated: 04 Dec '16, 14:33

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