/** * Given a handle on a capture file, and an offset within that file, * this function will read a packet and decide if it matches the display * filter. If it does, it calls proto_tree_get_fields() to read specific fields * into stdata. * * @return passed a boolean describing whether the packet matched the filter. */ gboolean process_packet(capture_file *cf, gint64 offset, st_data_t *stdata) { frame_data fdata; epan_dissect_t edt; gboolean passed; const struct wtap_pkthdr *whdr = wtap_phdr(cf->wth); union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth); const guchar *pd = wtap_buf_ptr(cf->wth); /* Count this packet. NB: the frame dissector uses this to determine frame.number */ cf->count++; /** * Initialize dissector tree */ epan_dissect_init(&edt, TRUE, TRUE); frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes); frame_data_set_before_dissect(&fdata, &cf->elapsed_time, &first_ts, &prev_dis_ts, &prev_cap_ts); passed = TRUE; // AB: prime the epan_dissect_t with the dfilter. if(cf->rfcode) { epan_dissect_prime_dfilter(&edt, cf->rfcode); } tap_queue_init(&edt); /** * Run the dissector on this packet */ epan_dissect_run(&edt, pseudo_header, pd, &fdata, NULL); tap_push_tapped_queue(&edt); // AB: Run the read filter if(cf->rfcode) { passed = dfilter_apply_edt(cf->rfcode, &edt); } else { passed = TRUE; } if(passed) { frame_data_set_after_dissect(&fdata, &cum_bytes, &prev_dis_ts); // stdata could be NULL if we are just counting packets if(stdata != NULL) proto_tree_get_fields(stdata, &edt); } epan_dissect_cleanup(&edt); frame_data_cleanup(&fdata); return passed; }
/** Does the dissection of one packet. @param in_data raw binary data of the packet to be processed @param mode specifies the debug mode @return dissected packet payload in a form of hf_datanode tree if everything went OK, NULL otherwise */ extern "C" __declspec(dllexport) hf_datanode *hf_dissect_one_packet(unsigned char *in_data, int mode) { epan_dissect_t *pedt; frame_data *fdata = g_slice_new(frame_data); int count = 0; nstime_t elapsed_time; elapsed_time.secs = 0; elapsed_time.nsecs = 100; name_number = 1; if(mode==DEBUG_MODE) { printf("DEBUG mode on.\n"); debug_mode = mode; } if(fdata==NULL) return NULL; // create a wiretap header wrapper around the data wtap *wth; wth = hf_create_fakewth(in_data); // this should happen only if we run out of memory! if(wth==NULL) return NULL; // initilaize the values for fake time measurement hf_init_timestructs(); // disecton process begins // initialiation phase...set up the frame and dissection structures frame_data_init(fdata,count,wtap_phdr(wth),wth->data_offset,cum_bytes); pedt = epan_dissect_new(TRUE,TRUE); frame_data_set_before_dissect(fdata,&(elapsed_time),&first_ts,&prev_dis_ts,&prev_cap_ts); // the core of the dissection epan_dissect_run(pedt,wtap_pseudoheader(wth),wtap_buf_ptr(wth),fdata,NULL); // cleanup after the dissection frame_data_set_after_dissect(fdata,&cum_bytes,&prev_dis_ts); // transform the dissected data to the form of a hf_datanode tree hf_datanode * returned_node = hf_transform_ptree_to_datamodel(pedt); // free the one-packet dissection structure epan_dissect_t epan_dissect_free(pedt); // disecton process ends // deallocation phase g_slice_free(frame_data, fdata); buffer_free(wth->frame_buffer); g_free(wth->frame_buffer); g_free(wth->capture.pcap); g_free(wth); hf_datanode *returned_payload = hf_return_only_payload(returned_node); // fragmented packet or dissection failure should be noted if(mode==DEBUG_MODE) { if(!returned_payload) fprintf(stderr, "Dissection returned NULL - either fragmented message or protocol unknown.\n"); } // print the part that will be returned from the function after the duplicates were skipped etc. if(debug_mode==DEBUG_MODE) { hf_print_datamodel(returned_payload,1,1); } // if we were in debug mode, switch it off debug_mode = NODEBUG_MODE; return returned_payload; }