/* new packets arrived */ void capture_info_new_packets(int to_read) { int err; gchar *err_info; gint64 data_offset; const struct wtap_pkthdr *phdr; union wtap_pseudo_header *pseudo_header; int wtap_linktype; const guchar *buf; info_data.ui.new_packets = to_read; /*g_warning("new packets: %u", to_read);*/ while (to_read != 0 && (wtap_read(info_data.wtap, &err, &err_info, &data_offset))) { phdr = wtap_phdr(info_data.wtap); pseudo_header = wtap_pseudoheader(info_data.wtap); wtap_linktype = phdr->pkt_encap; buf = wtap_buf_ptr(info_data.wtap); capture_info_packet(&info_data.counts, wtap_linktype, buf, phdr->caplen, pseudo_header); /*g_warning("new packet");*/ to_read--; } capture_info_ui_update(&info_data.ui); }
union wtap_pseudo_header* CaptureFile::getPseudoHeader() { return wtap_pseudoheader(wth); }
/** * 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; }
int main(int argc, char *argv[]) { int opt; gboolean do_append = FALSE; gboolean verbose = FALSE; int in_file_count = 0; guint snaplen = 0; #ifdef PCAP_NG_DEFAULT int file_type = WTAP_FILE_PCAPNG; /* default to pcap format */ #else int file_type = WTAP_FILE_PCAP; /* default to pcapng format */ #endif int frame_type = -2; int out_fd; merge_in_file_t *in_files = NULL, *in_file; int i; struct wtap_pkthdr *phdr, snap_phdr; wtap_dumper *pdh; int open_err, read_err=0, write_err, close_err; gchar *err_info; int err_fileno; char *out_filename = NULL; gboolean got_read_error = FALSE, got_write_error = FALSE; int count; #ifdef _WIN32 arg_list_utf_16to8(argc, argv); #endif /* _WIN32 */ /* Process the options first */ while ((opt = getopt(argc, argv, "hvas:T:F:w:")) != -1) { switch (opt) { case 'w': out_filename = optarg; break; case 'a': do_append = !do_append; break; case 'T': frame_type = wtap_short_string_to_encap(optarg); if (frame_type < 0) { fprintf(stderr, "mergecap: \"%s\" isn't a valid encapsulation type\n", optarg); list_encap_types(); exit(1); } break; case 'F': file_type = wtap_short_string_to_file_type(optarg); if (file_type < 0) { fprintf(stderr, "mergecap: \"%s\" isn't a valid capture file type\n", optarg); list_capture_types(); exit(1); } break; case 'v': verbose = TRUE; break; case 's': snaplen = get_positive_int(optarg, "snapshot length"); break; case 'h': usage(); exit(0); break; case '?': /* Bad options if GNU getopt */ switch(optopt) { case'F': list_capture_types(); break; case'T': list_encap_types(); break; default: usage(); } exit(1); break; } } /* check for proper args; at a minimum, must have an output * filename and one input file */ in_file_count = argc - optind; if (!out_filename) { fprintf(stderr, "mergecap: an output filename must be set with -w\n"); fprintf(stderr, " run with -h for help\n"); return 1; } if (in_file_count < 1) { fprintf(stderr, "mergecap: No input files were specified\n"); return 1; } /* open the input files */ if (!merge_open_in_files(in_file_count, &argv[optind], &in_files, &open_err, &err_info, &err_fileno)) { fprintf(stderr, "mergecap: Can't open %s: %s\n", argv[optind + err_fileno], wtap_strerror(open_err)); switch (open_err) { case WTAP_ERR_UNSUPPORTED: case WTAP_ERR_UNSUPPORTED_ENCAP: case WTAP_ERR_BAD_FILE: fprintf(stderr, "(%s)\n", err_info); g_free(err_info); break; } return 2; } if (verbose) { for (i = 0; i < in_file_count; i++) fprintf(stderr, "mergecap: %s is type %s.\n", argv[optind + i], wtap_file_type_string(wtap_file_type(in_files[i].wth))); } if (snaplen == 0) { /* * Snapshot length not specified - default to the maximum of the * snapshot lengths of the input files. */ snaplen = merge_max_snapshot_length(in_file_count, in_files); } /* set the outfile frame type */ if (frame_type == -2) { /* * Default to the appropriate frame type for the input files. */ frame_type = merge_select_frame_type(in_file_count, in_files); if (verbose) { if (frame_type == WTAP_ENCAP_PER_PACKET) { /* * Find out why we had to choose WTAP_ENCAP_PER_PACKET. */ int first_frame_type, this_frame_type; first_frame_type = wtap_file_encap(in_files[0].wth); for (i = 1; i < in_file_count; i++) { this_frame_type = wtap_file_encap(in_files[i].wth); if (first_frame_type != this_frame_type) { fprintf(stderr, "mergecap: multiple frame encapsulation types detected\n"); fprintf(stderr, " defaulting to WTAP_ENCAP_PER_PACKET\n"); fprintf(stderr, " %s had type %s (%s)\n", in_files[0].filename, wtap_encap_string(first_frame_type), wtap_encap_short_string(first_frame_type)); fprintf(stderr, " %s had type %s (%s)\n", in_files[i].filename, wtap_encap_string(this_frame_type), wtap_encap_short_string(this_frame_type)); break; } } } fprintf(stderr, "mergecap: selected frame_type %s (%s)\n", wtap_encap_string(frame_type), wtap_encap_short_string(frame_type)); } } /* open the outfile */ if (strncmp(out_filename, "-", 2) == 0) { /* use stdout as the outfile */ out_fd = 1 /*stdout*/; } else { /* open the outfile */ out_fd = ws_open(out_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (out_fd == -1) { fprintf(stderr, "mergecap: Couldn't open output file %s: %s\n", out_filename, g_strerror(errno)); exit(1); } } /* prepare the outfile */ pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, FALSE /* compressed */, &open_err); if (pdh == NULL) { merge_close_in_files(in_file_count, in_files); g_free(in_files); fprintf(stderr, "mergecap: Can't open or create %s: %s\n", out_filename, wtap_strerror(open_err)); exit(1); } /* do the merge (or append) */ count = 1; for (;;) { if (do_append) in_file = merge_append_read_packet(in_file_count, in_files, &read_err, &err_info); else in_file = merge_read_packet(in_file_count, in_files, &read_err, &err_info); if (in_file == NULL) { /* EOF */ break; } if (read_err != 0) { /* I/O error reading from in_file */ got_read_error = TRUE; break; } if (verbose) fprintf(stderr, "Record: %u\n", count++); /* We simply write it, perhaps after truncating it; we could do other * things, like modify it. */ phdr = wtap_phdr(in_file->wth); if (snaplen != 0 && phdr->caplen > snaplen) { snap_phdr = *phdr; snap_phdr.caplen = snaplen; phdr = &snap_phdr; } if (!wtap_dump(pdh, phdr, wtap_pseudoheader(in_file->wth), wtap_buf_ptr(in_file->wth), &write_err)) { got_write_error = TRUE; break; } } merge_close_in_files(in_file_count, in_files); if (!got_read_error && !got_write_error) { if (!wtap_dump_close(pdh, &write_err)) got_write_error = TRUE; } else wtap_dump_close(pdh, &close_err); if (got_read_error) { /* * Find the file on which we got the error, and report the error. */ for (i = 0; i < in_file_count; i++) { if (in_files[i].state == GOT_ERROR) { fprintf(stderr, "mergecap: Error reading %s: %s\n", in_files[i].filename, wtap_strerror(read_err)); switch (read_err) { case WTAP_ERR_UNSUPPORTED: case WTAP_ERR_UNSUPPORTED_ENCAP: case WTAP_ERR_BAD_FILE: fprintf(stderr, "(%s)\n", err_info); g_free(err_info); break; } } } } if (got_write_error) { switch (write_err) { case WTAP_ERR_UNSUPPORTED_ENCAP: /* * This is a problem with the particular frame we're writing; * note that, and give the frame number. */ fprintf(stderr, "mergecap: Frame %u of \"%s\" has a network type that can't be saved in a file with that format\n.", in_file->packet_num, in_file->filename); break; default: fprintf(stderr, "mergecap: Error writing to outfile: %s\n", wtap_strerror(write_err)); break; } } g_free(in_files); return (!got_read_error && !got_write_error) ? 0 : 2; }
/** 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; }