In "add_packet_to_packet_list()" in "file.c", we have code that does:
/* Dissect the frame. */
edt = epan_dissect_new(create_proto_tree, FALSE);
if (cf->dfcode != NULL && refilter) {
epan_dissect_prime_dfilter(edt, cf->dfcode);
}
if (filter_list) {
filter_list_prime_edt(edt);
}
epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
tap_push_tapped_queue();
and in "wtap_dispatch_cb_print()" in "tethereal.c", we have code that
does:
edt = epan_dissect_new(create_proto_tree, verbose);
if (cf->rfcode) {
epan_dissect_prime_dfilter(edt, cf->rfcode);
}
tap_queue_init(pseudo_header, buf, &fdata);
epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
tap_push_tapped_queue();
In "tap_push_tapped_queue()" we also call "epan_dissect_run()". That
means we run *two* dissections on the same packet.
Perhaps:
"tap_queue_init()" should return a Boolean indicating whether
there are any taps or not;
"add_packet_to_packet_list()" and "wtap_dispatch_cb_print()"
should set "create_proto_tree" to TRUE if there are any taps;
there should be a "tap.c" routine to do
/* loop over all tap listeners and build the list of all
interesting hf_fields */
for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
if(tl->code){
epan_dissect_prime_dfilter(edt, tl->code);
}
}
(i.e., the stuff done in "tap_push_tapped_queue()" before
calling "epan_dissect_run()") and that should be called by
"add_packet_to_packet_list()" and "wtap_dispatch_cb_print()"
before calling "epan_dissect_new()";
there should be a "tap.c" routine to do
/* loop over all tap listeners and call the listener callback
for all packets that match the filter. */
for(tp=tap_packet_list_queue;tp;tp=tp->next){
for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
if(tp->tap_id==tl->tap_id){
int passed=TRUE;
if(tl->code){
passed=dfilter_apply_edt(tl->code, edt);
}
if(passed && tl->packet){
tl->needs_redraw|=tl->packet(tl->tapdata, tp->pinfo, tp->tap_specific_data);
}
}
}
}
(i.e., the stuff done in "tap_push_tapped_queue()" after calling
"epan_dissect_run()") and that should be called by
"add_packet_to_packet_list()" and "wtap_dispatch_cb_print()"
after calling "epan_dissect_new()".
Those latter two routines, both of which would take an "epan_dissect_t
*" as an argument, would replace "tap_push_tapped_queue()".
This would also mean that "tap_queue_init()" wouldn't have to take the
pseudo_header, buffer, or frame_data pointers as arguments, and the
"l_pseudo_header", "l_buf", and "l_fdata" globals would disappear.