diff options
author | Anders Broman <anders.broman@ericsson.com> | 2012-08-08 14:06:29 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2012-08-08 14:06:29 +0000 |
commit | ae5a2f3b6df1c3c02450350e1e1c98488d6d3813 (patch) | |
tree | 15df29d5363afa418958a7be76298845a6d3a053 /file.c | |
parent | bbd9a397f878fc2b7171c2a9f47dbc69b97d1daf (diff) |
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.c | 123 |
1 files changed, 112 insertions, 11 deletions
@@ -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; |