> It is my first contact with the ethereal sourcecode and I was a little bit
> confused by old/new dissectors. Looking at sources packet-*.c, I recognised
> several different "flavours" of calling the next dissector. Calling the
> BLVC-dissector was easy (udp.port == 47808), but the BACnet-dissector isn't
> (bvlc.function == 0x0b).
The names of "dissector tables" are often the same as the names of
registered fields in dissector - but that's by convention; if you
register a field named "bvlc.function", that doesn't automatically
create a dissector table named "bvlc.function", and there may also be
dissector tables for which there are no corresponding fields (such as,
for example, the "ethertype" dissector table - the Ethernet type field,
the PID field in SNAP-encapsulated LLC packets, and some other fields
all contain Ethernet type values, and are all used to switch through the
"ethertype" dissector table).
The BVLC dissector would have to register, in its "proto_register"
routine, a dissector table, by doing:
static dissector_table_t bvlc_dissector_table;
...
void
proto_register_bvlc(void)
{
...
proto_bvlc = proto_register_protocol("BACnet Virtual Link Control",
"BVLC", "bvlc");
proto_register_field_array(proto_bvlc, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("bvlc", dissect_bvlc, proto_bvlc);
/* subdissector code */
bvlc_dissector_table = register_dissector_table("bvlc.function");
}
Then, instead of
next_tvb = tvb_new_subset(tvb,offset+4,-1,npdu_length);
dissect_bacnet(next_tvb, pinfo, tree);
you'd do
next_tvb = tvb_new_subset(tvb,offset+4,-1,npdu_length);
if (!dissector_try_port(bvlc_dissector_table, function, next_tvb,
pinfo, tree) {
/* Unknown function - dissect the paylod as data */
dissect_data(next_tvb, 0, pinfo, tree);
}
where "function" would be a variable set to the value of the "function"
field in the BVLC packet.