Ethereal-dev: [Ethereal-dev] Changing tap code not to call "epan_dissect_run()" one more time?

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxx>
Date: Thu, 10 Oct 2002 17:31:08 -0700
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.