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.

Reply via email to