Ask Your Question

lua dissector, need to set pinfo.in_error_pkt but cannot

asked 2023-06-07 11:03:31 +0000

Hi! I am writing a dissector (so far all is good) but now I am hitting a snag.

At a certain offset my protocol contains an IP header as part of its payload. Just the IP header (20 bytes, starts with x'45'...). My payload then continues with other data not related to the IP header.

Similar in a fashion to ICMP, for example, which will provide the errant IP header as part of its error report.

Simply calling the "ip" dissector works, but the header is colored red and expert reports length discrepancies.

In the epan/dissectors/icmp.c I can see how they make sure that the dissection of ONLY the IP header is requested: They set the pinfo.in_error_pkt flag.

My attempts to do that in my .lua dissector fail because for some reason, pinfo.in_error_pkt is "Retrieve only". I cannot set it.

Here is a code snippet showing what I want to do:

    temp = pinfo.in_error_pkt
    pinfo.in_error_pkt = true -- THIS LINE FAILS
    Dissector.get("ip"):call(buffer(some_offset, 20):tvb(), pinfo, tree)
    pinfo.in_error_pkt = temp
edit retag flag offensive close merge delete


2 Answers

Sort by ยป oldest newest most voted

answered 2023-06-07 11:50:31 +0000

Chuckc gravatar image

(Cloudflare not accepting links in comments - again - ugh. This may not be the final answer.)


/* WSLUA_ATTRIBUTE Pinfo_in_error_pkt RO If we're inside an error packet. */

Yep, definitely read-only.
Can you copy the bytes to another TVB then call the ip dissector on that?

edit flag offensive delete link more


I tried copying the tvbrange out to a bytearray, and using that bytearray as :tvb calling the ip dissector:

        local ipheader = buffer:bytes(some_offset, header_len)
    local iptvb = ipheader:tvb("IP Header")
    subtree:add(iptvb(0, -1), "foo")
    Dissector.get("ip"):call(iptvb(0, -1):tvb(), pinfo, tree)

I can see the "foo" tab (I made this for debug purpose) has the right 20 bytes, but the ip header dissection is once again complaining about the total length being higher (in this case 48) than the actual length ( = 20). The ip dissector wants to continue onwards with a tcp dissector, which of course is not provided.

FanDjango gravatar imageFanDjango ( 2023-06-07 12:18:58 +0000 )edit

What if you fudge/correct the ip.len bytes in the copied TVB to be 20?

Chuckc gravatar imageChuckc ( 2023-06-07 12:31:12 +0000 )edit

Har har, I thought of that and tried it.

ipheader:set_index(3, 20)

That actually fixes the length error.

But of course, the dissector now outputs an "untruth" in the length field. And the length is not always twenty, I would need to check for options present and IPv6, and so on and on.

FanDjango gravatar imageFanDjango ( 2023-06-07 12:39:27 +0000 )edit

You could go the other way and pad the TVB with bogus TCP header/payload but that might be getting off in the weeds.

Chuckc gravatar imageChuckc ( 2023-06-07 13:22:54 +0000 )edit

Bit of a drag, yes, especially when the IP header sometimes contains a jumbo frame length.

I am surprised that no one has come up with this kind of "embedded" use of an internal dissector before in lua. What is the technical reason for the read-only on that pinfo flag? Hmmm.

FanDjango gravatar imageFanDjango ( 2023-06-07 13:32:36 +0000 )edit

answered 2023-06-22 12:53:36 +0000 addresses this, I have tested the branch and it works.

Not only for IP headers, by the way, also for TCP headers that I also need to dissect.

Very happy to confirm that using this pinfo flag will do the trick. At some point in time it will be merged, I suppose, and then released.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2023-06-07 11:03:31 +0000

Seen: 168 times

Last updated: Jun 22 '23