# Calling "mac-nr" dissector from LUA script results in an error

Hi,

My usecase is this.

1. I have a 5G-NR Layer1 to Layer2 Protocol like nFAPI that encapsulates the NR MAC payload such that (UDP->myFAPI->MAC PDU)
2. I wrote a LUA script to process this FAPI protocol and it works great.
3. Now I want to parse and print the contents of the MAC PDU .. and in the interest of not re-inventing the wheel i tried to use the existing "mac-nr" like so -> Dissector.get("mac-nr"):call(buffer(pktOffset):tvb(), pinfo, subtree)
4. Now I get an (expert) error saying "Can't dissect NR MAC frame because no per-frame info was attached!". i.e. the following snippet in -> packet-mac-nr.c -> dissect_mac_nr

/* Look for packet info! */ p_mac_nr_info = (mac_nr_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_nr, 0);

/* Can't dissect anything without it... */ if (p_mac_nr_info == NULL) { proto_tree_add_expert(mac_nr_tree, pinfo, &ei_mac_nr_no_per_frame_data, tvb, offset, -1); return 0; }

5. Upon inspection, it looks like i need to fill this packet info and set it in "pinfo" prior to calling "mac-nr" dissector..

6. Problem is, i dont know how to do this in LUA for the destination C dissector. And there does not seem to be any posts on this very specific issue (Forgive me if there is one.. and pls point me to it)
7. Had I written this dissector in C, I would have been able to do this seamlessly (I imagine).

So my question is.. can this be done via the LUA script ? If so how

Any help is appreciated and thanks in advance

edit retag close merge delete

Sort by » oldest newest most voted

Hi ... the solution to my particular problem is one of the following

1. Either write a LUA binding in C for the proto_data and extend the current "mac-nr" dissector

2. Or build a new custom tvb, in a way that the existing code expects it, as suggested by chuckc ... which seems the simpler thing to do.. to me

So I am going ahead with (2) and it seems to be working and i could atleast proceed with this for now...

And so I am thankful for the help. This is my first question and I am thankful it gave me a way forward. Thanks again chuckc

more

Why not pass it the pinfo that was passed into your dissector?

function p_multi.dissector(buf, pkt, tree)
...
if dissector ~= nil then
-- Dissector was found, invoke subdissector with a new Tvb,
-- created from the current buffer (skipping first two bytes).
dissector:call(buf(2):tvb(), pkt, tree)

function guacp_post.dissector(tvbuf, pinfo, tree)
...
guacp_dissector:call(guacp_tvb:tvb(), pinfo, tree)

more

Thanks for the reply. And yes I am passing the pinfo that was received by my dissector.

Like so

function my_protocol.dissector(buffer, pinfo, tree)
pktLength = buffer:len()
pktOffset = 0
nextFieldLen = 0
if pktLength == 0 then return end

pinfo.cols.protocol = my_protocol.name

PREVIOUS_FRAME_NUMBER = CURRENT_FRAME_NUMBER
CURRENT_FRAME_NUMBER = pinfo.number
reset_Frame_Level_Globals()

pktlen = buffer:reported_length_remaining()

local subtree = tree:add(my_protocol, buffer(), "My FAPI Protocol")

if parseMyFAPIMessage(buffer, pinfo, subtree) == false then return funcReturnHook() end
end


And the same pinfo is passed down to other sub functions until it reaches to the place where I call ->

Dissector.get("mac-nr"):call(buffer(pktOffset):tvb(), pinfo, subtree)


It appears to me that, inorder to call "mac-nr" dissector, the caller needs to fill extra information which is mandatory for the parsing of the MAC PDU contents... Like SFN, Slot numbers, i.e. the following C Structure

/* Context info attached to each NR MAC frame */
typedef struct ...
(more)
( 2022-07-08 17:48:12 +0000 )edit

Looks like the heuristic dissect_mac_nr_heur() will add the proto_data to the pinfo.
It's in the udp table.
You could try DissectorTable.try_heuristics(listname, tvb, pinfo, tree). ("MAC-NR over UDP" is disabled by default so would need to enable it)

( 2022-07-08 18:36:37 +0000 )edit

But I tried it and it did not work ... Then i checked the dissect_mac_nr_heur() function ... and I think it wont work because it looks for the information in places where my packet would not have them ...

For instance

/* If redissecting, use previous info struct (if available) */
p_mac_nr_info = (mac_nr_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_nr, 0);
if (p_mac_nr_info == NULL) {
/* Allocate new info struct for this frame */
p_mac_nr_info = wmem_new0(wmem_file_scope(), mac_nr_info);

p_mac_nr_info->direction = tvb_get_guint8(tvb, offset++);
p_mac_nr_info->rntiType = tvb_get_guint8(tvb, offset++);


radioType, direcion and rntiType are not in this order in my FAPI protocol no matter what offset we use ... So i think this heuristic parsing also will not help. And that I might need another way to fill this "info struct" in LUA while I am parsing the upper layer (FAPI) fields, and pass the filled (LUA table !?) data to the "mac-nr" C ...(more)

( 2022-07-08 18:53:21 +0000 )edit

I think you would have to write a Lua binding in C for the proto_data functions. Beyond me.

If you have the data available that the heuristic is looking for but in the wrong order, you could build a new custom tvb using11.8.1.16. bytearray:tvb(name) and place the data at the proper offsets. This is getting pretty far away from your original question.

( 2022-07-08 20:33:03 +0000 )edit

That's not a bad idea .. i will give that a try (i.e. to create a new TVB in the expected order)

( 2022-07-08 21:54:13 +0000 )edit