aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2014-01-18 15:20:02 +0100
committerEvan Huus <eapache@gmail.com>2014-02-25 17:43:13 +0000
commit579e7e19ce8e5f1a6e16b75f130ad4b001157ca5 (patch)
tree423547b0256e93647f98710cf14e15e112f7f73f /wiretap
parentb6aae8d5c470aa681b70f33cad064dbb7045b3b7 (diff)
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>
Diffstat (limited to 'wiretap')
-rw-r--r--wiretap/file_access.c272
-rw-r--r--wiretap/merge.c2
-rw-r--r--wiretap/wtap.h23
3 files changed, 149 insertions, 148 deletions
diff --git a/wiretap/file_access.c b/wiretap/file_access.c
index 0ea55b42c8..97b9c7f5f6 100644
--- a/wiretap/file_access.c
+++ b/wiretap/file_access.c
@@ -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,
-};
-#define N_MAGIC_FILE_TYPES (sizeof magic_number_open_routines_base / sizeof magic_number_open_routines_base[0])
-
-static wtap_open_routine_t* magic_number_open_routines = NULL;
-
-static GArray* magic_number_open_routines_arr = NULL;
-
-/*
- * Initialize the magic-number open routines array if it has not been
- * initialized yet.
- */
-static void init_magic_number_open_routines(void) {
-
- if (magic_number_open_routines_arr) return;
-
- magic_number_open_routines_arr = g_array_new(FALSE,TRUE,sizeof(wtap_open_routine_t));
-
- g_array_append_vals(magic_number_open_routines_arr,magic_number_open_routines_base,N_MAGIC_FILE_TYPES);
-
- magic_number_open_routines = (wtap_open_routine_t*)(void *)magic_number_open_routines_arr->data;
-}
-
-void wtap_register_magic_number_open_routine(wtap_open_routine_t open_routine) {
- init_magic_number_open_routines();
-
- g_array_append_val(magic_number_open_routines_arr,open_routine);
-
- 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" },
+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_HEURISTIC_FILE_TYPES (sizeof heuristic_open_info_base / sizeof heuristic_open_info_base[0])
+#define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
-static const struct heuristic_open_info* heuristic_open_info = NULL;
+struct open_info *open_routines = NULL;
-static GArray* heuristic_open_info_arr = NULL;
+static GArray *open_info_arr = NULL;
-/*
- * Initialize the heuristics array if it has not been initialized yet.
- */
-static void init_heuristic_open_info(void) {
+void init_open_routines(void) {
- if (heuristic_open_info_arr) return;
+ if (open_info_arr) return;
- heuristic_open_info_arr = g_array_new(FALSE,TRUE,sizeof(struct heuristic_open_info));
+ open_info_arr = g_array_new(FALSE,TRUE,sizeof(struct open_info));
- g_array_append_vals(heuristic_open_info_arr,heuristic_open_info_base,N_HEURISTIC_FILE_TYPES);
+ g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
- heuristic_open_info = (const struct heuristic_open_info*)(void *)heuristic_open_info_arr->data;
+ open_routines = (struct open_info *) open_info_arr->data;
}
-void wtap_register_heuristic_open_info(const struct heuristic_open_info *hi) {
- init_heuristic_open_info();
+void wtap_register_open_info(const struct open_info *oi) {
+ init_open_routines();
- g_array_append_val(heuristic_open_info_arr,*hi);
+ g_array_append_val(open_info_arr, oi);
- 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;
diff --git a/wiretap/merge.c b/wiretap/merge.c
index 34f71ec7c5..547c60b814 100644
--- a/wiretap/merge.c
+++ b/wiretap/merge.c
@@ -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;
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 1831565030..a5d8c51b4a 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -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