Ask Your Question
0

How can I call one dissector from another

asked 2021-03-25 18:01:50 +0000

oneeyeman gravatar image

updated 2021-03-29 19:13:06 +0000

grahamb gravatar image

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 flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2021-03-25 18:32:50 +0000

grahamb gravatar image

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().

edit flag offensive delete link more

Comments

@grahamb, Thx for the reply.

[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)

oneeyeman gravatar imageoneeyeman ( 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.

oneeyeman gravatar imageoneeyeman ( 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.

oneeyeman gravatar imageoneeyeman ( 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)

grahamb gravatar imagegrahamb ( 2021-03-26 09:26:49 +0000 )edit

@grahamb,

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)
oneeyeman gravatar imageoneeyeman ( 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?

oneeyeman gravatar imageoneeyeman ( 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.

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

@grahamb,

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)

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

@grahamb,

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

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

Unfortunately I think this area has changed since the 1.10 codebase and I'm not an archaeologist. Again I can only suggest you look at other examples in the codebase as it obviously works for all the other dissectors.

Note that when a dissector calls another dissector, the former knows about the latter mostly because the latter has registered with the former in some way, e.g. via a port table. Sect .17 of README.dissector has the final paragraph:

To call a dissector you need to get the handle of the dissector using find_dissector(), passing it the string name of the dissector. The setting of the handle is usually done once at startup during the proto_reg_handoff function within the calling dissector.

You can also call the "dissection" function of another dissector directly if the target dissector makes it available, usually via a header file, e.g. packet-xxx.h ...(more)

grahamb gravatar imagegrahamb ( 2021-03-29 18:02:43 +0000 )edit

@grahamb,

Yes, I think I got that deduced from the flow I pointed in my previous reply. What I'd like to know is - how do I regsiter it? What I should call to do that?

Thank you.

P.S.: I will try to dig in the documentation thru the source code, but I just need to find how to register.

oneeyeman gravatar imageoneeyeman ( 2021-03-29 18:58:38 +0000 )edit

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

Stats

Asked: 2021-03-25 18:01:50 +0000

Seen: 138 times

Last updated: Mar 29