예제 #1
0
static void
show_version(GString *comp_info_str, GString *runtime_info_str)
{
    printf("Captype (Wireshark) %s\n"
           "\n"
           "%s"
           "\n"
           "%s"
           "\n"
           "%s",
           get_ws_vcs_version_info(), get_copyright_info(),
           comp_info_str->str, runtime_info_str->str);
}
예제 #2
0
static void
exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
{
    int   import_file_fd;
    char *tmpname, *capfile_name;
    int   err;

    /* pcapng defs */
    wtapng_section_t            *shb_hdr;
    wtapng_iface_descriptions_t *idb_inf;
    wtapng_if_descr_t            int_data;
    GString                     *os_info_str;
    char                        *appname;

    /* Choose a random name for the temporary import buffer */
    import_file_fd = create_tempfile(&tmpname, "Wireshark_PDU_");
    capfile_name = g_strdup(tmpname);

    /* Create data for SHB  */
    os_info_str = g_string_new("");
    get_os_version_info(os_info_str);

    appname = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());

    shb_hdr = g_new(wtapng_section_t,1);
    shb_hdr->section_length = -1;
    /* options */
    shb_hdr->opt_comment    = g_strdup_printf("Dump of PDUs from %s", cfile.filename);
    shb_hdr->shb_hardware   = NULL;                    /* UTF-8 string containing the
                                                       * description of the hardware used to create this section.
                                                       */
    shb_hdr->shb_os         = os_info_str->str;        /* UTF-8 string containing the name
                                                       * of the operating system used to create this section.
                                                       */
    g_string_free(os_info_str, FALSE);                /* The actual string is not freed */
    shb_hdr->shb_user_appl  = appname;                /* UTF-8 string containing the name
                                                       *  of the application used to create this section.
                                                       */


    /* Create fake IDB info */
    idb_inf = g_new(wtapng_iface_descriptions_t,1);
    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));

    /* create the fake interface data */
    int_data.wtap_encap            = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
    int_data.time_units_per_second = 1000000; /* default microsecond resolution */
    int_data.link_type             = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
    int_data.snap_len              = WTAP_MAX_PACKET_SIZE;
    int_data.if_name               = g_strdup("Fake IF, PDU->Export");
    int_data.opt_comment           = NULL;
    int_data.if_description        = NULL;
    int_data.if_speed              = 0;
    int_data.if_tsresol            = 6;
    int_data.if_filter_str         = NULL;
    int_data.bpf_filter_len        = 0;
    int_data.if_filter_bpf_bytes   = NULL;
    int_data.if_os                 = NULL;
    int_data.if_fcslen             = -1;
    int_data.num_stat_entries      = 0;          /* Number of ISB:s */
    int_data.interface_statistics  = NULL;

    g_array_append_val(idb_inf->interface_data, int_data);

    exp_pdu_tap_data->wdh = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE, FALSE, shb_hdr, idb_inf, &err);
    if (exp_pdu_tap_data->wdh == NULL) {
        open_failure_alert_box(capfile_name, err, TRUE);
        goto end;
    }


    /* Run the tap */
    cf_retap_packets(&cfile);


    if (!wtap_dump_close(exp_pdu_tap_data->wdh, &err)) {
        write_failure_alert_box(capfile_name, err);
    }

    remove_tap_listener(exp_pdu_tap_data);

    /* XXX: should this use the open_routine type in the cfile instead of WTAP_TYPE_AUTO? */
    if (cf_open(&cfile, capfile_name, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) {
        open_failure_alert_box(capfile_name, err, FALSE);
        goto end;
    }

    switch (cf_read(&cfile, FALSE)) {
    case CF_READ_OK:
    case CF_READ_ERROR:
    /* Just because we got an error, that doesn't mean we were unable
       to read any of the file; we handle what we could get from the
       file. */
    break;

    case CF_READ_ABORTED:
    /* The user bailed out of re-reading the capture file; the
       capture file has been closed - just free the capture file name
       string and return (without changing the last containing
       directory). */
    break;
    }

end:
    g_free(capfile_name);
    g_free(shb_hdr);
    g_free(appname);
}
예제 #3
0
/*
 * Opens an .xml file with Trace data formated according to 3GPP TS 32.423 and converts it to
 * an "Exported PDU type file with the entire xml file as the first "packet" appending the
 * raw messages as subsequent packages to be dissected by wireshark.
 */
static wtap_open_return_val
create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_423_file_info_t *file_info)
{
	int import_file_fd;
	wtap_dumper* wdh_exp_pdu;
	int   exp_pdu_file_err;

	/* pcapng defs */
	wtapng_section_t            *shb_hdr;
	wtapng_iface_descriptions_t *idb_inf;
	wtapng_if_descr_t            int_data;
	GString                     *os_info_str;
	char                        *appname;
	gint64 file_size;
	int packet_size;
	guint8 *packet_buf;
	int wrt_err;
	gchar *wrt_err_info;
	struct wtap_pkthdr phdr;

	gboolean do_random = FALSE;
	char *curr_pos, *next_pos;

	import_file_fd = create_tempfile(&(file_info->tmpname), "Wireshark_PDU_");

	/* Now open a file and dump to it */
	/* Create data for SHB  */
	os_info_str = g_string_new("");
	get_os_version_info(os_info_str);

	appname = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());

	shb_hdr = g_new(wtapng_section_t, 1);
	shb_hdr->section_length = -1;
	/* options */
	shb_hdr->opt_comment = g_strdup_printf("File converted to Exported PDU format during opening");
	/*
	* UTF-8 string containing the description of the hardware used to create
	* this section.
	*/
	shb_hdr->shb_hardware = NULL;
	/*
	* UTF-8 string containing the name of the operating system used to create
	* this section.
	*/
	shb_hdr->shb_os = g_string_free(os_info_str, FALSE);
	/*
	* UTF-8 string containing the name of the application used to create
	* this section.
	*/
	shb_hdr->shb_user_appl = appname;

	/* Create fake IDB info */
	idb_inf = g_new(wtapng_iface_descriptions_t, 1);
	idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));

	/* create the fake interface data */
	int_data.wtap_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
	int_data.time_units_per_second = 1000000; /* default microsecond resolution */
	int_data.link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
	int_data.snap_len = WTAP_MAX_PACKET_SIZE;
	int_data.if_name = g_strdup("Fake IF");
	int_data.opt_comment = NULL;
	int_data.if_description = NULL;
	int_data.if_speed = 0;
	int_data.if_tsresol = 6;
	int_data.if_filter_str = NULL;
	int_data.bpf_filter_len = 0;
	int_data.if_filter_bpf_bytes = NULL;
	int_data.if_os = NULL;
	int_data.if_fcslen = -1;
	int_data.num_stat_entries = 0;          /* Number of ISB:s */
	int_data.interface_statistics = NULL;

	g_array_append_val(idb_inf->interface_data, int_data);

	wdh_exp_pdu = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU,
					  WTAP_MAX_PACKET_SIZE, FALSE, shb_hdr, idb_inf, NULL, &exp_pdu_file_err);
	if (wdh_exp_pdu == NULL) {
		return WTAP_OPEN_ERROR;
	}

	g_free(shb_hdr);
	g_free(appname);

	/* OK we've opend a new pcap-ng file and written the headers, time to do the packets, strt by finding the file size */

	if ((file_size = wtap_file_size(wth, err)) == -1)
		return WTAP_OPEN_ERROR;

	if (file_size > MAX_FILE_SIZE) {
		/*
		* Don't blow up trying to allocate space for an
		* immensely-large file.
		*/
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("mime_file: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
			file_size, MAX_FILE_SIZE);
		return WTAP_OPEN_ERROR;
	}
	packet_size = (int)file_size;
	/* Allocate the packet buffer
	* (the whole file + Exported PDU tag "protocol" and
	* the string "xml" + 1 filler to end on 4 byte boundary for the tag
	* + End of options 4 bytes
	*/
	/* XXX add the length of exported bdu tag(s) here */
	packet_buf = (guint8 *)g_malloc(packet_size + 12);

	packet_buf[0] = 0;
	packet_buf[1] = 12; /* EXP_PDU_TAG_PROTO_NAME */
	packet_buf[2] = 0;
	packet_buf[3] = 4;
	packet_buf[4] = 0x78; /* "x" */
	packet_buf[5] = 0x6d; /* "m" */
	packet_buf[6] = 0x6c; /* "l" */
	packet_buf[7] = 0;
	/* End of options */
	packet_buf[8] = 0;
	packet_buf[9] = 0;
	packet_buf[10] = 0;
	packet_buf[11] = 0;


	if (!wtap_read_bytes(wth->fh, packet_buf + 12, packet_size, &wrt_err, &wrt_err_info)){
		return WTAP_OPEN_ERROR;
	}

	/* Create the packet header */
	memset(&phdr, 0, sizeof(struct wtap_pkthdr));
	phdr.rec_type = REC_TYPE_PACKET;
	phdr.presence_flags = 0; /* yes, we have no bananas^Wtime stamp */

	phdr.caplen = packet_size + 12;
	phdr.len = packet_size + 12;

	phdr.ts.secs = 0;
	phdr.ts.nsecs = 0;

	/* XXX: report errors! */
	if (!wtap_dump(wdh_exp_pdu, &phdr, packet_buf, &wrt_err, &wrt_err_info)) {
		switch (wrt_err) {

		case WTAP_ERR_UNWRITABLE_REC_DATA:
			g_free(wrt_err_info);
			break;

		default:
			break;
		}
		g_free(packet_buf);
		return WTAP_OPEN_ERROR;
	}

	/* Advance *packet_buf to point at the raw file data */
	curr_pos = packet_buf + 12;
	/* Lets add the raw messages as packets after the main "packet" with the whole file */
	while ((curr_pos = strstr(curr_pos, "<msg")) != NULL){
		wtap_open_return_val temp_val;

		curr_pos = curr_pos + 4;
		next_pos = strstr(curr_pos, "</msg>");
		if (!next_pos){
			/* Somethings wrong, bail out */
			break;
		}
		next_pos = next_pos + 6;
		/* Do we have a raw msg?) */
		curr_pos = strstr(curr_pos, "<rawMsg");
		if (!curr_pos){
			/* No rawMsg, continue */
			curr_pos = next_pos;
			continue;
		}
		curr_pos = curr_pos + 7;
		/* Add the raw msg*/
		temp_val = write_packet_data(wdh_exp_pdu, &phdr, &wrt_err, &wrt_err_info, curr_pos);
		if (temp_val != WTAP_OPEN_MINE){
			g_free(packet_buf);
			return temp_val;
		}
		curr_pos = next_pos;
	}

	/* Close the written file*/
	if (!wtap_dump_close(wdh_exp_pdu, err)){
		g_free(packet_buf);
		return WTAP_OPEN_ERROR;
	}

	g_free(packet_buf);
	/* Now open the file for reading */

	/* Find out if random read was requested */
	if (wth->random_fh){
		do_random = TRUE;
	}
	file_info->wth_tmp_file =
		wtap_open_offline(file_info->tmpname, WTAP_TYPE_AUTO, err, err_info, do_random);

	if (!file_info->wth_tmp_file){
		return WTAP_OPEN_ERROR;
	}

	return WTAP_OPEN_MINE;
}
예제 #4
0
int
exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, char *comment)
{

    int   err;

    /* pcapng defs */
    wtap_block_t                 shb_hdr;
    GArray                      *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
    wtapng_iface_descriptions_t *idb_inf;
    wtap_block_t                 int_data;
    wtapng_if_descr_mandatory_t *int_data_mand;
    GString                     *os_info_str;
    gsize                        opt_len;
    gchar                       *opt_str;

    /* Create data for SHB  */
    os_info_str = g_string_new("");
    get_os_version_info(os_info_str);

    shb_hdr = wtap_block_create(WTAP_BLOCK_NG_SECTION);

    /* options */
    wtap_block_add_string_option(shb_hdr, OPT_COMMENT, comment, strlen(comment));
    g_free(comment);

    /*
     * UTF-8 string containing the name of the operating system used to create
     * this section.
     */
    opt_len = os_info_str->len;
    opt_str = g_string_free(os_info_str, FALSE);
    if (opt_str) {
        wtap_block_add_string_option(shb_hdr, OPT_SHB_OS, opt_str, opt_len);
        g_free(opt_str);
    }
    /*
     * UTF-8 string containing the name of the application used to create
     * this section.
     */
    wtap_block_add_string_option_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info());

    /* Create fake IDB info */
    idb_inf = g_new(wtapng_iface_descriptions_t,1);
    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));

    /* create the fake interface data */
    int_data = wtap_block_create(WTAP_BLOCK_IF_DESCR);
    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
    int_data_mand->wtap_encap      = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
    int_data_mand->time_units_per_second = 1000000000; /* default nanosecond resolution */
    int_data_mand->snap_len        = WTAP_MAX_PACKET_SIZE_STANDARD;

    wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF, PDU->Export", strlen("Fake IF, PDU->Export"));
    wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 9);

    g_array_append_val(idb_inf->interface_data, int_data);

    g_array_append_val(shb_hdrs, shb_hdr);

    /* Use a random name for the temporary import buffer */
    exp_pdu_tap_data->wdh = wtap_dump_fdopen_ng(fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE_STANDARD, FALSE,
        shb_hdrs, idb_inf, NULL, &err);
    if (exp_pdu_tap_data->wdh == NULL) {
        g_assert(err != 0);
        return err;
    }

    return 0;
}
예제 #5
0
static void
exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
{
    char *tmpname, *capfile_name;
    int   err;

    /* pcapng defs */
    wtap_optionblock_t           shb_hdr;
    wtapng_iface_descriptions_t *idb_inf;
    wtap_optionblock_t           int_data;
    wtapng_if_descr_mandatory_t *int_data_mand;
    GString                     *os_info_str;
    gchar                       *opt_comment, *wireshark_ver;

    /* Create data for SHB  */
    os_info_str = g_string_new("");
    get_os_version_info(os_info_str);

    shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);

    /* options */
    opt_comment = g_strdup_printf("Dump of PDUs from %s", cfile.filename);
    wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, opt_comment);
    g_free(opt_comment);

    /*
     * UTF-8 string containing the name of the operating system used to create
     * this section.
     */
    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE));
    /*
     * UTF-8 string containing the name of the application used to create
     * this section.
     */
    wireshark_ver = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, wireshark_ver);
    g_free(wireshark_ver);

    /* Create fake IDB info */
    idb_inf = g_new(wtapng_iface_descriptions_t,1);
    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));

    /* create the fake interface data */
    int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
    int_data_mand->wtap_encap      = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
    int_data_mand->time_units_per_second = 1000000000; /* default nanosecond resolution */
    int_data_mand->link_type       = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
    int_data_mand->snap_len        = WTAP_MAX_PACKET_SIZE;

    wtap_optionblock_set_option_string(int_data, OPT_IDB_NAME, "Fake IF, PDU->Export");
    wtap_optionblock_set_option_uint8(int_data, OPT_IDB_TSRESOL, 9);

    g_array_append_val(idb_inf->interface_data, int_data);

    /* Use a random name for the temporary import buffer */
    exp_pdu_tap_data->wdh = wtap_dump_open_tempfile_ng(&tmpname, "Wireshark_PDU_",
                            WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
                            WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE,
                            FALSE, shb_hdr, idb_inf, NULL, &err);
    capfile_name = g_strdup(tmpname);
    if (exp_pdu_tap_data->wdh == NULL) {
        open_failure_alert_box(capfile_name ? capfile_name : "temporary file", err, TRUE);
        goto end;
    }

    /* Run the tap */
    cf_retap_packets(&cfile);


    if (!wtap_dump_close(exp_pdu_tap_data->wdh, &err)) {
        write_failure_alert_box(capfile_name, err);
    }

    remove_tap_listener(exp_pdu_tap_data);

    /* XXX: should this use the open_routine type in the cfile instead of WTAP_TYPE_AUTO? */
    if (cf_open(&cfile, capfile_name, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) {
        open_failure_alert_box(capfile_name, err, FALSE);
        goto end;
    }

    switch (cf_read(&cfile, FALSE)) {
    case CF_READ_OK:
    case CF_READ_ERROR:
        /* Just because we got an error, that doesn't mean we were unable
           to read any of the file; we handle what we could get from the
           file. */
        break;

    case CF_READ_ABORTED:
        /* The user bailed out of re-reading the capture file; the
           capture file has been closed - just free the capture file name
           string and return (without changing the last containing
           directory). */
        break;
    }

end:
    g_free(capfile_name);
    wtap_optionblock_free(shb_hdr);
    wtap_free_idb_info(idb_inf);
}
예제 #6
0
int
main(int argc, char *argv[])
{
  GString *comp_info_str;
  GString *runtime_info_str;
  wtap  *wth;
  int    err;
  gchar *err_info;
  int    i;
  int    opt;
  int    overall_error_status;
  static const struct option long_options[] = {
      {"help", no_argument, NULL, 'h'},
      {"version", no_argument, NULL, 'v'},
      {0, 0, 0, 0 }
  };

#ifdef HAVE_PLUGINS
  char  *init_progfile_dir_error;
#endif

  /* Set the C-language locale to the native environment. */
  setlocale(LC_ALL, "");

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

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

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

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

  /*
   * Get credential information for later use.
   */
  init_process_policies();
  init_open_routines();

#ifdef HAVE_PLUGINS
  if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) {
    g_warning("captype: init_progfile_dir(): %s", init_progfile_dir_error);
    g_free(init_progfile_dir_error);
  } else {
    /* Register all the plugin types we have. */
    wtap_register_plugin_types(); /* Types known to libwiretap */

    init_report_err(failure_message,NULL,NULL,NULL);

    /* Scan for plugins.  This does *not* call their registration routines;
       that's done later.

       Don't report failures to load plugins because most (non-wiretap)
       plugins *should* fail to load (because we're not linked against
       libwireshark and dissector plugins need libwireshark). */
    scan_plugins(DONT_REPORT_LOAD_FAILURE);

    /* Register all libwiretap plugin modules. */
    register_all_wiretap_modules();
  }
#endif

  /* Process the options */
  while ((opt = getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) {

    switch (opt) {

      case 'h':
        printf("Captype (Wireshark) %s\n"
               "Print the file types of capture files.\n"
               "See https://www.wireshark.org for more information.\n",
               get_ws_vcs_version_info());
        print_usage(stdout);
        exit(0);
        break;

      case 'v':
        comp_info_str = get_compiled_version_info(NULL, NULL);
        runtime_info_str = get_runtime_version_info(NULL);
        show_version("Captype (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 '?':              /* Bad flag - print usage message */
        print_usage(stderr);
        exit(1);
        break;
    }
  }

  if (argc < 2) {
    print_usage(stderr);
    return 1;
  }

  overall_error_status = 0;

  for (i = 1; i < argc; i++) {
    wth = wtap_open_offline(argv[i], WTAP_TYPE_AUTO, &err, &err_info, FALSE);

    if(wth) {
      printf("%s: %s\n", argv[i], wtap_file_type_subtype_short_string(wtap_file_type_subtype(wth)));
      wtap_close(wth);
    } else {
      if (err == WTAP_ERR_FILE_UNKNOWN_FORMAT)
        printf("%s: unknown\n", argv[i]);
      else {
        fprintf(stderr, "captype: Can't open %s: %s\n", argv[i],
                wtap_strerror(err));
        if (err_info != NULL) {
          fprintf(stderr, "(%s)\n", err_info);
          g_free(err_info);
        }
        overall_error_status = 1; /* remember that an error has occurred */
      }
    }

  }

  return overall_error_status;
}
예제 #7
0
int
main(int argc, char *argv[])
{
    GString *comp_info_str;
    GString *runtime_info_str;
    char *init_progfile_dir_error;
    wtap *wth = NULL;
    wtap_dumper *pdh = NULL;
    wtap_rec dump_rec;
    Buffer buf;
    int err;
    gchar *err_info;
    gint64 data_offset;
    const wtap_rec *rec;
    guint wrong_order_count = 0;
    gboolean write_output_regardless = TRUE;
    guint i;
    GArray                      *shb_hdrs = NULL;
    wtapng_iface_descriptions_t *idb_inf = NULL;
    GArray                      *nrb_hdrs = NULL;
    int                          ret = EXIT_SUCCESS;

    GPtrArray *frames;
    FrameRecord_t *prevFrame = NULL;

    int opt;
    static const struct option long_options[] = {
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'v'},
        {0, 0, 0, 0 }
    };
    int file_count;
    char *infile;
    const char *outfile;

    cmdarg_err_init(failure_warning_message, failure_message_cont);

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

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

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

    /*
     * Get credential information for later use.
     */
    init_process_policies();

    /*
     * Attempt to get the pathname of the directory containing the
     * executable file.
     */
    init_progfile_dir_error = init_progfile_dir(argv[0]);
    if (init_progfile_dir_error != NULL) {
        fprintf(stderr,
                "reordercap: Can't get pathname of directory containing the reordercap program: %s.\n",
                init_progfile_dir_error);
        g_free(init_progfile_dir_error);
    }

    init_report_message(failure_warning_message, failure_warning_message,
                        NULL, NULL, NULL);

    wtap_init(TRUE);

    /* Process the options first */
    while ((opt = getopt_long(argc, argv, "hnv", long_options, NULL)) != -1) {
        switch (opt) {
            case 'n':
                write_output_regardless = FALSE;
                break;
            case 'h':
                printf("Reordercap (Wireshark) %s\n"
                       "Reorder timestamps of input file frames into output file.\n"
                       "See https://www.wireshark.org for more information.\n",
                       get_ws_vcs_version_info());
                print_usage(stdout);
                goto clean_exit;
            case 'v':
                comp_info_str = get_compiled_version_info(NULL, NULL);
                runtime_info_str = get_runtime_version_info(NULL);
                show_version("Reordercap (Wireshark)", comp_info_str, runtime_info_str);
                g_string_free(comp_info_str, TRUE);
                g_string_free(runtime_info_str, TRUE);
                goto clean_exit;
            case '?':
                print_usage(stderr);
                ret = INVALID_OPTION;
                goto clean_exit;
        }
    }

    /* Remaining args are file names */
    file_count = argc - optind;
    if (file_count == 2) {
        infile  = argv[optind];
        outfile = argv[optind+1];
    }
    else {
        print_usage(stderr);
        ret = INVALID_OPTION;
        goto clean_exit;
    }

    /* Open infile */
    /* TODO: if reordercap is ever changed to give the user a choice of which
       open_routine reader to use, then the following needs to change. */
    wth = wtap_open_offline(infile, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
    if (wth == NULL) {
        cfile_open_failure_message("reordercap", infile, err, err_info);
        ret = OPEN_ERROR;
        goto clean_exit;
    }
    DEBUG_PRINT("file_type_subtype is %d\n", wtap_file_type_subtype(wth));

    shb_hdrs = wtap_file_get_shb_for_new_file(wth);
    idb_inf = wtap_file_get_idb_info(wth);
    nrb_hdrs = wtap_file_get_nrb_for_new_file(wth);

    /* Open outfile (same filetype/encap as input file) */
    if (strcmp(outfile, "-") == 0) {
      pdh = wtap_dump_open_stdout_ng(wtap_file_type_subtype(wth), wtap_file_encap(wth),
                                     wtap_snapshot_length(wth), FALSE, shb_hdrs, idb_inf, nrb_hdrs, &err);
    } else {
      pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth),
                              wtap_snapshot_length(wth), FALSE, shb_hdrs, idb_inf, nrb_hdrs, &err);
    }
    g_free(idb_inf);
    idb_inf = NULL;

    if (pdh == NULL) {
        cfile_dump_open_failure_message("reordercap", outfile, err,
                                        wtap_file_type_subtype(wth));
        wtap_block_array_free(shb_hdrs);
        wtap_block_array_free(nrb_hdrs);
        ret = OUTPUT_FILE_ERROR;
        goto clean_exit;
    }

    /* Allocate the array of frame pointers. */
    frames = g_ptr_array_new();

    /* Read each frame from infile */
    while (wtap_read(wth, &err, &err_info, &data_offset)) {
        FrameRecord_t *newFrameRecord;

        rec = wtap_get_rec(wth);

        newFrameRecord = g_slice_new(FrameRecord_t);
        newFrameRecord->num = frames->len + 1;
        newFrameRecord->offset = data_offset;
        if (rec->presence_flags & WTAP_HAS_TS) {
            newFrameRecord->frame_time = rec->ts;
        } else {
            nstime_set_unset(&newFrameRecord->frame_time);
        }

        if (prevFrame && frames_compare(&newFrameRecord, &prevFrame) < 0) {
           wrong_order_count++;
        }

        g_ptr_array_add(frames, newFrameRecord);
        prevFrame = newFrameRecord;
    }
    if (err != 0) {
      /* Print a message noting that the read failed somewhere along the line. */
      cfile_read_failure_message("reordercap", infile, err, err_info);
    }

    printf("%u frames, %u out of order\n", frames->len, wrong_order_count);

    /* Sort the frames */
    if (wrong_order_count > 0) {
        g_ptr_array_sort(frames, frames_compare);
    }

    /* Write out each sorted frame in turn */
    wtap_rec_init(&dump_rec);
    ws_buffer_init(&buf, 1500);
    for (i = 0; i < frames->len; i++) {
        FrameRecord_t *frame = (FrameRecord_t *)frames->pdata[i];

        /* Avoid writing if already sorted and configured to */
        if (write_output_regardless || (wrong_order_count > 0)) {
            frame_write(frame, wth, pdh, &dump_rec, &buf, infile, outfile);
        }
        g_slice_free(FrameRecord_t, frame);
    }
    wtap_rec_cleanup(&dump_rec);
    ws_buffer_free(&buf);

    if (!write_output_regardless && (wrong_order_count == 0)) {
        printf("Not writing output file because input file is already in order.\n");
    }

    /* Free the whole array */
    g_ptr_array_free(frames, TRUE);

    /* Close outfile */
    if (!wtap_dump_close(pdh, &err)) {
        cfile_close_failure_message(outfile, err);
        wtap_block_array_free(shb_hdrs);
        wtap_block_array_free(nrb_hdrs);
        ret = OUTPUT_FILE_ERROR;
        goto clean_exit;
    }
    wtap_block_array_free(shb_hdrs);
    wtap_block_array_free(nrb_hdrs);

    /* Finally, close infile and release resources. */
    wtap_close(wth);

clean_exit:
    wtap_cleanup();
    free_progdirs();
    return ret;
}
예제 #8
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;
}