Heuristic Dissector is never called
Hello! I was trying to write a dissector for a custom protocol. The supposed protocol has a specific sync word so I tried to make my dissector be port-agnostic that simply searches for the specified word in the beginning of the header.
Here's a sketch of the code:
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *foo_proto_tree, void* data){
// build protocol tree...
}
static gboolean
frame_sync_test_foo(tvbuff_t *tvb)
{
if (tvb_strncaseeql(tvb, UDP_OFFSET, "FOOBAR", 6) == 0) {
return TRUE;
}
return FALSE;
}
static gboolean
dissect_foo_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
if ( !frame_sync_test_foo(tvb) ) {
return FALSE;
}
dissect_foo(tvb, pinfo, tree, data);
return TRUE;
}
void
proto_reg_handoff_foo(void)
{
static dissector_handle_t foo_handle;
foo_handle = create_dissector_handle(dissect_foo, proto_foo);
register_dissector("FOO", dissect_foo, proto_foo);
heur_dissector_add("udp", dissect_foo_heur, "FOO (UDP)", "foo_udp", proto_foo, HEURISTIC_ENABLE);
}
void proto_register_foo(void)
{
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_foo,
&ett_foo_primary_hdr,
&ett_foo_secondary_hdr
};
// set-up header files...
proto_foo = proto_register_protocol("FOO", "FOOBAR", "foo");
proto_register_field_array(proto_foo, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
After compiling, my protocol is registered as expected (meaning that I can see my protocol in the list of available protocols and its hash table contains all the fields I set up), but I couldn't dissect any packet. I generated a few UDP packets and while I'd expect the UDP payload to be dissected according to my protocol (granted its first few bytes match the ones of the sync word), I don't get anything (note that I have the Try heuristic dissectors first option enabled).
Also what perplexes me even more, is the fact that dissect_foo_heur
is never called, which I don't find to be reasonable since the UDP payload doesn't match with any other dissector. That means that Wireshark doesn't ever consider checking my dissector when receiving a UDP packet.
Is there anything wrong with my code or am I misunderstanding something in the way that heuristic dissectors are supposed to work (sorry for the noob question :P)
Does your dissector show up in the udp heuristic table? Look in View -> Internal -> Dissector Tables and search for udp. Does the data show up as "data" under udp indicating that the default data dissector has been called?
For your first question the answer is yes, it shows up as expected. I'm not sure I got your second question though. I can see the header of the UDP packet, but the packet I actually sent simply shows up as UDP Payload.
If the udp dissector can't find either a port configured dissector or a heuristic one that will handle the payload, it's handed off to the generic "data" dissector. See the wiki page for the "data" protocol.
Sure but if I understand correctly, when receiving a chunk of "data", Wireshark tries to find a suitable sub-dissector and it cycles through all the "candidate dissector". Problem is,
dissect_foo_heur
isn't ever called, despite my data simply being labeled simply as "UDP Payload"As you note, this doesn't appear to be happening for your dissector, I'm trying to find out what is happening.
Personally I would fire up the debugger and look in packet-udp where it attempts to hand off the data to sub-dissectors.