forked from osmocom/wireshark
Make it possible to merge libpcap files with different encapsulation types by making the output file a pcapng file and construkting SHB and IDB
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@44338 f5534014-38df-0310-8fa8-9805f1628bb7
This commit is contained in:
parent
1dbd5cb48e
commit
990e03675e
123
file.c
123
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;
|
||||
|
|
6
merge.h
6
merge.h
|
@ -44,8 +44,10 @@ typedef struct merge_in_file_s {
|
|||
wtap *wth;
|
||||
gint64 data_offset;
|
||||
in_file_state_e state;
|
||||
guint32 packet_num; /* current packet number */
|
||||
gint64 size; /* file size */
|
||||
guint32 packet_num; /* current packet number */
|
||||
gint64 size; /* file size */
|
||||
guint32 interface_id; /* identifier of the interface.
|
||||
* Used for fake interfaces when writing WTAP_ENCAP_PER_PACKET */
|
||||
} merge_in_file_t;
|
||||
|
||||
/** Open a number of input files to merge.
|
||||
|
|
Loading…
Reference in New Issue