Ejemplo n.º 1
0
/* new packets arrived */
void capture_info_new_packets(int to_read)
{
    int err;
    gchar *err_info;
    gint64 data_offset;
    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_cleareof(info_data.wtap);
        if (wtap_read(info_data.wtap, &err, &err_info, &data_offset)) {
            phdr = wtap_phdr(info_data.wtap);
            pseudo_header = &phdr->pseudo_header;
            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);
}
Ejemplo n.º 2
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);
  create_app_running_mutex();
#endif /* _WIN32 */

  /* Process the options first */
  while ((opt = getopt(argc, argv, "aF:hs:T:vw:")) != -1) {

    switch (opt) {
    case 'a':
      do_append = !do_append;
      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 'h':
      usage();
      exit(0);
      break;

    case 's':
      snaplen = get_positive_int(optarg, "snapshot length");
      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 'v':
      verbose = TRUE;
      break;

    case 'w':
      out_filename = optarg;
      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 */
  if(file_type == WTAP_FILE_PCAPNG ){
    wtapng_section_t *shb_hdr;
    GString *comment_gstr;

    shb_hdr = g_new(wtapng_section_t,1);
    comment_gstr = g_string_new("File created by merging: \n");

    for (i = 0; i < in_file_count; i++) {
      g_string_append_printf(comment_gstr, "File%d: %s \n",i+1,in_files[i].filename);
    }
    shb_hdr->section_length = -1;
    /* options */
    shb_hdr->opt_comment   = comment_gstr->str; /* NULL if not available */
    shb_hdr->shb_hardware  = NULL;              /* NULL if not available, UTF-8 string containing the description of the hardware used to create this section. */
    shb_hdr->shb_os        = NULL;              /* NULL if not available, UTF-8 string containing the name of the operating system used to create this section. */
    shb_hdr->shb_user_appl = "mergecap";        /* NULL if not available, UTF-8 string containing the name of the application used to create this section. */

    pdh = wtap_dump_fdopen_ng(out_fd, file_type, frame_type, snaplen,
                              FALSE /* compressed */, shb_hdr, NULL /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
    g_string_free(comment_gstr, TRUE);
  } else {
    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_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;
}
Ejemplo n.º 3
0
const guchar* CaptureFile::getPd() {
    return wtap_buf_ptr(wth);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/*
 * Merges the files based on given input, and invokes callback during
 * execution. Returns MERGE_OK on success, or a MERGE_ERR_XXX on failure; note
 * that the passed-in 'err' variable will be more specific to what failed, and
 * err_info will have pretty output.
 */
merge_result
merge_files(int out_fd, const gchar* out_filename, const int file_type,
            const char *const *in_filenames, const guint in_file_count,
            const gboolean do_append, const idb_merge_mode mode,
            guint snaplen, const gchar *app_name, merge_progress_callback_t* cb,
            int *err, gchar **err_info, guint *err_fileno)
{
    merge_in_file_t    *in_files = NULL, *in_file = NULL;
    int                 frame_type = WTAP_ENCAP_PER_PACKET;
    merge_result        status = MERGE_OK;
    wtap_dumper        *pdh;
    struct wtap_pkthdr *phdr, snap_phdr;
    int                 count = 0;
    gboolean            stop_flag = FALSE;
    GArray             *shb_hdrs = NULL;
    wtapng_iface_descriptions_t *idb_inf = NULL;

    g_assert(out_fd > 0);
    g_assert(in_file_count > 0);
    g_assert(in_filenames != NULL);
    g_assert(err != NULL);
    g_assert(err_info != NULL);
    g_assert(err_fileno != NULL);

    /* if a callback was given, it has to have a callback function ptr */
    g_assert((cb != NULL) ? (cb->callback_func != NULL) : TRUE);

    merge_debug("merge_files: begin");

    /* open the input files */
    if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
                             err, err_info, err_fileno)) {
        merge_debug("merge_files: merge_open_in_files() failed with err=%d", *err);
        return MERGE_ERR_CANT_OPEN_INFILE;
    }

    if (cb)
        cb->callback_func(MERGE_EVENT_INPUT_FILES_OPENED, 0, in_files, in_file_count, cb->data);

    if (snaplen == 0) {
        /* Snapshot length not specified - default to the maximum. */
        snaplen = WTAP_MAX_PACKET_SIZE;
    }

    /*
     * This doesn't tell us that much. It tells us what to set the outfile's
     * encap type to, but that's all - for example, it does *not* tells us
     * whether the input files had the same number of IDBs, for the same exact
     * interfaces, and only one IDB each, so it doesn't actually tell us
     * whether we can merge IDBs into one or not.
     */
    frame_type = merge_select_frame_type(in_file_count, in_files);
    merge_debug("merge_files: got frame_type=%d", frame_type);

    if (cb)
        cb->callback_func(MERGE_EVENT_FRAME_TYPE_SELECTED, frame_type, in_files, in_file_count, cb->data);

    /* prepare the outfile */
    if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
        shb_hdrs = create_shb_header(in_files, in_file_count, app_name);
        merge_debug("merge_files: SHB created");

        idb_inf = generate_merged_idb(in_files, in_file_count, mode);
        merge_debug("merge_files: IDB merge operation complete, got %u IDBs", idb_inf ? idb_inf->interface_data->len : 0);

        pdh = wtap_dump_fdopen_ng(out_fd, file_type, frame_type, snaplen,
                                  FALSE /* compressed */, shb_hdrs, idb_inf,
                                  NULL, err);
    }
    else {
        pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, FALSE /* compressed */, err);
    }

    if (pdh == NULL) {
        merge_close_in_files(in_file_count, in_files);
        g_free(in_files);
        wtap_block_array_free(shb_hdrs);
        wtap_free_idb_info(idb_inf);
        return MERGE_ERR_CANT_OPEN_OUTFILE;
    }

    if (cb)
        cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);

    for (;;) {
        *err = 0;

        if (do_append) {
            in_file = merge_append_read_packet(in_file_count, in_files, err,
                                               err_info);
        }
        else {
            in_file = merge_read_packet(in_file_count, in_files, err,
                                        err_info);
        }

        if (in_file == NULL) {
            /* EOF */
            break;
        }

        if (*err != 0) {
            /* I/O error reading from in_file */
            status = MERGE_ERR_CANT_READ_INFILE;
            break;
        }

        count++;
        if (cb)
            stop_flag = cb->callback_func(MERGE_EVENT_PACKET_WAS_READ, count, in_files, in_file_count, cb->data);

        if (stop_flag) {
            /* The user decided to abort the merge. */
            status = MERGE_USER_ABORTED;
            break;
        }

        phdr = wtap_phdr(in_file->wth);

        if (snaplen != 0 && phdr->caplen > snaplen) {
            /*
             * The dumper will only write up to caplen bytes out, so we only
             * need to change that value, instead of cloning the whole packet
             * with fewer bytes.
             *
             * XXX: but do we need to change the IDBs' snap_len?
             */
            snap_phdr = *phdr;
            snap_phdr.caplen = snaplen;
            phdr = &snap_phdr;
        }

        if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
            /*
             * XXX - We should do this only for record types
             * that pertain to a particular interface; for
             * now, we hardcode that, but we need to figure
             * out a more general way to handle this.
             */
            if (phdr->rec_type == REC_TYPE_PACKET) {
                if (!map_phdr_interface_id(phdr, in_file)) {
                    status = MERGE_ERR_BAD_PHDR_INTERFACE_ID;
                    break;
                }
            }
        }

        if (!wtap_dump(pdh, phdr, wtap_buf_ptr(in_file->wth), err, err_info)) {
            status = MERGE_ERR_CANT_WRITE_OUTFILE;
            break;
        }
    }

    if (cb)
        cb->callback_func(MERGE_EVENT_DONE, count, in_files, in_file_count, cb->data);

    merge_close_in_files(in_file_count, in_files);

    if (status == MERGE_OK || status == MERGE_USER_ABORTED) {
        if (!wtap_dump_close(pdh, err))
            status = MERGE_ERR_CANT_CLOSE_OUTFILE;
    } else {
        /*
         * We already got some error; no need to report another error on
         * close.
         *
         * Don't overwrite the earlier error.
         */
        int close_err = 0;
        (void)wtap_dump_close(pdh, &close_err);
    }

    if (status != MERGE_OK) {
        GString *err_message = NULL;
        gchar   *display_basename = NULL;

        switch(status) {

            case MERGE_ERR_CANT_READ_INFILE:
                *err_info = get_read_error_string(in_files, in_file_count, err, err_info);
                break;

            case MERGE_ERR_CANT_WRITE_OUTFILE: /* fall through */
            case MERGE_ERR_CANT_CLOSE_OUTFILE:
                *err_info = get_write_error_string(in_file, file_type, out_filename, err, err_info);
                break;

            case MERGE_ERR_BAD_PHDR_INTERFACE_ID:
                display_basename = g_filename_display_basename(in_file ? in_file->filename : "UNKNOWN");
                if (*err_info != NULL)
                    g_free(*err_info);
                err_message = g_string_new("");
                g_string_printf(err_message,
                    "Record %u of \"%s\" has an interface ID which does not match any IDB in its file.",
                    in_file ? in_file->packet_num : 0, display_basename);
                g_free(display_basename);
                *err_info = g_string_free(err_message, FALSE);
                break;

            case MERGE_USER_ABORTED: /* not really an error */
            default:
                break;
        }
    }

    g_free(in_files);
    wtap_block_array_free(shb_hdrs);
    wtap_free_idb_info(idb_inf);

    return status;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
static merge_result
merge_process_packets(wtap_dumper *pdh, const int file_type,
                      merge_in_file_t *in_files, const guint in_file_count,
                      const gboolean do_append, guint snaplen,
                      merge_progress_callback_t* cb,
                      int *err, gchar **err_info, guint *err_fileno,
                      guint32 *err_framenum)
{
    merge_result        status = MERGE_OK;
    merge_in_file_t    *in_file;
    int                 count = 0;
    gboolean            stop_flag = FALSE;
    struct wtap_pkthdr *phdr, snap_phdr;

    for (;;) {
        *err = 0;

        if (do_append) {
            in_file = merge_append_read_packet(in_file_count, in_files, err,
                                               err_info);
        }
        else {
            in_file = merge_read_packet(in_file_count, in_files, err,
                                        err_info);
        }

        if (in_file == NULL) {
            /* We're at EOF on all input files */
            break;
        }

        if (*err != 0) {
            /* I/O error reading from in_file */
            status = MERGE_ERR_CANT_READ_INFILE;
            break;
        }

        count++;
        if (cb)
            stop_flag = cb->callback_func(MERGE_EVENT_PACKET_WAS_READ, count, in_files, in_file_count, cb->data);

        if (stop_flag) {
            /* The user decided to abort the merge. */
            status = MERGE_USER_ABORTED;
            break;
        }

        phdr = wtap_phdr(in_file->wth);

        if (snaplen != 0 && phdr->caplen > snaplen) {
            /*
             * The dumper will only write up to caplen bytes out, so we only
             * need to change that value, instead of cloning the whole packet
             * with fewer bytes.
             *
             * XXX: but do we need to change the IDBs' snap_len?
             */
            snap_phdr = *phdr;
            snap_phdr.caplen = snaplen;
            phdr = &snap_phdr;
        }

        if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
            /*
             * XXX - We should do this only for record types
             * that pertain to a particular interface; for
             * now, we hardcode that, but we need to figure
             * out a more general way to handle this.
             */
            if (phdr->rec_type == REC_TYPE_PACKET) {
                if (!map_phdr_interface_id(phdr, in_file)) {
                    status = MERGE_ERR_BAD_PHDR_INTERFACE_ID;
                    break;
                }
            }
        }

        if (!wtap_dump(pdh, phdr, wtap_buf_ptr(in_file->wth), err, err_info)) {
            status = MERGE_ERR_CANT_WRITE_OUTFILE;
            break;
        }
    }

    if (cb)
        cb->callback_func(MERGE_EVENT_DONE, count, in_files, in_file_count, cb->data);

    merge_close_in_files(in_file_count, in_files);

    if (status == MERGE_OK || status == MERGE_USER_ABORTED) {
        if (!wtap_dump_close(pdh, err))
            status = MERGE_ERR_CANT_CLOSE_OUTFILE;
    } else {
        /*
         * We already got some error; no need to report another error on
         * close.
         *
         * Don't overwrite the earlier error.
         */
        int close_err = 0;
        (void)wtap_dump_close(pdh, &close_err);
    }

    if (status == MERGE_OK || in_file == NULL) {
        *err_fileno = 0;
        *err_framenum = 0;
    } else {
        *err_fileno = (guint)(in_file - in_files);
        *err_framenum = in_file->packet_num;
    }

    return status;
}
Ejemplo n.º 8
0
int
main(int argc, char *argv[])
{
  int ser_fd;
  GError *err = NULL;
  int werr;
  gchar *err_info;
  gint64 data_offset;
  wtap *w;
  GOptionContext *opt_ctxt;
  gint64 ts_start_us = 0;
  gint64 time_start_us = 0;
  opt_ctxt = g_option_context_new ("FILE");
  g_option_context_add_main_entries(opt_ctxt, app_options, NULL);
  if (!g_option_context_parse(opt_ctxt, &argc, &argv, &err)) {
    g_printerr("Failed to parse options: %s\n", err->message);
    return EXIT_FAILURE;
  }
  g_option_context_free(opt_ctxt);
  
  w = wtap_open_offline(argv[1], WTAP_TYPE_AUTO, &werr, &err_info, FALSE);
  if (!w) {
    g_printerr("Failed to open packet file: %d\n", werr);
    return EXIT_FAILURE;
  }

  if (pseudo) {
    ser_fd = open_pseudo_terminal(&err);
    if (ser_fd < 0) {
      g_printerr("Failed open pseudo terminal: %s\n", err->message);
      return EXIT_FAILURE;
    }
  } else {
    ser_fd = profibus_serial_open(device, speed, &err);
    if (ser_fd < 0) {
      g_printerr("Failed open serial port: %s\n", err->message);
      return EXIT_FAILURE;
    }
  }
  
  while(TRUE) {
    guint8 *data;
    struct wtap_pkthdr *hdr;
    if (!wtap_read(w, &werr, &err_info, &data_offset)) {
      if (err == 0) break;
      g_printerr("Failed to read packet file: %d\n", werr);
      return EXIT_FAILURE;
    }
    hdr = wtap_phdr(w);
    data = wtap_buf_ptr(w);
    if (timing) {
      if (time_start_us == 0) {
	ts_start_us = hdr->ts.secs * 1000000LL +  hdr->ts.nsecs / 1000;
	time_start_us = g_get_monotonic_time();
      } else {
	gint64 ts = hdr->ts.secs * 1000000LL +  hdr->ts.nsecs / 1000;
	gint64 next = time_start_us + (ts - ts_start_us);
	gint64 now = g_get_monotonic_time();
	gint64 delay = next - now;
	if (delay > 0) {
	  poll(NULL, 0, delay / 1000);
	}
      }
    }
    if (write(ser_fd, data, hdr->len) != hdr->len) {
      g_printerr("Failed to write to serial device: %s\n", strerror(errno));
      break;
    }
    /* g_debug("Write %d", hdr->len); */
  }
  wtap_close(w);
  g_message("EOF");
  close(ser_fd);
  return EXIT_SUCCESS;
}
Ejemplo n.º 9
0
int
main(int argc, char *argv[])
{
  GString            *comp_info_str;
  GString            *runtime_info_str;
  int                 opt;
DIAG_OFF(cast-qual)
  static const struct option long_options[] = {
      {(char *)"help", no_argument, NULL, 'h'},
      {(char *)"version", no_argument, NULL, 'V'},
      {0, 0, 0, 0 }
  };
DIAG_ON(cast-qual)
  gboolean            do_append          = FALSE;
  gboolean            verbose            = FALSE;
  int                 in_file_count      = 0;
  guint               snaplen            = 0;
#ifdef PCAP_NG_DEFAULT
  int                 file_type          = WTAP_FILE_TYPE_SUBTYPE_PCAPNG; /* default to pcap format */
#else
  int                 file_type          = WTAP_FILE_TYPE_SUBTYPE_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, *write_err_info = NULL;
  int                 err_fileno;
  char               *out_filename       = NULL;
  gboolean            got_read_error     = FALSE, got_write_error = FALSE;
  int                 count;

  cmdarg_err_init(mergecap_cmdarg_err, mergecap_cmdarg_err_cont);

#ifdef _WIN32
  arg_list_utf_16to8(argc, argv);
  create_app_running_mutex();
#endif /* _WIN32 */

  /* Get the compile-time version information string */
  comp_info_str = get_compiled_version_info(NULL, get_mergecap_compiled_info);

  /* Get the run-time version information string */
  runtime_info_str = get_runtime_version_info(get_mergecap_runtime_info);

  /* Add it to the information to be reported on a crash. */
  ws_add_crash_info("Mergecap (Wireshark) %s\n"
       "\n"
       "%s"
       "\n"
       "%s",
    get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);

  /* Process the options first */
  while ((opt = getopt_long(argc, argv, "aF:hs:T:vVw:", long_options, NULL)) != -1) {

    switch (opt) {
    case 'a':
      do_append = !do_append;
      break;

    case 'F':
      file_type = wtap_short_string_to_file_type_subtype(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 'h':
      printf("Mergecap (Wireshark) %s\n"
             "Merge two or more capture files into one.\n"
             "See http://www.wireshark.org for more information.\n",
             get_ws_vcs_version_info());
      print_usage(stdout);
      exit(0);
      break;

    case 's':
      snaplen = get_positive_int(optarg, "snapshot length");
      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 'v':
      verbose = TRUE;
      break;

    case 'V':
      show_version("Mergecap (Wireshark)", comp_info_str, runtime_info_str);
      g_string_free(comp_info_str, TRUE);
      g_string_free(runtime_info_str, TRUE);
      exit(0);
      break;

    case 'w':
      out_filename = optarg;
      break;

    case '?':              /* Bad options if GNU getopt */
      switch(optopt) {
      case'F':
        list_capture_types();
        break;
      case'T':
        list_encap_types();
        break;
      default:
        print_usage(stderr);
      }
      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));
    if (err_info != NULL) {
      fprintf(stderr, "(%s)\n", err_info);
      g_free(err_info);
    }
    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_subtype_string(wtap_file_type_subtype(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 */
  if(file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG ){
    wtapng_section_t *shb_hdr;
    GString *comment_gstr;

    shb_hdr = g_new(wtapng_section_t,1);
    comment_gstr = g_string_new("File created by merging: \n");

    for (i = 0; i < in_file_count; i++) {
      g_string_append_printf(comment_gstr, "File%d: %s \n",i+1,in_files[i].filename);
    }
    shb_hdr->section_length = -1;
    /* options */
    shb_hdr->opt_comment   = comment_gstr->str; /* NULL if not available */
    shb_hdr->shb_hardware  = NULL;              /* NULL if not available, UTF-8 string containing the description of the hardware used to create this section. */
    shb_hdr->shb_os        = NULL;              /* NULL if not available, UTF-8 string containing the name of the operating system used to create this section. */
    shb_hdr->shb_user_appl = g_strdup("mergecap"); /* NULL if not available, UTF-8 string containing the name of the application used to create this section. */

    pdh = wtap_dump_fdopen_ng(out_fd, file_type, frame_type, snaplen,
                              FALSE /* compressed */, shb_hdr, NULL /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
    g_string_free(comment_gstr, TRUE);
  } else {
    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: %d\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_buf_ptr(in_file->wth), &write_err, &write_err_info)) {
      got_write_error = TRUE;
      break;
    }
  }

  merge_close_in_files(in_file_count, in_files);
  if (!got_write_error) {
    if (!wtap_dump_close(pdh, &write_err))
      got_write_error = TRUE;
  } else {
    /*
     * We already got a write error; no need to report another
     * write error on close.
     *
     * Don't overwrite the earlier write error.
     */
    (void)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));
        if (err_info != NULL) {
          fprintf(stderr, "(%s)\n", err_info);
          g_free(err_info);
        }
      }
    }
  }

  if (got_write_error) {
    switch (write_err) {

    case WTAP_ERR_UNWRITABLE_ENCAP:
      /*
       * This is a problem with the particular frame we're writing and
       * the file type and subtype we're wwriting; note that, and
       * report the frame number and file type/subtype.
       */
      fprintf(stderr, "mergecap: Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.\n",
              in_file ? in_file->packet_num : 0, in_file ? in_file->filename : "UNKNOWN",
              wtap_file_type_subtype_string(file_type));
      break;

    case WTAP_ERR_PACKET_TOO_LARGE:
      /*
       * This is a problem with the particular frame we're writing and
       * the file type and subtype we're wwriting; note that, and
       * report the frame number and file type/subtype.
       */
      fprintf(stderr, "mergecap: Frame %u of \"%s\" is too large for a \"%s\" file.\n",
              in_file ? in_file->packet_num : 0, in_file ? in_file->filename : "UNKNOWN",
              wtap_file_type_subtype_string(file_type));
      break;

    case WTAP_ERR_UNWRITABLE_REC_TYPE:
      /*
       * This is a problem with the particular record we're writing and
       * the file type and subtype we're wwriting; note that, and
       * report the record number and file type/subtype.
       */
      fprintf(stderr, "mergecap: Record %u of \"%s\" has a record type that can't be saved in a \"%s\" file.\n",
              in_file ? in_file->packet_num : 0, in_file ? in_file->filename : "UNKNOWN",
              wtap_file_type_subtype_string(file_type));
      break;

    case WTAP_ERR_UNWRITABLE_REC_DATA:
      /*
       * This is a problem with the particular record we're writing and
       * the file type and subtype we're wwriting; note that, and
       * report the record number and file type/subtype.
       */
      fprintf(stderr, "mergecap: Record %u of \"%s\" has data that can't be saved in a \"%s\" file.\n(%s)\n",
              in_file ? in_file->packet_num : 0, in_file ? in_file->filename : "UNKNOWN",
              wtap_file_type_subtype_string(file_type),
              write_err_info != NULL ? write_err_info : "no information supplied");
      g_free(write_err_info);
      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;
}