# How can I call one dissector from another

Hi, ALL, This is my first post so please be gentle. ;-)

1) Could someone point me to the official documentation that will explain the parameters of tvb_new_subset()/tvb_new_subset_length_caplen()?

Problem:

I'm trying to daisy-chain 2 dissectors. Both are written by our group. First one is successfully perform what needs to be done.

The size of the message is 3 bytes - first one is message type and then 2 bytes of data length that follow. The length of the data is successfully retrieved in the variable msg_len.

So I called:

next_tvb = tvb_new_subset( tvb, 3, msg_len, msg_len );


but this call will simply return from the parsing function and will not do anything.

If I try to call:

next_tvb = tvb_new_subset( tvb, 3, -1, -1 );


it succeeds.

However, I'm not sure that the second call is correct and that I wil get a proper data for the packet/message.

2) Consider following scenario:

new_tvb = tvb_new_subset();
// pass the data to second dissector
if( !!handle )
handle = find_dissector();
if( handle )
call_dissector( handle, next_tvb, pinfo, tree );


I presume that call_dissector() will call the dissect_XXX() function from the second dissector.

However, this is not the case.

Trying to set a breakpoint at that function - it never hit.

So what function will be called when executing call_dissector() API? Again - link to the official Wireshark documentation would be nice.

I'm looking for an official documentation or any official (meaning from the Wireshark site, and not 3rd party) references.

As you can see the dissectors are written in C and so I am looking for some guidance.

Thank you.

edit retag close merge delete

Sort by » oldest newest most voted

The "official" documentation is in the code so "use the source Luke", e.g. tvbuff.h where the comments will guide you. You can also look at README.dissector, Section 1.7 "Calling other dissectors".

In the current development branch there is no function tvb_new_subset(), so it appears that you're working with older code, can you specify which version?

The parameters for tvb_new_subset_length_caplen() are in the header comment. As can be seen in the comments for the subsequent functions, tvb_new_subset_length() and tvb_new_subset_remaining() the backing_length and reported_length arguments can be set to -1 to consume the rest of the source buffer.

For your 2nd query, have you put a breakpoint in the dissector making the call_dissector() call to see what it's doing, e.g. find_handle() might be returning null.

There are may examples of producing a subset tvb to hand off to another dissector, e.g. packet-udp.c in the function decode_udp_ports().

more

[quote] The "official" documentation is in the code [/quote]

That sucks!! That sucks big time!!

If I'm writing a dissector and want to quicly check what the function does it is much easier to go get it from the web or a text document. Why it is not there in the first place? IDK.

Well then it is very weird. The first call should have been succeed just as well as the second call. Because there is nothing after the byte msg_len.

I can use "-1" I guess, but it seems overproductive.

[quote] For your 2nd query, have you put a breakpoint in the dissector making the call_dissector() call to see what it's doing, e.g. find_handle() might be returning null. [/quote] As you can see from the code I posted, the handle can't be NULL And the code does go to ...(more)

( 2021-03-25 19:09:19 +0000 )edit

@grahamb, One more thing - I just looked at the tvbuff.h

** Create a tvbuff that's a subset of another tvbuff.
*
* 'backing_offset', if positive, is the offset from the beginning of
* the backing tvbuff at which the new tvbuff's data begins, and, if
* negative, is the offset from the end of the backing tvbuff at which
* the new tvbuff's data begins.
*


It does not say anything about whether it is 0- or 1-bawsed.

Those little details are very important and should be mentioned somewhere in the documentation, not in the comment of the source code.

And this is just one example.

Thank you.

( 2021-03-25 20:20:55 +0000 )edit

@grahamb, Also, I just grab the latest sources hoping to analyze the call_dissector() call

But running:

grep -ri "call_dissector *


I see too many instances of it and can't pick up where the function code itself is located.

Can you help?

Thank you.

( 2021-03-25 21:07:09 +0000 )edit

re. documentation, it is what it is. Feel free to spend your time creating extensive documentation for free for others if you so wish. Most IDE's will show preceding comments in tooltips when hovering over a function in your code.

For the tvb_new_subset_xxx() functions, the backing_offset is as described in the comment excerpt you displayed. 0 is a positive value, and indicates the subset is to begin at the start of the source tvb.

For backing_length, there is a comment explaining the values:

* 'backing_length' is the length of the data to include in the new
* tvbuff, starting with the byte at 'backing_offset"; if -1, it
* means "to the end of the backing tvbuff".  It can be 0, although
* the usefulness of the buffer would be rather limited.


For reported_length there is no direct comment, maybe you could submit a patch to correct that, but the comment for the simplest ...(more)

( 2021-03-26 09:26:49 +0000 )edit
re. documentation, it is what it is. Feel free to spend your time creating extensive documentation for free for others if you so wish. Most IDE's will show preceding comments in tooltips when hovering over a function in your code.


As you said it yourself - most IDEs. Besides - all this is just a comments in the code and not a documentation.

For the tvb_new_subset_xxx() functions, the backing_offset is as described in the comment excerpt you displayed. 0 is a positive value, and indicates the subset is to begin at the start of the source tvb.

For backing_length, there is a comment explaining the values:

* 'backing_length' is the length of the data to include in the new
* tvbuff, starting with the byte at 'backing_offset"; if -1, it
* means "to the end of the backing tvbuff".  It can be 0, although
* the usefulness of the buffer would be rather limited ...
(more)
( 2021-03-26 16:20:35 +0000 )edit

@grahamb, Also, what about the code for the call_dissector() function? As I said - simple grep won't work because the retuirn type and the function name are on a different lines.

Thank you.

P.S.: BTW, the properties for the second dissector set the port number as default one for when this dissector is used without any additional protocol. And its wrong? Can it be the reason for the second dissector not being called?

( 2021-03-26 16:24:41 +0000 )edit

For backing_offset the concept of 0 based doesn't really hold here, as it can be negative which starts from the other end of the backing (or source) tvb. A value of zero will start from the beginning of the backing tvb as implied in the comment:

 * 'backing_offset', if positive, is the offset from the beginning of
* the backing tvbuff at which the new tvbuff's data begins


I didn't realise you were looking for the definition of call_dissector() itself, that's in epan/packet.c. Generally all "common" dissection stuff is in epan, specific protocol stuff is in epan/dissectors.

I don't really have any idea why the second dissector isn't being called, but I suspect the find_dissector() might be failing. If you can get a handle to it, you can call it.

( 2021-03-26 16:52:23 +0000 )edit

Then you for providing the file name!

Looking at the source code I see that the function call_dissector() return "int" and not "void"

So I added the return value to be stored in some temporary variable and to my surprise I got some very weird results.

call_dissector() -> call_dissector_with_data() call_dissector_with_data() -> call_dissector_only()

Now call_dissector_only either returns 0 or the captured data length.

Since my temporary variable didn't get a 0, (I actually got 101, but that's different story) - I kept looking.

call_dissector_only -> call_dissector_work(), where the only way it returns 0 is if the call to proto_is_protocol_enabled( handle->protocol ) will fail.

Keep in mind that all this is deduced by just looking at the code of the latest version.

I, in fact, have a WS version 1.10.14 on RHEL7, but I hope that this code didn't change (much).

Therefore I think I need to somehow ...(more)

( 2021-03-26 21:20:41 +0000 )edit

So is there a difference for registering the dissector for call to "call_dissector()" and when I use the dissector directly?

( 2021-03-29 17:16:05 +0000 )edit