Wireshark: Add option to choose format type of capture file

The best heuristic can fail, so add possibility to manually choose
capture file format type, so not correctly recognize file format can be
loaded in Wireshark.

On the other side now it is possible to open capture file
as file format to be dissected.

Change-Id: I5a9f662b32ff7e042f753a92eaaa86c6e41f400a
Reviewed-on: https://code.wireshark.org/review/16
Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
Reviewed-by: Hadriel Kaplan <hadrielk@yahoo.com>
Reviewed-by: Evan Huus <eapache@gmail.com>
Tested-by: Evan Huus <eapache@gmail.com>
This commit is contained in:
Michal Labedzki 2014-01-18 15:20:02 +01:00 committed by Evan Huus
parent b6aae8d5c4
commit 579e7e19ce
27 changed files with 242 additions and 190 deletions

View File

@ -1126,6 +1126,7 @@ main(int argc, char *argv[])
* 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))) {
@ -1407,7 +1408,7 @@ main(int argc, char *argv[])
}
#endif /* HAVE_LIBGCRYPT */
wth = wtap_open_offline(argv[opt], &err, &err_info, FALSE);
wth = wtap_open_offline(argv[opt], WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if (!wth) {
fprintf(stderr, "capinfos: Can't open %s: %s\n", argv[opt],

View File

@ -236,7 +236,7 @@ capture_input_read_all(capture_session *cap_session, gboolean is_tempfile,
int err;
/* Capture succeeded; attempt to open the capture file. */
if (cf_open((capture_file *)cap_session->cf, capture_opts->save_file, is_tempfile, &err) != CF_OK) {
if (cf_open((capture_file *)cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err) != CF_OK) {
/* We're not doing a capture any more, so we don't have a save file. */
return FALSE;
}
@ -362,7 +362,7 @@ capture_input_new_file(capture_session *cap_session, gchar *new_file)
/* if we are in real-time mode, open the new file now */
if(capture_opts->real_time_mode) {
/* Attempt to open the capture file and set up to read from it. */
switch(cf_open((capture_file *)cap_session->cf, capture_opts->save_file, is_tempfile, &err)) {
switch(cf_open((capture_file *)cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
case CF_OK:
break;
case CF_ERROR:

View File

@ -221,7 +221,7 @@ gboolean capture_info_new_file(const char *new_filename)
wtap_close(info_data.wtap);
}
info_data.wtap = wtap_open_offline(new_filename, &err, &err_info, FALSE);
info_data.wtap = wtap_open_offline(new_filename, WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if (!info_data.wtap) {
err_msg = g_strdup_printf(cf_open_error_message(err, err_info, FALSE, WTAP_FILE_TYPE_SUBTYPE_UNKNOWN),
new_filename);

View File

@ -112,6 +112,7 @@ main(int argc, char *argv[])
* 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))) {
@ -143,7 +144,7 @@ main(int argc, char *argv[])
overall_error_status = 0;
for (i = 1; i < argc; i++) {
wth = wtap_open_offline(argv[i], &err, &err_info, FALSE);
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)));

View File

@ -884,6 +884,7 @@ main(int argc, char *argv[])
* Get credential information for later use.
*/
init_process_policies();
init_open_routines();
#ifdef HAVE_PLUGINS
/* Register wiretap plugins */
@ -1148,7 +1149,7 @@ main(int argc, char *argv[])
exit(1);
}
wth = wtap_open_offline(argv[optind], &err, &err_info, FALSE);
wth = wtap_open_offline(argv[optind], WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if (!wth) {
fprintf(stderr, "editcap: Can't open %s: %s\n", argv[optind],

10
file.c
View File

@ -336,12 +336,12 @@ ws_epan_new(capture_file *cf)
}
cf_status_t
cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
wtap *wth;
gchar *err_info;
wth = wtap_open_offline(fname, err, &err_info, TRUE);
wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
if (wth == NULL)
goto fail;
@ -4336,7 +4336,7 @@ rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
wtap_close(cf->wth);
/* Open the new file. */
cf->wth = wtap_open_offline(fname, err, &err_info, TRUE);
cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, err, &err_info, TRUE);
if (cf->wth == NULL) {
cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
return CF_READ_ERROR;
@ -4770,7 +4770,7 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
the wtap structure, the filename, and the "is temporary"
status applies to the new file; just update that. */
wtap_close(cf->wth);
cf->wth = wtap_open_offline(fname, &err, &err_info, TRUE);
cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
if (cf->wth == NULL) {
cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
cf_close(cf);
@ -5212,7 +5212,7 @@ cf_reload(capture_file *cf) {
filename = g_strdup(cf->filename);
is_tempfile = cf->is_tempfile;
cf->is_tempfile = FALSE;
if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
if (cf_open(cf, filename, WTAP_TYPE_AUTO, is_tempfile, &err) == CF_OK) {
switch (cf_read(cf, TRUE)) {
case CF_READ_OK:

3
file.h
View File

@ -108,11 +108,12 @@ cf_callback_remove(cf_callback_t func);
*
* @param cf the capture file to be opened
* @param fname the filename to be opened
* @param type WTAP_TYPE_AUTO for automatic or index to direct open routine
* @param is_tempfile is this a temporary file?
* @param err error code
* @return one of cf_status_t
*/
cf_status_t cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err);
cf_status_t cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err);
/**
* Close a capture file.

View File

@ -221,8 +221,10 @@ int main(int argc, char *argv[])
exit(1);
}
init_open_routines();
/* Open infile */
wth = wtap_open_offline(infile, &err, &err_info, TRUE);
wth = wtap_open_offline(infile, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
if (wth == NULL) {
fprintf(stderr, "reordercap: Can't open %s: %s\n", infile,
wtap_strerror(err));

View File

@ -906,6 +906,8 @@ main(int argc, char *argv[])
timestamp_set_precision(TS_PREC_AUTO);
timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
init_open_routines();
#ifdef HAVE_PLUGINS
/* Register all the plugin types we have. */
epan_register_plugin_types(); /* Types known to libwireshark */
@ -1425,7 +1427,7 @@ main(int argc, char *argv[])
relinquish_special_privs_perm();
print_current_user();
if (cf_open(&cfile, cf_name, FALSE, &err) != CF_OK) {
if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
epan_cleanup();
return 2;
}
@ -2498,7 +2500,7 @@ write_finale(void)
}
cf_status_t
cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
#if USE_FTAP
ftap *fth;
@ -2513,7 +2515,7 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
if (fth == NULL)
goto fail;
#else
wth = wtap_open_offline(fname, err, &err_info, perform_two_pass_analysis);
wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
if (wth == NULL)
goto fail;
#endif

View File

@ -1110,6 +1110,8 @@ main(int argc, char *argv[])
timestamp_set_precision(TS_PREC_AUTO);
timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
init_open_routines();
#ifdef HAVE_PLUGINS
/* Register all the plugin types we have. */
epan_register_plugin_types(); /* Types known to libwireshark */
@ -1999,7 +2001,7 @@ main(int argc, char *argv[])
relinquish_special_privs_perm();
print_current_user();
if (cf_open(&cfile, cf_name, FALSE, &err) != CF_OK) {
if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
epan_cleanup();
return 2;
}
@ -2594,7 +2596,7 @@ capture_input_new_file(capture_session *cap_session, gchar *new_file)
/* if we are in real-time mode, open the new file now */
if (do_dissection) {
/* Attempt to open the capture file and set up to read from it. */
switch(cf_open((capture_file *)cap_session->cf, capture_opts->save_file, is_tempfile, &err)) {
switch(cf_open((capture_file *)cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
case CF_OK:
break;
case CF_ERROR:
@ -3945,13 +3947,13 @@ write_finale(void)
}
cf_status_t
cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
wtap *wth;
gchar *err_info;
char err_msg[2048+1];
wth = wtap_open_offline(fname, err, &err_info, perform_two_pass_analysis);
wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
if (wth == NULL)
goto fail;

View File

@ -139,7 +139,7 @@ preview_set_filename(GtkWidget *prev, const gchar *cf_name)
return NULL;
}
wth = wtap_open_offline(cf_name, &err, &err_info, TRUE);
wth = wtap_open_offline(cf_name, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
if (wth == NULL) {
label = (GtkWidget *)g_object_get_data(G_OBJECT(prev), PREVIEW_FORMAT_KEY);
if (err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
@ -474,11 +474,14 @@ preview_new(void)
/* Open a file */
static gboolean
gtk_open_file(GtkWidget *w, GString *file_name, GString *display_filter)
gtk_open_file(GtkWidget *w, GString *file_name, gint *type, GString *display_filter)
{
GtkWidget *file_open_w;
GtkWidget *main_hb, *main_vb, *filter_hbox, *filter_bt, *filter_te;
GtkWidget *m_resolv_cb, *n_resolv_cb, *t_resolv_cb, *e_resolv_cb, *prev;
GtkWidget *format_type_co;
GtkCellRenderer *cell;
gint i;
/* No Apply button, and "OK" just sets our text widget, it doesn't
activate it (i.e., it doesn't cause us to try to open the file). */
@ -542,6 +545,21 @@ gtk_open_file(GtkWidget *w, GString *file_name, GString *display_filter)
gtk_box_pack_start(GTK_BOX(main_hb), main_vb, FALSE, FALSE, 0);
gtk_widget_show(main_vb);
format_type_co = gtk_combo_box_text_new();
cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(format_type_co), cell, TRUE);
gtk_widget_set_tooltip_text(format_type_co, "Format type of capture file");
gtk_box_pack_start(GTK_BOX(main_vb), format_type_co, FALSE, FALSE, 0);
gtk_combo_box_text_append_text((GtkComboBoxText *) format_type_co, (const gchar *) "Automatic");
for (i = 0; open_routines[i].name != NULL; i += 1) {
gtk_combo_box_text_append_text((GtkComboBoxText *) format_type_co, open_routines[i].name);
}
gtk_combo_box_set_active((GtkComboBox *) format_type_co, 0);
gtk_widget_show(format_type_co);
/* Filter row */
filter_hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1, FALSE);
gtk_container_set_border_width(GTK_CONTAINER(filter_hbox), 0);
@ -639,6 +657,8 @@ gtk_open_file(GtkWidget *w, GString *file_name, GString *display_filter)
else
gbl_resolv_flags.use_external_net_name_resolver = FALSE;
*type = gtk_combo_box_get_active((GtkComboBox *) format_type_co);
/* We've crossed the Rubicon; get rid of the file selection box. */
window_destroy(GTK_WIDGET(file_open_w));
@ -666,6 +686,7 @@ file_open_cmd(capture_file *cf, GtkWidget *w _U_)
GString *display_filter = g_string_new("");
dfilter_t *rfcode = NULL;
int err;
int type = WTAP_TYPE_AUTO;
/*
* Loop until the user either selects a file or gives up.
@ -674,7 +695,7 @@ file_open_cmd(capture_file *cf, GtkWidget *w _U_)
#ifdef USE_WIN32_FILE_DIALOGS
if (win32_open_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level)), file_name, display_filter)) {
#else /* USE_WIN32_FILE_DIALOGS */
if (gtk_open_file(top_level, file_name, display_filter)) {
if (gtk_open_file(top_level, file_name, &type, display_filter)) {
#endif /* USE_WIN32_FILE_DIALOGS */
/* Only close the old file now that we know we want to open another one. */
@ -690,7 +711,7 @@ file_open_cmd(capture_file *cf, GtkWidget *w _U_)
}
/* Try to open the capture file. */
if (cf_open(&cfile, file_name->str, FALSE, &err) != CF_OK) {
if (cf_open(&cfile, file_name->str, type, FALSE, &err) != CF_OK) {
/* We couldn't open it; don't dismiss the open dialog box,
just leave it around so that the user can, after they
dismiss the alert box popped up for the open error,
@ -971,7 +992,7 @@ file_merge_cmd(GtkWidget *w _U_)
cf_close(&cfile);
/* Try to open the merged capture file. */
if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) {
if (cf_open(&cfile, tmpname, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) {
/* We couldn't open it; fail. */
if (rfcode != NULL)
dfilter_free(rfcode);

View File

@ -204,7 +204,7 @@ dnd_open_file_cmd(gchar *cf_names_freeme)
if (in_file_count == 1) {
/* open and read the capture file (this will close an existing file) */
if (cf_open(&cfile, in_filenames[0], FALSE, &err) == CF_OK) {
if (cf_open(&cfile, in_filenames[0], WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
/* XXX - add this to the menu if the read fails? */
cf_read(&cfile, FALSE);
add_menu_recent_capture_file(in_filenames[0]);
@ -219,7 +219,7 @@ dnd_open_file_cmd(gchar *cf_names_freeme)
/* Merge succeeded; close the currently-open file and try
to open the merged capture file. */
cf_close(&cfile);
if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) == CF_OK) {
if (cf_open(&cfile, tmpname, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) == CF_OK) {
g_free(tmpname);
cf_read(&cfile, FALSE);
} else {

View File

@ -541,7 +541,7 @@ file_import_open(text_import_info_t *info)
write_failure_alert_box(capfile_name, err);
}
if (cf_open(&cfile, capfile_name, TRUE /* temporary file */, &err) != CF_OK) {
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;
}

View File

@ -79,7 +79,7 @@ fs_open_entry(fileset_entry *entry)
/* close the old and open the new file */
cf_close(&cfile);
if (cf_open(&cfile, fname, FALSE, &err) == CF_OK) {
if (cf_open(&cfile, fname, WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
cf_read(&cfile, FALSE);
}

View File

@ -518,7 +518,7 @@ static gboolean funnel_open_file(const char* fname, const char* filter, const ch
}
if (cf_open(&cfile, fname, FALSE, &err) != CF_OK) {
if (cf_open(&cfile, fname, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
*err_str = g_strerror(err);
if (rfcode != NULL) dfilter_free(rfcode);
return FALSE;

View File

@ -2523,6 +2523,8 @@ main(int argc, char *argv[])
g_free(init_progfile_dir_error);
}
init_open_routines();
#ifdef HAVE_PLUGINS
/* Register all the plugin types we have. */
epan_register_plugin_types(); /* Types known to libwireshark */
@ -3088,7 +3090,7 @@ main(int argc, char *argv[])
}
}
if (!rfilter_parse_failed) {
if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
/* "cf_open()" succeeded, so it closed the previous
capture file, and thus destroyed any previous read filter
attached to "cf". */

View File

@ -4323,7 +4323,7 @@ menu_open_filename(gchar *cf_name)
recent_files_list = (GList *)g_object_get_data(G_OBJECT(submenu_recent_files), "recent-files-list");
/* XXX: ask user to remove item, it's maybe only a temporary problem */
/* open and read the capture file (this will close an existing file) */
if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
cf_read(&cfile, FALSE);
}else{
recent_files_list = remove_present_file_name(recent_files_list, cf_name);
@ -4351,7 +4351,7 @@ menu_open_recent_file_cmd(GtkAction *action)
#endif
/* open and read the capture file (this will close an existing file) */
if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
cf_read(&cfile, FALSE);
} else {
submenu_recent_files = gtk_ui_manager_get_widget(ui_manager_main_menubar, MENU_RECENT_FILES_PATH);

View File

@ -231,7 +231,7 @@ bool CaptureFileDialog::isCompressed() {
return compressed_;
}
int CaptureFileDialog::open(QString &file_name) {
int CaptureFileDialog::open(QString &file_name, unsigned int &type) {
GString *fname = g_string_new(file_name.toUtf8().constData());
GString *dfilter = g_string_new(display_filter_.toUtf8().constData());
gboolean wof_status;
@ -239,6 +239,7 @@ int CaptureFileDialog::open(QString &file_name) {
// XXX Add a widget->HWND routine to qt_ui_utils and use it instead.
wof_status = win32_open_file((HWND)parentWidget()->effectiveWinId(), fname, dfilter);
file_name = fname->str;
type = format_type_.currentIndex();
display_filter_ = dfilter->str;
g_string_free(fname, TRUE);
@ -499,6 +500,15 @@ void CaptureFileDialog::addDisplayFilterEdit() {
last_row_++;
}
void CaptureFileDialog::addFormatTypeSelector(QVBoxLayout &v_box) {
format_type_.addItem("Automatic");
for (int i = 0; open_routines[i].name != NULL; i += 1) {
format_type_.addItem(open_routines[i].name);
}
v_box.addWidget(&format_type_, 0, Qt::AlignTop);
}
void CaptureFileDialog::addResolutionControls(QVBoxLayout &v_box) {
mac_res_.setText(tr("&MAC name resolution"));
mac_res_.setChecked(gbl_resolv_flags.mac_name);
@ -548,11 +558,12 @@ QDialogButtonBox *CaptureFileDialog::addHelpButton(topic_action_e help_topic)
return button_box;
}
int CaptureFileDialog::open(QString &file_name) {
int CaptureFileDialog::open(QString &file_name, unsigned int &type) {
setWindowTitle(tr("Wireshark: Open Capture File"));
setNameFilters(buildFileOpenTypeList());
setFileMode(QFileDialog::ExistingFile);
addFormatTypeSelector(left_v_box_);
addDisplayFilterEdit();
addResolutionControls(left_v_box_);
addPreview(right_v_box_);
@ -569,6 +580,7 @@ int CaptureFileDialog::open(QString &file_name) {
if (QFileDialog::exec() && selectedFiles().length() > 0) {
file_name = selectedFiles()[0];
type = format_type_.currentIndex();
display_filter_.append(display_filter_edit_->text());
gbl_resolv_flags.mac_name = mac_res_.isChecked();
@ -761,7 +773,7 @@ void CaptureFileDialog::preview(const QString & path)
return;
}
wth = wtap_open_offline(path.toUtf8().data(), &err, &err_info, TRUE);
wth = wtap_open_offline(path.toUtf8().data(), WTAP_TYPE_AUTO, &err, &err_info, TRUE);
if (wth == NULL) {
if(err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
preview_format_.setText(tr("unknown file format"));

View File

@ -41,6 +41,7 @@
#include <QRadioButton>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QComboBox>
class CaptureFileDialog : public QFileDialog
{
@ -87,6 +88,7 @@ private:
#if !defined(Q_OS_WIN)
void addMergeControls(QVBoxLayout &v_box);
void addFormatTypeSelector(QVBoxLayout &v_box);
void addDisplayFilterEdit();
void addPreview(QVBoxLayout &v_box);
QString fileExtensionType(int et, bool extension_globs = true);
@ -110,6 +112,7 @@ private:
QRadioButton merge_chrono_;
QRadioButton merge_append_;
QComboBox format_type_;
QHash<QString, int>type_hash_;
void addResolutionControls(QVBoxLayout &v_box);
@ -143,7 +146,7 @@ signals:
public slots:
int exec();
int open(QString &file_name);
int open(QString &file_name, unsigned int &type);
check_savability_t saveAs(QString &file_name, bool must_support_comments);
check_savability_t exportSelectedPackets(QString &file_name, packet_range_t *range);
int merge(QString &file_name);

View File

@ -832,6 +832,8 @@ int main(int argc, char *argv[])
init_report_err(failure_alert_box, open_failure_alert_box,
read_failure_alert_box, write_failure_alert_box);
init_open_routines();
#ifdef HAVE_PLUGINS
/* Register all the plugin types we have. */
epan_register_plugin_types(); /* Types known to libwireshark */

View File

@ -643,7 +643,7 @@ void MainWindow::mergeCaptureFile()
/* Try to open the merged capture file. */
cfile.window = this;
if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) {
if (cf_open(&cfile, tmpname, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) {
/* We couldn't open it; fail. */
cfile.window = NULL;
if (rfcode != NULL)

View File

@ -102,6 +102,7 @@ void MainWindow::openCaptureFile(QString &cf_path, QString &display_filter)
QString file_name = "";
dfilter_t *rfcode = NULL;
int err;
unsigned int type;
testCaptureFileClose(false);
@ -130,7 +131,7 @@ void MainWindow::openCaptureFile(QString &cf_path, QString &display_filter)
break;
}
if (open_dlg.open(file_name)) {
if (open_dlg.open(file_name, type)) {
if (dfilter_compile(display_filter.toUtf8().constData(), &rfcode)) {
cf_set_rfcode(&cfile, rfcode);
} else {
@ -153,7 +154,7 @@ void MainWindow::openCaptureFile(QString &cf_path, QString &display_filter)
/* Try to open the capture file. */
cfile.window = this;
if (cf_open(&cfile, cf_path.toUtf8().constData(), FALSE, &err) != CF_OK) {
if (cf_open(&cfile, cf_path.toUtf8().constData(), type, FALSE, &err) != CF_OK) {
/* We couldn't open it; don't dismiss the open dialog box,
just leave it around so that the user can, after they
dismiss the alert box popped up for the open error,

View File

@ -162,7 +162,7 @@ exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
remove_tap_listener(exp_pdu_tap_data);
if (cf_open(&cfile, capfile_name, TRUE /* temporary file */, &err) != CF_OK) {
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;
}

View File

@ -1157,7 +1157,7 @@ preview_set_file_info(HWND of_hwnd, gchar *preview_file) {
return FALSE;
}
wth = wtap_open_offline(preview_file, &err, &err_info, TRUE);
wth = wtap_open_offline(preview_file, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
if (cur_ctrl && wth == NULL) {
if(err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
SetWindowText(cur_ctrl, _T("unknown file format"));

View File

@ -301,149 +301,98 @@ GSList *wtap_get_all_file_extensions_list(void)
* just overwrite the pointer.
*/
/* Files that have magic bytes in fixed locations. These
* are easy to identify. Only an open routine is needed.
*/
static const wtap_open_routine_t magic_number_open_routines_base[] = {
libpcap_open,
pcapng_open,
ngsniffer_open,
snoop_open,
iptrace_open,
netmon_open,
netxray_open,
radcom_open,
nettl_open,
visual_open,
_5views_open,
network_instruments_open,
peektagged_open,
dbs_etherwatch_open,
k12_open,
catapult_dct2000_open,
aethra_open,
btsnoop_open,
eyesdn_open,
tnef_open,
static struct open_info open_info_base[] = {
{ "Pcap", OPEN_INFO_MAGIC, libpcap_open, "pcap" },
{ "PcapNG", OPEN_INFO_MAGIC, pcapng_open, "pcapng"},
{ "NgSniffer", OPEN_INFO_MAGIC, ngsniffer_open, NULL },
{ "Snoop", OPEN_INFO_MAGIC, snoop_open, NULL },
{ "IP Trace", OPEN_INFO_MAGIC, iptrace_open, NULL },
{ "Netmon", OPEN_INFO_MAGIC, netmon_open, NULL },
{ "Netxray", OPEN_INFO_MAGIC, netxray_open, NULL },
{ "Radcom", OPEN_INFO_MAGIC, radcom_open, NULL },
{ "Nettl", OPEN_INFO_MAGIC, nettl_open, NULL },
{ "Visual", OPEN_INFO_MAGIC, visual_open, NULL },
{ "5 Views", OPEN_INFO_MAGIC, _5views_open, NULL },
{ "Network Instruments", OPEN_INFO_MAGIC, network_instruments_open, NULL },
{ "Peek Tagged", OPEN_INFO_MAGIC, peektagged_open, NULL },
{ "DBS Etherwatch", OPEN_INFO_MAGIC, dbs_etherwatch_open, NULL },
{ "K12", OPEN_INFO_MAGIC, k12_open, NULL },
{ "Catapult DCT 2000", OPEN_INFO_MAGIC, catapult_dct2000_open, NULL },
{ "Aethra", OPEN_INFO_MAGIC, aethra_open, NULL },
{ "BTSNOOP", OPEN_INFO_MAGIC, btsnoop_open, "log" },
{ "EYESDN", OPEN_INFO_MAGIC, eyesdn_open, NULL },
{ "TNEF", OPEN_INFO_MAGIC, tnef_open, NULL },
{ "MIME Files with Magic Bytes", OPEN_INFO_MAGIC, mime_file_open, NULL },
{ "Lanalyzer", OPEN_INFO_HEURISTIC, lanalyzer_open, "tr1" },
/*
* PacketLogger must come before MPEG, because its files
* are sometimes grabbed by mpeg_open.
*/
{ "Packet Logger", OPEN_INFO_HEURISTIC, packetlogger_open, "pklg" },
/* Some MPEG files have magic numbers, others just have heuristics. */
{ "Mpeg", OPEN_INFO_HEURISTIC, mpeg_open, "mpg;mp3" },
{ "DCT3 Trace", OPEN_INFO_HEURISTIC, dct3trace_open, "xml" },
{ "Daintree SNA", OPEN_INFO_HEURISTIC, daintree_sna_open, "dcf" },
{ "Stanag 4607", OPEN_INFO_HEURISTIC, stanag4607_open, NULL },
{ "BER", OPEN_INFO_HEURISTIC, ber_open, NULL },
/* I put NetScreen *before* erf, because there were some
* false positives with my test-files (Sake Blok, July 2007)
*
* I put VWR *after* ERF, because there were some cases where
* ERF files were misidentified as vwr files (Stephen
* Donnelly, August 2013; see bug 9054)
*
* I put VWR *after* Peek Classic, CommView, iSeries text,
* Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
* because there were some cases where files of those types were
* misidentified as vwr files (Guy Harris, December 2013)
*/
{ "Netscreen", OPEN_INFO_HEURISTIC, netscreen_open, "txt" },
{ "ERF", OPEN_INFO_HEURISTIC, erf_open, "erf" },
{ "IPfix", OPEN_INFO_HEURISTIC, ipfix_open, "pfx;ipfix" },
{ "K12 Text", OPEN_INFO_HEURISTIC, k12text_open, "txt" },
{ "Peek Classic", OPEN_INFO_HEURISTIC, peekclassic_open, "pkt;tpc;apc;wpz" },
{ "PPP Dump", OPEN_INFO_HEURISTIC, pppdump_open, NULL },
{ "iSeries", OPEN_INFO_HEURISTIC, iseries_open, "txt" },
{ "i4btrace", OPEN_INFO_HEURISTIC, i4btrace_open, NULL },
{ "Mp2t", OPEN_INFO_HEURISTIC, mp2t_open, "ts;mpg" },
{ "Csids", OPEN_INFO_HEURISTIC, csids_open, NULL },
{ "VMS", OPEN_INFO_HEURISTIC, vms_open, "txt" },
{ "Cosine", OPEN_INFO_HEURISTIC, cosine_open, "txt" },
{ "Hcidump", OPEN_INFO_HEURISTIC, hcidump_open, NULL },
{ "Commview", OPEN_INFO_HEURISTIC, commview_open, "ncf" },
{ "Nstrace", OPEN_INFO_HEURISTIC, nstrace_open, "txt" },
/* ASCII trace files from Telnet sessions. */
{ "Ascend", OPEN_INFO_HEURISTIC, ascend_open, "txt" },
{ "Toshiba", OPEN_INFO_HEURISTIC, toshiba_open, "txt" },
/* Extremely weak heuristics - put them at the end. */
{ "VWR", OPEN_INFO_HEURISTIC, vwr_open, "vwr" },
{ "Camins", OPEN_INFO_HEURISTIC, camins_open, "camins" },
{ NULL, 0, NULL, NULL}
};
#define N_MAGIC_FILE_TYPES (sizeof magic_number_open_routines_base / sizeof magic_number_open_routines_base[0])
#define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
static wtap_open_routine_t* magic_number_open_routines = NULL;
struct open_info *open_routines = NULL;
static GArray* magic_number_open_routines_arr = NULL;
static GArray *open_info_arr = NULL;
/*
* Initialize the magic-number open routines array if it has not been
* initialized yet.
*/
static void init_magic_number_open_routines(void) {
void init_open_routines(void) {
if (magic_number_open_routines_arr) return;
if (open_info_arr) return;
magic_number_open_routines_arr = g_array_new(FALSE,TRUE,sizeof(wtap_open_routine_t));
open_info_arr = g_array_new(FALSE,TRUE,sizeof(struct open_info));
g_array_append_vals(magic_number_open_routines_arr,magic_number_open_routines_base,N_MAGIC_FILE_TYPES);
g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
magic_number_open_routines = (wtap_open_routine_t*)(void *)magic_number_open_routines_arr->data;
open_routines = (struct open_info *) open_info_arr->data;
}
void wtap_register_magic_number_open_routine(wtap_open_routine_t open_routine) {
init_magic_number_open_routines();
void wtap_register_open_info(const struct open_info *oi) {
init_open_routines();
g_array_append_val(magic_number_open_routines_arr,open_routine);
g_array_append_val(open_info_arr, oi);
magic_number_open_routines = (wtap_open_routine_t*)(void *)magic_number_open_routines_arr->data;
}
/* Files that don't have magic bytes at a fixed location,
* but that instead require a heuristic of some sort to
* identify them. This includes ASCII trace files.
*
* Entries for the ASCII trace files that would be, for example,
* saved copies of a Telnet session to some box are put after
* most of the other entries, as we don't want to treat a capture
* of such a session as a trace file from such a session
* merely because it has the right text in it. They still
* appear before the *really* weak entries, such as the VWR entry.
*/
static const struct heuristic_open_info heuristic_open_info_base[] = {
{ lanalyzer_open, "tr1", },
/*
* PacketLogger must come before MPEG, because its files
* are sometimes grabbed by mpeg_open.
*/
{ packetlogger_open, "pklg" },
/* Some MPEG files have magic numbers, others just have heuristics. */
{ mpeg_open, "mpg;mp3" },
{ dct3trace_open, "xml" },
{ daintree_sna_open, "dcf" },
{ mime_file_open, NULL },
{ stanag4607_open, NULL },
{ ber_open, NULL },
/* I put NetScreen *before* erf, because there were some
* false positives with my test-files (Sake Blok, July 2007)
*
* I put VWR *after* ERF, because there were some cases where
* ERF files were misidentified as vwr files (Stephen
* Donnelly, August 2013; see bug 9054)
*
* I put VWR *after* Peek Classic, CommView, iSeries text,
* Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
* because there were some cases where files of those types were
* misidentified as vwr files (Guy Harris, December 2013)
*/
{ netscreen_open, "txt" },
{ erf_open, "erf" },
{ ipfix_open, "pfx;ipfix" },
{ k12text_open, "txt" },
{ peekclassic_open, "pkt;tpc;apc;wpz" },
{ pppdump_open, NULL },
{ iseries_open, "txt" },
{ i4btrace_open, NULL },
{ mp2t_open, "ts;mpg" },
{ csids_open, NULL },
{ vms_open, "txt" },
{ cosine_open, "txt" },
{ hcidump_open, NULL },
{ commview_open, "ncf" },
{ nstrace_open, "txt" },
/* ASCII trace files from Telnet sessions. */
{ ascend_open, "txt" },
{ toshiba_open, "txt" },
/* Extremely weak heuristics - put them at the end. */
{ vwr_open, "vwr" },
{ camins_open, "camins" },
};
#define N_HEURISTIC_FILE_TYPES (sizeof heuristic_open_info_base / sizeof heuristic_open_info_base[0])
static const struct heuristic_open_info* heuristic_open_info = NULL;
static GArray* heuristic_open_info_arr = NULL;
/*
* Initialize the heuristics array if it has not been initialized yet.
*/
static void init_heuristic_open_info(void) {
if (heuristic_open_info_arr) return;
heuristic_open_info_arr = g_array_new(FALSE,TRUE,sizeof(struct heuristic_open_info));
g_array_append_vals(heuristic_open_info_arr,heuristic_open_info_base,N_HEURISTIC_FILE_TYPES);
heuristic_open_info = (const struct heuristic_open_info*)(void *)heuristic_open_info_arr->data;
}
void wtap_register_heuristic_open_info(const struct heuristic_open_info *hi) {
init_heuristic_open_info();
g_array_append_val(heuristic_open_info_arr,*hi);
heuristic_open_info = (const struct heuristic_open_info*)(void *)heuristic_open_info_arr->data;
open_routines = (struct open_info *) open_info_arr->data;
}
/*
@ -566,13 +515,13 @@ static gboolean heuristic_uses_extension(unsigned int i, const char *extension)
/*
* Does this file type *have* any extensions?
*/
if (heuristic_open_info[i].extensions == NULL)
if (open_routines[i].extensions == NULL)
return FALSE; /* no */
/*
* Get a list of the extensions used by the specified file type.
*/
extensions_set = g_strsplit(heuristic_open_info[i].extensions, ";", 0);
extensions_set = g_strsplit(open_routines[i].extensions, ";", 0);
/*
* Check each of them against the specified extension.
@ -595,7 +544,7 @@ static gboolean heuristic_uses_extension(unsigned int i, const char *extension)
so that it can do sequential I/O to a capture file that's being
written to as new packets arrive independently of random I/O done
to display protocol trees for packets when they're selected. */
wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
gboolean do_random)
{
int fd;
@ -719,8 +668,6 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
wth->tsprecision = WTAP_FILE_TSPREC_USEC;
wth->priv = NULL;
init_magic_number_open_routines();
init_heuristic_open_info();
if (wth->random_fh) {
wth->fast_seek = g_ptr_array_new();
@ -728,8 +675,35 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
file_set_random_access(wth->random_fh, TRUE, wth->fast_seek);
}
if (type != 0 && type <= open_info_arr->len + 1) {
int result;
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
/* I/O error - give up */
wtap_close(wth);
return NULL;
}
result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
switch (result) {
case -1:
/* I/O error - give up */
wtap_close(wth);
return NULL;
case 0:
/* No I/O error, but not that type of file */
goto fail;
case 1:
/* We found the file type */
goto success;
}
}
/* Try all file types that support magic numbers */
for (i = 0; i < magic_number_open_routines_arr->len; i++) {
for (i = 0; i < open_info_arr->len - 1; i++) {
/* Seek back to the beginning of the file; the open routine
for the previous file type may have left the file
position somewhere other than the beginning, and the
@ -737,13 +711,15 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
to start reading at the beginning.
Initialize the data offset while we're at it. */
if (open_routines[i].type != OPEN_INFO_MAGIC) continue;
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
/* I/O error - give up */
wtap_close(wth);
return NULL;
}
switch ((*magic_number_open_routines[i])(wth, err, err_info)) {
switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
case -1:
/* I/O error - give up */
@ -764,8 +740,10 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
extension = get_file_extension(filename);
if (extension != NULL) {
/* Yes - try the heuristic types that use that extension first. */
for (i = 0; i < heuristic_open_info_arr->len; i++) {
for (i = 0; i < open_info_arr->len - 1; i++) {
if (open_routines[i].type != OPEN_INFO_HEURISTIC) continue;
/* Does this type use that extension? */
if (heuristic_uses_extension(i, extension)) {
/* Yes. */
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
@ -775,7 +753,7 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
return NULL;
}
switch ((*heuristic_open_info[i].open_routine)(wth,
switch ((*open_routines[i].open_routine)(wth,
err, err_info)) {
case -1:
@ -797,7 +775,8 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
}
/* Now try the ones that don't use it. */
for (i = 0; i < heuristic_open_info_arr->len; i++) {
for (i = 0; i < open_info_arr->len - 1; i++) {
if (open_routines[i].type != OPEN_INFO_HEURISTIC) continue;
/* Does this type use that extension? */
if (!heuristic_uses_extension(i, extension)) {
/* No. */
@ -808,7 +787,7 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
return NULL;
}
switch ((*heuristic_open_info[i].open_routine)(wth,
switch ((*open_routines[i].open_routine)(wth,
err, err_info)) {
case -1:
@ -831,15 +810,16 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
g_free(extension);
} else {
/* No - try all the heuristics types in order. */
for (i = 0; i < heuristic_open_info_arr->len; i++) {
for (i = 0; i < open_info_arr->len - 1; i++) {
if (open_routines[i].type != OPEN_INFO_HEURISTIC) continue;
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
/* I/O error - give up */
wtap_close(wth);
return NULL;
}
switch ((*heuristic_open_info[i].open_routine)(wth,
err, err_info)) {
switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
case -1:
/* I/O error - give up */
@ -857,6 +837,8 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
}
}
fail:
/* Well, it's not one of the types of file we know about. */
wtap_close(wth);
*err = WTAP_ERR_FILE_UNKNOWN_FORMAT;

View File

@ -62,7 +62,7 @@ merge_open_in_files(int in_file_count, char *const *in_file_names,
for (i = 0; i < in_file_count; i++) {
files[i].filename = in_file_names[i];
files[i].wth = wtap_open_offline(in_file_names[i], err, err_info, FALSE);
files[i].wth = wtap_open_offline(in_file_names[i], WTAP_TYPE_AUTO, err, err_info, FALSE);
files[i].data_offset = 0;
files[i].state = PACKET_NOT_PRESENT;
files[i].packet_num = 0;

View File

@ -1201,10 +1201,23 @@ typedef int (*wtap_open_routine_t)(struct wtap*, int *, char **);
* the ones that don't, to handle the case where a file of one type
* might be recognized by the heuristics for a different file type.
*/
struct heuristic_open_info {
/*struct heuristic_open_info {
wtap_open_routine_t open_routine;
const char *extensions;
};
*/
#define OPEN_INFO_MAGIC 0
#define OPEN_INFO_HEURISTIC 1
WS_DLL_PUBLIC void init_open_routines(void);
struct open_info {
const char *name;
int type;
wtap_open_routine_t open_routine;
const char *extensions;
};
WS_DLL_PUBLIC struct open_info *open_routines;
/*
* Types of comments.
@ -1251,11 +1264,13 @@ struct file_type_subtype_info {
int (*dump_open)(wtap_dumper *, int *);
};
#define WTAP_TYPE_AUTO 0
/** On failure, "wtap_open_offline()" returns NULL, and puts into the
* "int" pointed to by its second argument:
*
* @param filename Name of the file to open
* @param type WTAP_TYPE_AUTO for automatic recognize file format or explicit choose format type
* @param err a positive "errno" value if the capture file can't be opened;
* a negative number, indicating the type of error, on other failures.
* @param err_info for some errors, a string giving more details of
@ -1264,7 +1279,7 @@ struct file_type_subtype_info {
* FALSE if not
*/
WS_DLL_PUBLIC
struct wtap* wtap_open_offline(const char *filename, int *err,
struct wtap* wtap_open_offline(const char *filename, unsigned int type, int *err,
gchar **err_info, gboolean do_random);
/**
@ -1471,10 +1486,14 @@ WS_DLL_PUBLIC
void register_all_wiretap_modules(void);
WS_DLL_PUBLIC
void wtap_register_file_type_extension(const struct file_extension_info *ei);
#if 0
WS_DLL_PUBLIC
void wtap_register_magic_number_open_routine(wtap_open_routine_t open_routine);
WS_DLL_PUBLIC
void wtap_register_heuristic_open_info(const struct heuristic_open_info *oi);
#endif
WS_DLL_PUBLIC
void wtap_register_open_info(const struct open_info *oi);
WS_DLL_PUBLIC
int wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi);
WS_DLL_PUBLIC