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

How does dissector_add work?

0

Hi, I'm a newbie trying to write a dissector for the first time. I've noticed the function dissector_add() gets called to associate a particular identifier with a dissector handle.

If I call dissector_add() twice for the same handle does it "and" these two identifiers or "or" them?

What do I do if I want my dissector to match a combination of "and"s and "or"s, like an expression like this might indicate?: "((host 1.2.3.4 and port 111) or (host 5.6.7.8 and port 222))"

asked 05 Oct '11, 12:47

JVo's gravatar image

JVo
16558
accept rate: 0%

edited 05 Oct '11, 16:40

multipleinterfaces's gravatar image

multipleinte...
1.3k152340


One Answer:

3

dissector_add is really just a #defined alias for dissector_add_uint, so if you are using dissector_add you should change it to dissector_add_uint. That said, when you call dissector_add_uint("foo", BAR_PORT, bar_handle);, it adds the dissector referenced by bar_handle to the dissector table referenced by foo for the uint value BAR_PORT.

To answer your question, it would be more like a logical or operation. Consider adding a dissector to the udp.port table twice using 1337 and 31337 as your ports --when the UDP dissector looks into its table for traffic on either of those ports, your dissector would be called. Note that hueristic dissectors work a little differently. dissector_add_uint is declared in epan/packet.h, so you should read some of the comments there about how the functions work and are intended to be used.

Edit: Regarding your comments, 1337 and 31337 were example ports; in your example, these would be 111 and 222.

Regarding the IP address, there are no dissector tables tied to particular IP addresses. Network protocols are generic and typically understood by more than one machine, and maintaining large lists of IPs would become cumbersome (and practically infeasable) over time. In stead, you can limit the packets you see with a display filter so that only hosts 1.2.3.4 and 5.6.7.8 are shown (ip.addr == 1.2.3.4 || ip.addr == 5.6.7.8).

You can find more information in the Wireshark Developer's Guide. Comments in the various source files (.c) typically concern implementation details that are subject to change or specific workarounds. Usually, you should hope to find the information you need in the header files, as these expose the interface as it is intended (and are usually easier to follow).

answered 05 Oct '11, 13:05

multipleinterfaces's gravatar image

multipleinte...
1.3k152340
accept rate: 12%

edited 05 Oct '11, 14:12

Thanks so much for the quick response.

So, are "1337" and "31337" just example port numbers? In my example that would be "111" and "222", right?

Sorry for my confusion but how would I handle the host IP addresses as well, like in my example? "((host 1.2.3.4 and port 111) or (host 5.6.7.8 and port 222))"

Because I don't want to match tcp port 111 on every IP address, just that one. How do I deal with a "logical and" expression?

(05 Oct '11, 13:38) JVo

Sorry for my very little understanding of this - I'm just not sure where to go to learn about dissector tables. There don't seem to be many detailed comments in packet.h. Is my best bet to try to read the code itself in packet.c?

Thanks again!

(05 Oct '11, 13:39) JVo

I've updated my answer with some more information. The comments in the header files are usually the ones to go by, though they can be daunting at first. Make sure you understand the relevant portions of the Developer's Guide and have read doc/README.developer. You can also find information on the wiki: http://wiki.wireshark.org/

(05 Oct '11, 14:14) multipleinte...

Thanks for the update.

Regarding the IP addresses: I suppose generally the port number for our protocol should be unique to messages of this protocol.

If, in the off chance, another message arrives with the same port number (from a different IP), I'm not sure what I'll do. Preventing it from being displayed by using the display filter isn't really what I'd want. I still want to display all messages, whether or not they are one of my protocol messages. Any other thoughts? I may just have to make the assumption that any message with this port number is of this protocol.

(05 Oct '11, 16:14) JVo

Do you know if it's possible to tie a dissector to a particular ethernet capture device such as eth0, eth1, etc?

(05 Oct '11, 16:16) JVo

I suppose there isn't a way in the dissect_foo() method to say "nevermind, this isn't a foo after all", is there? :o) (Sorry for the 20 questions)

(05 Oct '11, 16:19) JVo

You cannot tie your dissector to a specific capture interface (other than by only capturing on that interface) since this information is not provided to dissectors. Regarding your other questions, what you are looking for is a "hueristic dissector". You should look at doc/README.heuristic for information about how to convert your current dissector into a hueristic dissector and what changes you may need to make otherwise. If you go this route, also make sure that your transport protocol's try_heuristic_dissectors_first preference is enabled.

(05 Oct '11, 16:30) multipleinte...

I'll take a look at README.heuristic. Thanks!

(05 Oct '11, 16:52) JVo

Wireshark dissectors works in a similar way as the protocol stack does if your protocol runs on top of TCP/UDP the handoff would be to something listening to that port. (dissector registered in tcp and udp uint dissector tables in the case of Wireshark) When capturing you can use capture filters to only capture packets to from IP addresses and ports the interface yo capture on will be the ETH "selector". If your protocol has a magic number or a unique signature you can make it an heuristic dissector.

(07 Oct '11, 10:14) Anders ♦

The heuristic dissector idea looks promising in that I can check the IP addresses, and return FALSE if they don't match. However, can I use a heuristic dissector in combination with tcp_dissect_pdus()? I have 2 methods: tcp_dissect_foo() and tcp_dissect_foo_message(). tcp_dissect_foo() calls tcp_dissect_pdus(), which sets tcp_dissect_foo_message() to be called once the full message is received. If I make this a heuristic dissector and check my IPs in tcp_dissect_foo_message(), returning false if they don't match, will wireshark do the right thing and pass the message on to other dissectors?

(07 Oct '11, 10:51) JVo

Oh wait. Now that I think about it, I can check the IPs from tcp_dissect_foo() and return false if they don't match. If they do match, I could call tcp_dissect_pdus(). On the other hand, what if I wanted to check bytes in the message to verify that it was a "foo"? It seems like I would want to check those bytes in the full message, not in some random packet of the message. Thus, wouldn't I want to check them in tcp_dissect_foo_message() and return FALSE from there?

(07 Oct '11, 11:21) JVo

tcp_dissect_pdus() expects packets of a particular protocol, as it has to be able to figure out how big each packet is, and how that's done is protocol-dependent (for example, one protocol might have a 2-byte big-endian length field at the beginning of the packet whose value that includes the length of the length field, another might have a 4-byte little-endian length field 2 bytes into the packet whose value does not include the length of the length field). This makes it difficult to support having tcp_dissect_pdus() call heuristic dissectors, and it does not support that.

(07 Oct '11, 13:25) Guy Harris ♦♦
showing 5 of 12 show 7 more comments