/* 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);
}
Esempio n. 2
0
union wtap_pseudo_header* CaptureFile::getPseudoHeader() {
    return wtap_pseudoheader(wth);
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/**
	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;
}