summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-08-08 14:06:29 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-08-08 14:06:29 +0000
commitae5a2f3b6df1c3c02450350e1e1c98488d6d3813 (patch)
tree15df29d5363afa418958a7be76298845a6d3a053 /file.c
parentbbd9a397f878fc2b7171c2a9f47dbc69b97d1daf (diff)
downloadwireshark-ae5a2f3b6df1c3c02450350e1e1c98488d6d3813.tar.gz
Make it possible to merge libpcap files with different encapsulation types by making the output file a pcapng file and construkting SHB and IDB
svn path=/trunk/; revision=44338
Diffstat (limited to 'file.c')
-rw-r--r--file.c123
1 files changed, 112 insertions, 11 deletions
diff --git a/file.c b/file.c
index 369037f70b..89677a07c0 100644
--- a/file.c
+++ b/file.c
@@ -1258,6 +1258,8 @@ cf_merge_files(char **out_filenamep, int in_file_count,
gint64 progbar_nextstep;
gint64 progbar_quantum;
gchar *display_basename;
+ int selected_frame_type;
+ gboolean fake_interface_ids = FALSE;
/* open the input files */
if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
@@ -1288,17 +1290,105 @@ cf_merge_files(char **out_filenamep, int in_file_count,
return CF_ERROR;
}
- pdh = wtap_dump_fdopen(out_fd, file_type,
- merge_select_frame_type(in_file_count, in_files),
- merge_max_snapshot_length(in_file_count, in_files),
- FALSE /* compressed */, &open_err);
- if (pdh == NULL) {
- ws_close(out_fd);
- merge_close_in_files(in_file_count, in_files);
- g_free(in_files);
- cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
- file_type);
- return CF_ERROR;
+ selected_frame_type = merge_select_frame_type(in_file_count, in_files);
+
+ /* If we are trying to merge a number of libpcap files with different encapsulation types
+ * change the output file type to pcapng and create SHB and IDB:s for the new file use the
+ * interface index stored in in_files per file to change the phdr before writing the datablock.
+ * XXX should it be an option to convert to pcapng?
+ *
+ * We need something similar when merging pcapng files possibly with an option to say
+ * the same interface(s) used in all in files. SHBs comments should be merged together.
+ */
+ if((selected_frame_type == WTAP_ENCAP_PER_PACKET)&&(file_type == WTAP_FILE_PCAP)){
+ /* Write output in pcapng format */
+ wtapng_section_t *shb_hdr;
+ wtapng_iface_descriptions_t *idb_inf, *idb_inf_merge_file;
+ wtapng_if_descr_t int_data, *file_int_data;
+ GString *comment_gstr;
+ int i;
+
+ fake_interface_ids = TRUE;
+ /* Create SHB info */
+ shb_hdr = wtap_file_get_shb_info(in_files[0].wth);
+ comment_gstr = g_string_new("");
+ g_string_append_printf(comment_gstr, "%s \n",shb_hdr->opt_comment);
+ g_string_append_printf(comment_gstr, "File created by merging: \n");
+ file_type = WTAP_FILE_PCAPNG;
+
+ 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 = g_string_free(comment_gstr, FALSE); /* 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 = "Wireshark"; /* NULL if not available, 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->number_of_interfaces = in_file_count; /* TODO make this the number of DIFFERENT encapsulation types
+ * check that snaplength is the same too?
+ */
+ idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+
+ for (i = 0; i < in_file_count; i++) {
+ idb_inf_merge_file = wtap_file_get_idb_info(in_files[i].wth);
+ /* read the interface data from the in file to our combined interfca data */
+ file_int_data = &g_array_index (idb_inf_merge_file->interface_data, wtapng_if_descr_t, 0);
+ int_data.wtap_encap = file_int_data->wtap_encap;
+ int_data.time_units_per_second = file_int_data->time_units_per_second;
+ int_data.link_type = file_int_data->link_type;
+ int_data.snap_len = file_int_data->snap_len;
+ int_data.if_name = g_strdup(file_int_data->if_name);
+ 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);
+ g_free(idb_inf_merge_file);
+
+ /* Set fake interface Id in per file data */
+ in_files[i].interface_id = i;
+ }
+
+ pdh = wtap_dump_fdopen_ng(out_fd, file_type,
+ selected_frame_type,
+ merge_max_snapshot_length(in_file_count, in_files),
+ FALSE /* compressed */, shb_hdr, idb_inf /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
+
+ if (pdh == NULL) {
+ ws_close(out_fd);
+ merge_close_in_files(in_file_count, in_files);
+ g_free(in_files);
+ cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
+ file_type);
+ return CF_ERROR;
+ }
+
+ }else{
+
+ pdh = wtap_dump_fdopen(out_fd, file_type,
+ selected_frame_type,
+ merge_max_snapshot_length(in_file_count, in_files),
+ FALSE /* compressed */, &open_err);
+ if (pdh == NULL) {
+ ws_close(out_fd);
+ merge_close_in_files(in_file_count, in_files);
+ g_free(in_files);
+ cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
+ file_type);
+ return CF_ERROR;
+ }
}
/* Get the sum of the sizes of all the files. */
@@ -1382,6 +1472,17 @@ cf_merge_files(char **out_filenamep, int in_file_count,
break;
}
+ /* If we have WTAP_ENCAP_PER_PACKETend the infiles are of type WTAP_FILE_PCAP
+ * we need to set the interface id in the paket header = the interface index we used
+ * in the IDBs interface description for this file(encapsulation type).
+ */
+ if(fake_interface_ids){
+ struct wtap_pkthdr *phdr;
+
+ phdr = wtap_phdr(in_file->wth);
+ phdr->interface_id = in_file->interface_id;
+ phdr->presence_flags = phdr->presence_flags | WTAP_HAS_INTERFACE_ID;
+ }
if (!wtap_dump(pdh, wtap_phdr(in_file->wth), wtap_pseudoheader(in_file->wth),
wtap_buf_ptr(in_file->wth), &write_err)) {
got_write_error = TRUE;