/* * 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; }
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; }
/* creates a section header block for the new output file */ static GArray* create_shb_header(const merge_in_file_t *in_files, const guint in_file_count, const gchar *app_name) { GArray *shb_hdrs; wtap_block_t shb_hdr; GString *comment_gstr; GString *os_info_str; guint i; char* shb_comment = NULL; wtapng_mandatory_section_t* shb_data; gsize opt_len; gchar *opt_str; shb_hdrs = wtap_file_get_shb_for_new_file(in_files[0].wth); shb_hdr = g_array_index(shb_hdrs, wtap_block_t, 0); comment_gstr = g_string_new(""); /* * TODO: merge comments from all files * * XXX - do we want some way to record which comments, hardware/OS/app * descriptions, IDBs, etc.? came from which files? * * XXX - fix this to handle multiple comments from a single file. */ if (wtap_block_get_nth_string_option_value(shb_hdr, OPT_COMMENT, 0, &shb_comment) == WTAP_OPTTYPE_SUCCESS && strlen(shb_comment) > 0) { /* very lame way to save comments - does not save them from the other files */ g_string_append_printf(comment_gstr, "%s \n",shb_comment); } g_string_append_printf(comment_gstr, "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); } os_info_str = g_string_new(""); get_os_version_info(os_info_str); shb_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(shb_hdr); shb_data->section_length = -1; /* TODO: handle comments from each file being merged */ opt_len = comment_gstr->len; opt_str = g_string_free(comment_gstr, FALSE); wtap_block_set_nth_string_option_value(shb_hdr, OPT_COMMENT, 0, opt_str, opt_len); /* section comment */ g_free(opt_str); /* * XXX - and how do we preserve all the OPT_SHB_HARDWARE, OPT_SHB_OS, * and OPT_SHB_USERAPPL values from all the previous files? */ wtap_block_remove_option(shb_hdr, OPT_SHB_HARDWARE); opt_len = os_info_str->len; opt_str = g_string_free(os_info_str, FALSE); if (opt_str) { wtap_block_set_string_option_value(shb_hdr, OPT_SHB_OS, opt_str, opt_len); /* UTF-8 string containing the name */ /* of the operating system used to create this section. */ g_free(opt_str); } else { /* * No OS information; remove the old version. */ wtap_block_remove_option(shb_hdr, OPT_SHB_OS); } wtap_block_set_string_option_value(shb_hdr, OPT_SHB_USERAPPL, (char*)app_name, app_name ? strlen(app_name): 0 ); /* NULL if not available, UTF-8 string containing the name */ /* of the application used to create this section. */ return shb_hdrs; }
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); }
/* * Get various library run-time versions, and the OS version, and append * them to the specified GString. */ void get_runtime_version_info(GString *str, void (*additional_info)(GString *)) { #ifndef _WIN32 gchar *lang; #endif g_string_append(str, "on "); get_os_version_info(str); #ifndef _WIN32 /* Locale */ if ((lang = getenv ("LANG")) != NULL) g_string_append_printf(str, ", with locale %s", lang); else g_string_append(str, ", without locale"); #endif /* Libpcap */ g_string_append(str, ", "); get_runtime_pcap_version(str); /* zlib */ #if defined(HAVE_LIBZ) && !defined(_WIN32) g_string_append_printf(str, ", with libz %s", zlibVersion()); #endif /* Additional application-dependent information */ if (additional_info) (*additional_info)(str); g_string_append(str, "."); /* Compiler info */ /* * See https://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers * information on various defined strings. * * GCC's __VERSION__ is a nice text string for humans to * read. The page at sourceforge.net largely describes * numeric #defines that encode the version; if the compiler * doesn't also offer a nice printable string, we try prettifying * the number somehow. */ #if defined(__GNUC__) && defined(__VERSION__) /* * Clang and llvm-gcc also define __GNUC__ and __VERSION__; * distinguish between them. */ #if defined(__clang__) g_string_append_printf(str, "\n\nBuilt using clang %s.\n", __VERSION__); #elif defined(__llvm__) g_string_append_printf(str, "\n\nBuilt using llvm-gcc %s.\n", __VERSION__); #else /* boring old GCC */ g_string_append_printf(str, "\n\nBuilt using gcc %s.\n", __VERSION__); #endif /* llvm */ #elif defined(__HP_aCC) g_string_append_printf(str, "\n\nBuilt using HP aCC %d.\n", __HP_aCC); #elif defined(__xlC__) g_string_append_printf(str, "\n\nBuilt using IBM XL C %d.%d\n", (__xlC__ >> 8) & 0xFF, __xlC__ & 0xFF); #ifdef __IBMC__ if ((__IBMC__ % 10) != 0) g_string_append_printf(str, " patch %d", __IBMC__ % 10); #endif /* __IBMC__ */ g_string_append_printf(str, "\n"); #elif defined(__INTEL_COMPILER) g_string_append_printf(str, "\n\nBuilt using Intel C %d.%d", __INTEL_COMPILER / 100, (__INTEL_COMPILER / 10) % 10); if ((__INTEL_COMPILER % 10) != 0) g_string_append_printf(str, " patch %d", __INTEL_COMPILER % 10); #ifdef __INTEL_COMPILER_BUILD_DATE g_string_sprinta(str, ", compiler built %04d-%02d-%02d", __INTEL_COMPILER_BUILD_DATE / 10000, (__INTEL_COMPILER_BUILD_DATE / 100) % 100, __INTEL_COMPILER_BUILD_DATE % 100); #endif /* __INTEL_COMPILER_BUILD_DATE */ g_string_append_printf(str, "\n"); #elif defined(_MSC_FULL_VER) # if _MSC_FULL_VER > 99999999 g_string_append_printf(str, "\n\nBuilt using Microsoft Visual C++ %d.%d", (_MSC_FULL_VER / 10000000) - 6, (_MSC_FULL_VER / 100000) % 100); # if (_MSC_FULL_VER % 100000) != 0 g_string_append_printf(str, " build %d", _MSC_FULL_VER % 100000); # endif # else g_string_append_printf(str, "\n\nBuilt using Microsoft Visual C++ %d.%d", (_MSC_FULL_VER / 1000000) - 6, (_MSC_FULL_VER / 10000) % 100); # if (_MSC_FULL_VER % 10000) != 0 g_string_append_printf(str, " build %d", _MSC_FULL_VER % 10000); # endif # endif g_string_append_printf(str, "\n"); #elif defined(_MSC_VER) /* _MSC_FULL_VER not defined, but _MSC_VER defined */ g_string_append_printf(str, "\n\nBuilt using Microsoft Visual C++ %d.%d\n", (_MSC_VER / 100) - 6, _MSC_VER % 100); #elif defined(__SUNPRO_C) g_string_append_printf(str, "\n\nBuilt using Sun C %d.%d", (__SUNPRO_C >> 8) & 0xF, (__SUNPRO_C >> 4) & 0xF); if ((__SUNPRO_C & 0xF) != 0) g_string_append_printf(str, " patch %d", __SUNPRO_C & 0xF); g_string_append_printf(str, "\n"); #endif end_string(str); }