#include "config.h"
-#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
#include <errno.h>
#include <wsutil/file_util.h>
+#include <wsutil/tempfile.h>
#include "wtap-int.h"
#include "file_wrappers.h"
-#include "buffer.h"
+#include <wsutil/buffer.h>
#include "lanalyzer.h"
#include "ngsniffer.h"
#include "radcom.h"
#include "erf.h"
#include "hcidump.h"
#include "logcat.h"
+#include "logcat_text.h"
+#include "json.h"
#include "network_instruments.h"
#include "k12.h"
#include "ber.h"
#include "vwr.h"
#include "camins.h"
#include "stanag4607.h"
+#include "capsa.h"
#include "pcap-encap.h"
+#include "nettrace_3gpp_32_423.h"
+#include "mplog.h"
/*
* Add an extension, and all compressed versions thereof, to a GSList
* of extensions.
*/
-static GSList *add_extensions(GSList *extensions, const gchar *extension,
- GSList *compressed_file_extensions)
+static GSList *
+add_extensions(GSList *extensions, const gchar *extension,
+ const char **compressed_file_extensions)
{
- GSList *compressed_file_extension;
+ const char **compressed_file_extensionp;
/*
* Add the specified extension.
* Now add the extensions for compressed-file versions of
* that extension.
*/
- for (compressed_file_extension = compressed_file_extensions;
- compressed_file_extension != NULL;
- compressed_file_extension = g_slist_next(compressed_file_extension)) {
+ for (compressed_file_extensionp = compressed_file_extensions;
+ *compressed_file_extensionp != NULL;
+ compressed_file_extensionp++) {
extensions = g_slist_append(extensions,
g_strdup_printf("%s.%s", extension,
- (gchar *)compressed_file_extension->data));
+ *compressed_file_extensionp));
}
return extensions;
/*
* File types that can be identified by file extensions.
+ *
+ * These are used in file open dialogs to offer choices of extensions
+ * for which to filter. Note that the first field can list more than
+ * one type of file, because, for example, ".cap" is a popular
+ * extension used by a number of capture file types.
*/
static const struct file_extension_info file_type_extensions_base[] = {
{ "Wireshark/tcpdump/... - pcap", "pcap;cap;dmp" },
{ "Network Monitor, Surveyor, NetScaler", "cap" },
{ "InfoVista 5View capture", "5vw" },
{ "Sniffer (DOS)", "cap;enc;trc;fdc;syc" },
- { "NetXRay, Sniffer (Windows)", "cap;caz" },
+ { "Cinco NetXRay, Sniffer (Windows)", "cap;caz" },
{ "Endace ERF capture", "erf" },
{ "EyeSDN USB S0/E1 ISDN trace format", "trc" },
{ "HP-UX nettl trace", "trc0;trc1" },
{ "Network Instruments Observer", "bfr" },
+ { "Colasoft Capsa", "cscpkt" },
{ "Novell LANalyzer", "tr1" },
{ "Tektronix K12xx 32-bit .rf5 format", "rf5" },
- { "WildPackets *Peek", "pkt;tpc;apc;wpz" },
+ { "Savvius *Peek", "pkt;tpc;apc;wpz" },
{ "Catapult DCT2000 trace (.out format)", "out" },
+ { "Micropross mplog", "mplog" },
{ "MPEG files", "mpg;mp3" },
- { "CommView", "ncf" },
+ { "TamoSoft CommView", "ncf" },
{ "Symbian OS btsnoop", "log" },
{ "Transport-Neutral Encapsulation Format", "tnef" },
{ "XML files (including Gammu DCT3 traces)", "xml" },
{ "MPEG2 transport stream", "mp2t;ts;mpg" },
{ "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr" },
{ "CAM Inspector file", "camins" },
+ { "JavaScript Object Notation file", "json" }
};
#define N_FILE_TYPE_EXTENSIONS (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
static GArray* file_type_extensions_arr = NULL;
/* initialize the extensions array if it has not been initialized yet */
-static void init_file_type_extensions(void) {
+static void
+init_file_type_extensions(void)
+{
if (file_type_extensions_arr) return;
file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
}
-void wtap_register_file_type_extension(const struct file_extension_info *ei) {
+void
+wtap_register_file_type_extension(const struct file_extension_info *ei)
+{
init_file_type_extensions();
g_array_append_val(file_type_extensions_arr,*ei);
file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
}
-int wtap_get_num_file_type_extensions(void)
+int
+wtap_get_num_file_type_extensions(void)
{
return file_type_extensions_arr->len;
}
-const char *wtap_get_file_extension_type_name(int extension_type)
+const char *
+wtap_get_file_extension_type_name(int extension_type)
{
return file_type_extensions[extension_type].name;
}
-static GSList *add_extensions_for_file_extensions_type(int extension_type,
- GSList *extensions, GSList *compressed_file_extensions)
+static GSList *
+add_extensions_for_file_extensions_type(int extension_type,
+ GSList *extensions, const char **compressed_file_extensions)
{
gchar **extensions_set, **extensionp, *extension;
All strings in the list are allocated with g_malloc() and must be freed
with g_free(). */
-GSList *wtap_get_file_extension_type_extensions(guint extension_type)
+GSList *
+wtap_get_file_extension_type_extensions(guint extension_type)
{
- GSList *compressed_file_extensions;
GSList *extensions;
if (extension_type >= file_type_extensions_arr->len)
extensions = NULL; /* empty list, to start with */
- /*
- * Get the list of compressed-file extensions.
- */
- compressed_file_extensions = wtap_get_compressed_file_extensions();
-
/*
* Add all this file extension type's extensions, with compressed
* variants.
*/
extensions = add_extensions_for_file_extensions_type(extension_type,
- extensions, compressed_file_extensions);
+ extensions, compressed_file_extension_table);
- g_slist_free(compressed_file_extensions);
return extensions;
}
All strings in the list are allocated with g_malloc() and must be freed
with g_free(). */
-GSList *wtap_get_all_file_extensions_list(void)
+GSList *
+wtap_get_all_file_extensions_list(void)
{
- GSList *compressed_file_extensions;
GSList *extensions;
unsigned int i;
extensions = NULL; /* empty list, to start with */
- /*
- * Get the list of compressed-file extensions.
- */
- compressed_file_extensions = wtap_get_compressed_file_extensions();
-
for (i = 0; i < file_type_extensions_arr->len; i++) {
/*
* Add all this file extension type's extensions, with
* compressed variants.
*/
extensions = add_extensions_for_file_extensions_type(i,
- extensions, compressed_file_extensions);
+ extensions, compressed_file_extension_table);
}
- g_slist_free(compressed_file_extensions);
return extensions;
}
-/* The open_file_* routines should return:
+/*
+ * The open_file_* routines should return:
*
* -1 on an I/O error;
*
* However, the caller does have to free the private data pointer when
* returning 0, since the next file type will be called and will likely
* just overwrite the pointer.
+ *
+ * The names are used in file open dialogs to select, for files that
+ * don't have magic numbers and that could potentially be files of
+ * more than one type based on the heuristics, a particular file
+ * type to interpret it as, if the file name has no extension, the
+ * extension isn't sufficient to determine the appropriate file type,
+ * or the extension is wrong.
+ *
+ * NOTE: when adding file formats to this list you may also want to add them
+ * to the following files so that the various desktop environments will
+ * know that Wireshark can open the file:
+ * 1) wireshark-mime-package.xml (for freedesktop.org environments)
+ * 2) packaging/macosx/Info.plist.in (for OS X)
+ * 3) packaging/nsis/AdditionalTasksPage.ini, packaging/nsis/common.nsh,
+ * and packaging/wix/ComponentGroups.wxi (for Windows)
+ *
+ * If your file format has an expected extension (e.g., ".pcap") then you
+ * should probably also add it to file_type_extensions_base[] (in this file).
*/
-
static struct open_info open_info_base[] = {
- { "Pcap", OPEN_INFO_MAGIC, libpcap_open, "pcap", NULL, NULL },
- { "PcapNG", OPEN_INFO_MAGIC, pcapng_open, "pcapng", NULL, NULL },
- { "NgSniffer", OPEN_INFO_MAGIC, ngsniffer_open, NULL, NULL, NULL },
- { "Snoop", OPEN_INFO_MAGIC, snoop_open, NULL, NULL, NULL },
- { "IP Trace", OPEN_INFO_MAGIC, iptrace_open, NULL, NULL, NULL },
- { "Netmon", OPEN_INFO_MAGIC, netmon_open, NULL, NULL, NULL },
- { "Netxray", OPEN_INFO_MAGIC, netxray_open, NULL, NULL, NULL },
- { "Radcom", OPEN_INFO_MAGIC, radcom_open, NULL, NULL, NULL },
- { "Nettl", OPEN_INFO_MAGIC, nettl_open, NULL, NULL, NULL },
- { "Visual", OPEN_INFO_MAGIC, visual_open, NULL, NULL, NULL },
- { "5 Views", OPEN_INFO_MAGIC, _5views_open, NULL, NULL, NULL },
- { "Network Instruments", OPEN_INFO_MAGIC, network_instruments_open, NULL, NULL, NULL },
- { "Peek Tagged", OPEN_INFO_MAGIC, peektagged_open, NULL, NULL, NULL },
- { "DBS Etherwatch", OPEN_INFO_MAGIC, dbs_etherwatch_open, NULL, NULL, NULL },
- { "K12", OPEN_INFO_MAGIC, k12_open, NULL, NULL, NULL },
- { "Catapult DCT 2000", OPEN_INFO_MAGIC, catapult_dct2000_open, NULL, NULL, NULL },
- { "Aethra", OPEN_INFO_MAGIC, aethra_open, NULL, NULL, NULL },
- { "BTSNOOP", OPEN_INFO_MAGIC, btsnoop_open, "log", NULL, NULL },
- { "EYESDN", OPEN_INFO_MAGIC, eyesdn_open, NULL, NULL, NULL },
- { "TNEF", OPEN_INFO_MAGIC, tnef_open, NULL, NULL, NULL },
- { "MIME Files with Magic Bytes", OPEN_INFO_MAGIC, mime_file_open, NULL, NULL, NULL },
- { "Lanalyzer", OPEN_INFO_HEURISTIC, lanalyzer_open, "tr1", NULL, NULL },
- /*
- * PacketLogger must come before MPEG, because its files
- * are sometimes grabbed by mpeg_open.
- */
- { "Packet Logger", OPEN_INFO_HEURISTIC, packetlogger_open, "pklg", NULL, NULL },
- /* Some MPEG files have magic numbers, others just have heuristics. */
- { "Mpeg", OPEN_INFO_HEURISTIC, mpeg_open, "mpg;mp3", NULL, NULL },
- { "DCT3 Trace", OPEN_INFO_HEURISTIC, dct3trace_open, "xml", NULL, NULL },
- { "Daintree SNA", OPEN_INFO_HEURISTIC, daintree_sna_open, "dcf", NULL, NULL },
- { "Stanag 4607", OPEN_INFO_HEURISTIC, stanag4607_open, NULL, NULL, NULL },
- { "BER", OPEN_INFO_HEURISTIC, ber_open, NULL, NULL, 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", NULL, NULL },
- { "ERF", OPEN_INFO_HEURISTIC, erf_open, "erf", NULL, NULL },
- { "IPfix", OPEN_INFO_HEURISTIC, ipfix_open, "pfx;ipfix",NULL, NULL },
- { "K12 Text", OPEN_INFO_HEURISTIC, k12text_open, "txt", NULL, NULL },
- { "Peek Classic", OPEN_INFO_HEURISTIC, peekclassic_open, "pkt;tpc;apc;wpz", NULL, NULL },
- { "PPP Dump", OPEN_INFO_HEURISTIC, pppdump_open, NULL, NULL, NULL },
- { "iSeries", OPEN_INFO_HEURISTIC, iseries_open, "txt", NULL, NULL },
- { "i4btrace", OPEN_INFO_HEURISTIC, i4btrace_open, NULL, NULL, NULL },
- { "Mp2t", OPEN_INFO_HEURISTIC, mp2t_open, "ts;mpg", NULL, NULL },
- { "Csids", OPEN_INFO_HEURISTIC, csids_open, NULL, NULL, NULL },
- { "VMS", OPEN_INFO_HEURISTIC, vms_open, "txt", NULL, NULL },
- { "Cosine", OPEN_INFO_HEURISTIC, cosine_open, "txt", NULL, NULL },
- { "Hcidump", OPEN_INFO_HEURISTIC, hcidump_open, NULL, NULL, NULL },
- { "Commview", OPEN_INFO_HEURISTIC, commview_open, "ncf", NULL, NULL },
- { "Nstrace", OPEN_INFO_HEURISTIC, nstrace_open, "txt", NULL, NULL },
- { "Logcat ", OPEN_INFO_HEURISTIC, logcat_open, "logcat", NULL, NULL },
- /* ASCII trace files from Telnet sessions. */
- { "Ascend", OPEN_INFO_HEURISTIC, ascend_open, "txt", NULL, NULL },
- { "Toshiba", OPEN_INFO_HEURISTIC, toshiba_open, "txt", NULL, NULL },
- /* Extremely weak heuristics - put them at the end. */
- { "VWR", OPEN_INFO_HEURISTIC, vwr_open, "vwr", NULL, NULL },
- { "Camins", OPEN_INFO_HEURISTIC, camins_open, "camins", NULL, NULL },
+ { "Wireshark/tcpdump/... - pcap", OPEN_INFO_MAGIC, libpcap_open, "pcap", NULL, NULL },
+ { "Wireshark/... - pcapng", OPEN_INFO_MAGIC, pcapng_open, "pcapng", NULL, NULL },
+ { "Sniffer (DOS)", OPEN_INFO_MAGIC, ngsniffer_open, NULL, NULL, NULL },
+ { "Snoop, Shomiti/Finisar Surveyor", OPEN_INFO_MAGIC, snoop_open, NULL, NULL, NULL },
+ { "AIX iptrace", OPEN_INFO_MAGIC, iptrace_open, NULL, NULL, NULL },
+ { "Microsoft Network Monitor", OPEN_INFO_MAGIC, netmon_open, NULL, NULL, NULL },
+ { "Cinco NetXray/Sniffer (Windows)", OPEN_INFO_MAGIC, netxray_open, NULL, NULL, NULL },
+ { "RADCOM WAN/LAN analyzer", OPEN_INFO_MAGIC, radcom_open, NULL, NULL, NULL },
+ { "HP-UX nettl trace", OPEN_INFO_MAGIC, nettl_open, NULL, NULL, NULL },
+ { "Visual Networks traffic capture", OPEN_INFO_MAGIC, visual_open, NULL, NULL, NULL },
+ { "InfoVista 5View capture", OPEN_INFO_MAGIC, _5views_open, NULL, NULL, NULL },
+ { "Network Instruments Observer", OPEN_INFO_MAGIC, network_instruments_open, NULL, NULL, NULL },
+ { "Savvius tagged", OPEN_INFO_MAGIC, peektagged_open, NULL, NULL, NULL },
+ { "Colasoft Capsa", OPEN_INFO_MAGIC, capsa_open, NULL, NULL, NULL },
+ { "DBS Etherwatch (VMS)", OPEN_INFO_MAGIC, dbs_etherwatch_open, NULL, NULL, NULL },
+ { "Tektronix K12xx 32-bit .rf5 format", OPEN_INFO_MAGIC, k12_open, NULL, NULL, NULL },
+ { "Catapult DCT2000 trace (.out format)", OPEN_INFO_MAGIC, catapult_dct2000_open, NULL, NULL, NULL },
+ { "Aethra .aps file", OPEN_INFO_MAGIC, aethra_open, NULL, NULL, NULL },
+ { "Symbian OS btsnoop", OPEN_INFO_MAGIC, btsnoop_open, "log", NULL, NULL },
+ { "EyeSDN USB S0/E1 ISDN trace format", OPEN_INFO_MAGIC, eyesdn_open, NULL, NULL, NULL },
+ { "Transport-Neutral Encapsulation Format", OPEN_INFO_MAGIC, tnef_open, NULL, NULL, NULL },
+ /* 3GPP TS 32.423 Trace must come before MIME Files as it's XML based*/
+ { "3GPP TS 32.423 Trace format", OPEN_INFO_MAGIC, nettrace_3gpp_32_423_file_open, NULL, NULL, NULL },
+ /* Gammu DCT3 trace must come before MIME files as it's XML based*/
+ { "Gammu DCT3 trace", OPEN_INFO_MAGIC, dct3trace_open, NULL, NULL, NULL },
+ { "MIME Files Format", OPEN_INFO_MAGIC, mime_file_open, NULL, NULL, NULL },
+ { "Micropross mplog", OPEN_INFO_MAGIC, mplog_open, "mplog", NULL, NULL },
+ { "Novell LANalyzer", OPEN_INFO_HEURISTIC, lanalyzer_open, "tr1", NULL, NULL },
+ /*
+ * PacketLogger must come before MPEG, because its files
+ * are sometimes grabbed by mpeg_open.
+ */
+ { "OS X PacketLogger", OPEN_INFO_HEURISTIC, packetlogger_open, "pklg", NULL, NULL },
+ /* Some MPEG files have magic numbers, others just have heuristics. */
+ { "MPEG", OPEN_INFO_HEURISTIC, mpeg_open, "mpg;mp3", NULL, NULL },
+ { "Daintree SNA", OPEN_INFO_HEURISTIC, daintree_sna_open, "dcf", NULL, NULL },
+ { "STANAG 4607 Format", OPEN_INFO_HEURISTIC, stanag4607_open, NULL, NULL, NULL },
+ { "ASN.1 Basic Encoding Rules", OPEN_INFO_HEURISTIC, ber_open, NULL, NULL, 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 snoop text file", OPEN_INFO_HEURISTIC, netscreen_open, "txt", NULL, NULL },
+ { "Endace ERF capture", OPEN_INFO_HEURISTIC, erf_open, "erf", NULL, NULL },
+ { "IPFIX File Format", OPEN_INFO_HEURISTIC, ipfix_open, "pfx;ipfix",NULL, NULL },
+ { "K12 text file", OPEN_INFO_HEURISTIC, k12text_open, "txt", NULL, NULL },
+ { "Savvius classic", OPEN_INFO_HEURISTIC, peekclassic_open, "pkt;tpc;apc;wpz", NULL, NULL },
+ { "pppd log (pppdump format)", OPEN_INFO_HEURISTIC, pppdump_open, NULL, NULL, NULL },
+ { "IBM iSeries comm. trace", OPEN_INFO_HEURISTIC, iseries_open, "txt", NULL, NULL },
+ { "I4B ISDN trace", OPEN_INFO_HEURISTIC, i4btrace_open, NULL, NULL, NULL },
+ { "MPEG2 transport stream", OPEN_INFO_HEURISTIC, mp2t_open, "ts;mpg", NULL, NULL },
+ { "CSIDS IPLog", OPEN_INFO_HEURISTIC, csids_open, NULL, NULL, NULL },
+ { "TCPIPtrace (VMS)", OPEN_INFO_HEURISTIC, vms_open, "txt", NULL, NULL },
+ { "CoSine IPSX L2 capture", OPEN_INFO_HEURISTIC, cosine_open, "txt", NULL, NULL },
+ { "Bluetooth HCI dump", OPEN_INFO_HEURISTIC, hcidump_open, NULL, NULL, NULL },
+ { "TamoSoft CommView", OPEN_INFO_HEURISTIC, commview_open, "ncf", NULL, NULL },
+ { "NetScaler", OPEN_INFO_HEURISTIC, nstrace_open, "cap", NULL, NULL },
+ { "Android Logcat Binary format", OPEN_INFO_HEURISTIC, logcat_open, "logcat", NULL, NULL },
+ { "Android Logcat Text formats", OPEN_INFO_HEURISTIC, logcat_text_open, "txt", NULL, NULL },
+ /* ASCII trace files from Telnet sessions. */
+ { "Lucent/Ascend access server trace", OPEN_INFO_HEURISTIC, ascend_open, "txt", NULL, NULL },
+ { "Toshiba Compact ISDN Router snoop", OPEN_INFO_HEURISTIC, toshiba_open, "txt", NULL, NULL },
+ /* Extremely weak heuristics - put them at the end. */
+ { "Ixia IxVeriWave .vwr Raw Capture", OPEN_INFO_HEURISTIC, vwr_open, "vwr", NULL, NULL },
+ { "CAM Inspector file", OPEN_INFO_HEURISTIC, camins_open, "camins", NULL, NULL },
+ { "JavaScript Object Notation", OPEN_INFO_HEURISTIC, json_open, "json", NULL, NULL }
};
/* this is only used to build the dynamic array on load, do NOT use this
* for anything else, because the size of the actual array will change if
- * Lua scripts register a new file reader.
+ * Lua scripts register a new file reader.
*/
#define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
/* this points to the first OPEN_INFO_HEURISTIC type in the array */
static guint heuristic_open_routine_idx = 0;
-static void set_heuristic_routine(void) {
+static void
+set_heuristic_routine(void)
+{
guint i;
g_assert(open_info_arr != NULL);
g_assert(heuristic_open_routine_idx > 0);
}
-void init_open_routines(void) {
- unsigned int i;
- struct open_info *i_open;
+void
+init_open_routines(void)
+{
+ unsigned int i;
+ struct open_info *i_open;
- if (open_info_arr)
- return;
+ if (open_info_arr)
+ return;
- open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
+ open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
- g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
+ g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
- open_routines = (struct open_info *)(void*) open_info_arr->data;
+ open_routines = (struct open_info *)(void*) open_info_arr->data;
- /* Populate the extensions_set list now */
- for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
- if (i_open->extensions != NULL)
- i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
- }
+ /* Populate the extensions_set list now */
+ for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
+ if (i_open->extensions != NULL)
+ i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
+ }
- set_heuristic_routine();
+ set_heuristic_routine();
}
-/* Registers a new file reader - currently only called by wslua code for Lua readers.
+/*
+ * Registers a new file reader - currently only called by wslua code for Lua readers.
* If first_routine is true, it's added before other readers of its type (magic or heuristic).
* Also, it checks for an existing reader of the same name and errors if it finds one; if
* you want to handle that condition more gracefully, call wtap_has_open_info() first.
*/
-void wtap_register_open_info(struct open_info *oi, const gboolean first_routine) {
- init_open_routines();
+void
+wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
+{
+ init_open_routines();
- if (!oi || !oi->name) {
- g_error("No open_info name given to register");
- return;
- }
+ if (!oi || !oi->name) {
+ g_error("No open_info name given to register");
+ return;
+ }
- /* verify name doesn't already exist */
- if (wtap_has_open_info(oi->name)) {
- g_error("Name given to register_open_info already exists");
- return;
- }
+ /* verify name doesn't already exist */
+ if (wtap_has_open_info(oi->name)) {
+ g_error("Name given to register_open_info already exists");
+ return;
+ }
- if (oi->extensions != NULL)
- oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
+ if (oi->extensions != NULL)
+ oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
- /* if it's magic and first, prepend it; if it's heuristic and not first,
- append it; if it's anything else, stick it in the middle */
- if (first_routine && oi->type == OPEN_INFO_MAGIC) {
- g_array_prepend_val(open_info_arr, *oi);
- } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
- g_array_append_val(open_info_arr, *oi);
- } else {
- g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
- }
+ /* if it's magic and first, prepend it; if it's heuristic and not first,
+ append it; if it's anything else, stick it in the middle */
+ if (first_routine && oi->type == OPEN_INFO_MAGIC) {
+ g_array_prepend_val(open_info_arr, *oi);
+ } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
+ g_array_append_val(open_info_arr, *oi);
+ } else {
+ g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
+ }
- open_routines = (struct open_info *)(void*) open_info_arr->data;
- set_heuristic_routine();
+ open_routines = (struct open_info *)(void*) open_info_arr->data;
+ set_heuristic_routine();
}
/* De-registers a file reader by removign it from the GArray based on its name.
* Note: this function will error if it doesn't find the given name; if you want to handle
* that condition more gracefully, call wtap_has_open_info() first.
*/
-void wtap_deregister_open_info(const gchar *name) {
- guint i;
- init_open_routines();
+void
+wtap_deregister_open_info(const gchar *name)
+{
+ guint i;
+ init_open_routines();
- if (!name) {
- g_error("Missing open_info name to de-register");
- return;
- }
+ if (!name) {
+ g_error("Missing open_info name to de-register");
+ return;
+ }
- for (i = 0; i < open_info_arr->len; i++) {
- if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
- if (open_routines[i].extensions_set != NULL)
- g_strfreev(open_routines[i].extensions_set);
- open_info_arr = g_array_remove_index(open_info_arr, i);
- set_heuristic_routine();
- return;
- }
- }
+ for (i = 0; i < open_info_arr->len; i++) {
+ if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
+ if (open_routines[i].extensions_set != NULL)
+ g_strfreev(open_routines[i].extensions_set);
+ open_info_arr = g_array_remove_index(open_info_arr, i);
+ set_heuristic_routine();
+ return;
+ }
+ }
- g_error("deregister_open_info: name not found");
+ g_error("deregister_open_info: name not found");
}
/* Determines if a open routine short name already exists
*/
-gboolean wtap_has_open_info(const gchar *name) {
- guint i;
- init_open_routines();
+gboolean
+wtap_has_open_info(const gchar *name)
+{
+ guint i;
+ init_open_routines();
- if (!name) {
- g_error("No name given to wtap_has_open_info!");
- return FALSE;
- }
+ if (!name) {
+ g_error("No name given to wtap_has_open_info!");
+ return FALSE;
+ }
- for (i = 0; i < open_info_arr->len; i++) {
- if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
- return TRUE;
- }
- }
+ for (i = 0; i < open_info_arr->len; i++) {
+ if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
/*
passed-in name (the name in the open_info struct). It returns WTAP_TYPE_AUTO
on failure, which is the number 0. The 'type' number is the entry's index+1,
because that's what wtap_open_offline() expects it to be. */
-unsigned int open_info_name_to_type(const char *name)
+unsigned int
+open_info_name_to_type(const char *name)
{
unsigned int i;
init_open_routines();
for (i = 0; i < open_info_arr->len; i++) {
if (open_routines[i].name != NULL &&
- strcmp(name, open_routines[i].name) == 0)
+ strcmp(name, open_routines[i].name) == 0)
return i+1;
}
return WTAP_TYPE_AUTO; /* no such file type */
}
-static char *get_file_extension(const char *pathname)
+static char *
+get_file_extension(const char *pathname)
{
gchar *filename;
gchar **components;
size_t ncomponents;
- GSList *compressed_file_extensions, *compressed_file_extension;
+ const char **compressed_file_extensionp;
gchar *extensionp;
/*
* Is the last component one of the extensions used for compressed
* files?
*/
- compressed_file_extensions = wtap_get_compressed_file_extensions();
- if (compressed_file_extensions == NULL) {
- /*
- * We don't support reading compressed files, so just
- * return a copy of whatever extension we did find.
- */
- extensionp = g_strdup(components[ncomponents - 1]);
- g_strfreev(components);
- return extensionp;
- }
extensionp = components[ncomponents - 1];
- for (compressed_file_extension = compressed_file_extensions;
- compressed_file_extension != NULL;
- compressed_file_extension = g_slist_next(compressed_file_extension)) {
- if (strcmp(extensionp, (char *)compressed_file_extension->data) == 0) {
+ for (compressed_file_extensionp = compressed_file_extension_table;
+ *compressed_file_extensionp != NULL;
+ compressed_file_extensionp++) {
+ if (strcmp(extensionp, *compressed_file_extensionp) == 0) {
/*
* Yes, it's one of the compressed-file extensions.
* Is there an extension before that?
/*
* Check if file extension is used in this heuristic
*/
-static gboolean heuristic_uses_extension(unsigned int i, const char *extension)
+static gboolean
+heuristic_uses_extension(unsigned int i, const char *extension)
{
gchar **extensionp;
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, unsigned int type, int *err, char **err_info,
- gboolean do_random)
+wtap *
+wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
+ gboolean do_random)
{
int fd;
ws_statb64 statb;
gboolean use_stdin = FALSE;
gchar *extension;
+ *err = 0;
+ *err_info = NULL;
+
init_open_routines();
/* open standard input if filename is '-' */
* Opens of FIFOs are allowed only when not opening
* for random access.
*
- * XXX - currently, we do seeking when trying to find
- * out the file type, so we don't actually support
- * opening FIFOs. However, we may eventually
- * do buffering that allows us to do at least some
- * file type determination even on pipes, so we
- * allow FIFO opens and let things fail later when
- * we try to seek.
+ * Currently, we do seeking when trying to find out
+ * the file type, but our I/O routines do some amount
+ * of buffering, and do backward seeks within the buffer
+ * if possible, so at least some file types can be
+ * opened from pipes, so we don't completely disallow opens
+ * of pipes.
*/
if (do_random) {
*err = WTAP_ERR_RANDOM_OPEN_PIPE;
wth->file_encap = WTAP_ENCAP_UNKNOWN;
wth->subtype_sequential_close = NULL;
wth->subtype_close = NULL;
- wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+ wth->file_tsprec = WTAP_TSPREC_USEC;
wth->priv = NULL;
wth->wslua_data = NULL;
+ wth->shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
/* Initialize the array containing a list of interfaces. pcapng_open and
* erf_open needs this (and libpcap_open for ERF encapsulation types).
* Always initing it here saves checking for a NULL ptr later. */
- wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+ wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
if (wth->random_fh) {
wth->fast_seek = g_ptr_array_new();
result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
switch (result) {
- case -1:
- /* I/O error - give up */
+ case WTAP_OPEN_ERROR:
+ /* Error - give up */
wtap_close(wth);
return NULL;
- case 0:
- /* No I/O error, but not that type of file */
+ case WTAP_OPEN_NOT_MINE:
+ /* No error, but not that type of file */
goto fail;
- case 1:
+ case WTAP_OPEN_MINE:
/* We found the file type */
goto success;
}
Initialize the data offset while we're at it. */
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
- /* I/O error - give up */
+ /* Error - give up */
wtap_close(wth);
return NULL;
}
switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
- case -1:
- /* I/O error - give up */
+ case WTAP_OPEN_ERROR:
+ /* Error - give up */
wtap_close(wth);
return NULL;
- case 0:
- /* No I/O error, but not that type of file */
+ case WTAP_OPEN_NOT_MINE:
+ /* No error, but not that type of file */
break;
- case 1:
+ case WTAP_OPEN_MINE:
/* We found the file type */
goto success;
}
if (heuristic_uses_extension(i, extension)) {
/* Yes. */
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
- /* I/O error - give up */
+ /* Error - give up */
g_free(extension);
wtap_close(wth);
return NULL;
switch ((*open_routines[i].open_routine)(wth,
err, err_info)) {
- case -1:
- /* I/O error - give up */
+ case WTAP_OPEN_ERROR:
+ /* Error - give up */
g_free(extension);
wtap_close(wth);
return NULL;
- case 0:
- /* No I/O error, but not that type of file */
+ case WTAP_OPEN_NOT_MINE:
+ /* No error, but not that type of file */
break;
- case 1:
+ case WTAP_OPEN_MINE:
/* We found the file type */
g_free(extension);
goto success;
}
}
- /* Now try the ones that don't use it. */
+ /*
+ * Now try the heuristic types that have no extensions
+ * to check; we try those before the ones that have
+ * extensions that *don't* match this file's extension,
+ * on the theory that files of those types generally
+ * have one of the type's extensions, and, as this file
+ * *doesn't* have one of those extensions, it's probably
+ * *not* one of those files.
+ */
for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
- /* Does this type use that extension? */
- if (!heuristic_uses_extension(i, extension)) {
+ /* Does this type have any extensions? */
+ if (open_routines[i].extensions == NULL) {
/* No. */
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
- /* I/O error - give up */
+ /* Error - give up */
g_free(extension);
wtap_close(wth);
return NULL;
switch ((*open_routines[i].open_routine)(wth,
err, err_info)) {
- case -1:
- /* I/O error - give up */
+ case WTAP_OPEN_ERROR:
+ /* Error - give up */
g_free(extension);
wtap_close(wth);
return NULL;
- case 0:
- /* No I/O error, but not that type of file */
+ case WTAP_OPEN_NOT_MINE:
+ /* No error, but not that type of file */
break;
- case 1:
+ case WTAP_OPEN_MINE:
+ /* We found the file type */
+ g_free(extension);
+ goto success;
+ }
+ }
+ }
+
+ /*
+ * Now try the ones that have extensions where none of
+ * them matches this file's extensions.
+ */
+ for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
+ /*
+ * Does this type have extensions and is this file's
+ * extension one of them?
+ */
+ if (open_routines[i].extensions != NULL &&
+ !heuristic_uses_extension(i, extension)) {
+ /* Yes and no. */
+ if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
+ /* Error - give up */
+ g_free(extension);
+ wtap_close(wth);
+ return NULL;
+ }
+
+ /* Set wth with wslua data if any - this is how we pass the data
+ * to the file reader, kind of like priv but not free'd later.
+ */
+ wth->wslua_data = open_routines[i].wslua_data;
+
+ switch ((*open_routines[i].open_routine)(wth,
+ err, err_info)) {
+
+ case WTAP_OPEN_ERROR:
+ /* Error - give up */
+ g_free(extension);
+ wtap_close(wth);
+ return NULL;
+
+ case WTAP_OPEN_NOT_MINE:
+ /* No error, but not that type of file */
+ break;
+
+ case WTAP_OPEN_MINE:
/* We found the file type */
g_free(extension);
goto success;
for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
- /* I/O error - give up */
+ /* Error - give up */
wtap_close(wth);
return NULL;
}
switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
- case -1:
- /* I/O error - give up */
+ case WTAP_OPEN_ERROR:
+ /* Error - give up */
wtap_close(wth);
return NULL;
- case 0:
- /* No I/O error, but not that type of file */
+ case WTAP_OPEN_NOT_MINE:
+ /* No error, but not that type of file */
break;
- case 1:
+ case WTAP_OPEN_MINE:
/* We found the file type */
goto success;
}
success:
wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
- buffer_init(wth->frame_buffer, 1500);
-
- if(wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP){
-
- wtapng_if_descr_t descr;
-
- descr.wtap_encap = wth->file_encap;
- descr.time_units_per_second = 1000000; /* default microsecond resolution */
- descr.link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
- descr.snap_len = wth->snapshot_length;
- descr.opt_comment = NULL;
- descr.if_name = NULL;
- descr.if_description = NULL;
- descr.if_speed = 0;
- descr.if_tsresol = 6;
- descr.if_filter_str= NULL;
- descr.bpf_filter_len= 0;
- descr.if_filter_bpf_bytes= NULL;
- descr.if_os = NULL;
- descr.if_fcslen = -1;
- descr.num_stat_entries = 0; /* Number of ISB:s */
- descr.interface_statistics = NULL;
+ ws_buffer_init(wth->frame_buffer, 1500);
+
+ if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
+ (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
+
+ wtap_optionblock_t descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+ wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+
+ descr_mand->wtap_encap = wth->file_encap;
+ if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
+ descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */
+ wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9);
+ descr_mand->tsprecision = WTAP_TSPREC_NSEC;
+ } else {
+ descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+ wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6);
+ descr_mand->tsprecision = WTAP_TSPREC_USEC;
+ }
+ descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
+ descr_mand->snap_len = wth->snapshot_length;
+
+ descr_mand->num_stat_entries = 0; /* Number of ISB:s */
+ descr_mand->interface_statistics = NULL;
g_array_append_val(wth->interface_data, descr);
}
return TRUE;
}
-/* Table of the file types we know about.
- Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending order */
+/* Table of the file types and subtypes for which we have built-in support.
+ Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending
+ order.
+
+ These are used to report what type and subtype a given file is and
+ to let the user select a format when writing out packets.
+
+ This table is what we start with, but it can be modified.
+ If we need to modify it, we allocate a GArray, copy the entries
+ in the above table to that GArray, use the copy as the table, and
+ make all changes to the copy. */
static const struct file_type_subtype_info dump_open_table_base[] = {
/* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN (only used internally for initialization) */
{ NULL, NULL, NULL, NULL,
NULL, NULL, NULL },
/* WTAP_FILE_TYPE_SUBTYPE_PCAP */
- /* Gianluca Varenni suggests that we add "deprecated" to the description. */
+ /* Gianluca Varenni suggests that we add "deprecated" to the description. */
{ "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp",
FALSE, FALSE, 0,
libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
visual_dump_can_write_encap, visual_dump_open, NULL },
/* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V56 */
- { "WildPackets classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
+ { "Savvius classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
FALSE, FALSE, 0,
NULL, NULL, NULL },
/* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V7 */
- { "WildPackets classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
+ { "Savvius classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
FALSE, FALSE, 0,
NULL, NULL, NULL },
/* WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED */
- { "WildPackets tagged", "peektagged", "pkt", "tpc;apc;wpz",
+ { "Savvius tagged", "peektagged", "pkt", "tpc;apc;wpz",
FALSE, FALSE, 0,
NULL, NULL, NULL },
NULL, NULL, NULL },
/* WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER */
- { "PacketLogger", "pklg", "pklg", NULL,
+ { "OS X PacketLogger", "pklg", "pklg", NULL,
FALSE, FALSE, 0,
NULL, NULL, NULL },
FALSE, FALSE, 0,
NULL, NULL, NULL },
- /* WTAP_FILE_NETSCALER_3_0 */
+ /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 */
{ "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
TRUE, FALSE, 0,
nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
- /* WTAP_FILE_LOGCAT */
- { "Android Logcat Binary format", "logcat", "logcat", NULL,
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT */
+ { "Android Logcat Binary format", "logcat", "logcat", NULL,
FALSE, FALSE, 0,
logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
- { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
- FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
- { "Android Logcat Process text format", "logcat-process", NULL, NULL,
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF */
+ { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_process_dump_open, NULL },
- { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
+ logcat_text_brief_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS */
+ { "Android Logcat Process text format", "logcat-process", NULL, NULL,
FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
- { "Android Logcat Time text format", "logcat-time", NULL, NULL,
+ logcat_text_process_dump_can_write_encap, logcat_text_process_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG */
+ { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_time_dump_open, NULL },
- { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
+ logcat_text_tag_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD */
+ { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
+ FALSE, FALSE, 0,
+ logcat_text_thread_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME */
+ { "Android Logcat Time text format", "logcat-time", NULL, NULL,
FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
+ logcat_text_time_dump_can_write_encap, logcat_text_time_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME */
{ "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
- { "Android Logcat Long text format", "logcat-long", NULL, NULL,
+ logcat_text_threadtime_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG */
+ { "Android Logcat Long text format", "logcat-long", NULL, NULL,
FALSE, FALSE, 0,
- logcat_dump_can_write_encap, logcat_text_long_dump_open, NULL }
+ logcat_text_long_dump_can_write_encap, logcat_text_long_dump_open, NULL },
+ /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA */
+ { "Colasoft Capsa format", "capsa", "cscpkt", NULL,
+ FALSE, FALSE, 0,
+ NULL, NULL, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER */
+ { "Colasoft Packet Builder format", "colasoft-pb", "cscpkt", NULL,
+ FALSE, FALSE, 0,
+ NULL, NULL, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_JSON */
+ { "JavaScript Object Notation", "json", "json", "NULL",
+ FALSE, FALSE, 0,
+ NULL, NULL, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 */
+ { "NetScaler Trace (Version 3.5)", "nstrace35", "cap", NULL,
+ TRUE, FALSE, 0,
+ nstrace_35_dump_can_write_encap, nstrace_dump_open, NULL },
+
+ /* WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423 */
+ { "3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
+ FALSE, FALSE, 0,
+ NULL, NULL, NULL },
+
+ /* WTAP_FILE_TYPE_MPLOG */
+ { "Micropross mplog file", "mplog", "mplog", NULL,
+ FALSE, FALSE, 0,
+ NULL, NULL, NULL }
};
+/*
+ * Pointer to the table we're currently using. It's initialized to point
+ * to the static table, but, if we have to allocate the GArray, it's
+ * changed to point to the data in the GArray.
+ */
+static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
+
+/*
+ * Number of elements in the table we're currently using. It's initialized
+ * to the number of elements in the static table, but, if we have to
+ * allocate the GArray, it's changed to have the size of the GArray.
+ */
gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
+/*
+ * Pointer to the GArray; NULL until it's needed.
+ */
static GArray* dump_open_table_arr = NULL;
-static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
-
-/* initialize the file types array if it has not being initialized yet */
-static void init_file_types_subtypes(void) {
+/*
+ * Create the GArray from the static table if it hasn't already been created.
+ */
+static void
+init_file_types_subtypes_garray(void)
+{
if (dump_open_table_arr) return;
dump_open_table_arr = g_array_new(FALSE,TRUE,sizeof(struct file_type_subtype_info));
/* if subtype is WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, then create a new subtype as well as register it, else replace the
existing entry in that spot */
-int wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype) {
- struct file_type_subtype_info* finfo = NULL;
- init_file_types_subtypes();
+int
+wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype)
+{
+ struct file_type_subtype_info* finfo;
if (!fi || !fi->name || !fi->short_name || subtype > wtap_num_file_types_subtypes) {
g_error("no file type info or invalid file type to register");
return subtype;
}
+ /*
+ * Create the GArray if it hasn't already been created.
+ */
+ init_file_types_subtypes_garray();
+
g_array_append_val(dump_open_table_arr,*fi);
dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
return subtype;
}
- /* yes, we're going to cast to change its const-ness */
- finfo = (struct file_type_subtype_info*)(&dump_open_table[subtype]);
+ /*
+ * Create the GArray if it hasn't already been created.
+ */
+ init_file_types_subtypes_garray();
+
+ /*
+ * Get the pointer from the GArray, so that we get a non-const
+ * pointer.
+ */
+ finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
/*finfo->name = fi->name;*/
/*finfo->short_name = fi->short_name;*/
finfo->default_file_extension = fi->default_file_extension;
/* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
*/
-void wtap_deregister_file_type_subtype(const int subtype) {
- struct file_type_subtype_info* finfo = NULL;
+void
+wtap_deregister_file_type_subtype(const int subtype)
+{
+ struct file_type_subtype_info* finfo;
if (subtype < 0 || subtype >= wtap_num_file_types_subtypes) {
g_error("invalid file type to de-register");
return;
}
- /* yes, we're going to cast to change its const-ness */
- finfo = (struct file_type_subtype_info*)(&dump_open_table[subtype]);
+ /*
+ * Create the GArray if it hasn't already been created.
+ */
+ init_file_types_subtypes_garray();
+
+ /*
+ * Get the pointer from the GArray, so that we get a non-const
+ * pointer.
+ */
+ finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
/* unfortunately, it's not safe to null-out the name or short_name; bunch of other code doesn't guard aainst that, afaict */
/*finfo->name = NULL;*/
/*finfo->short_name = NULL;*/
finfo->wslua_info = NULL;
}
-int wtap_get_num_file_types_subtypes(void)
+int
+wtap_get_num_file_types_subtypes(void)
{
return wtap_num_file_types_subtypes;
}
gboolean
wtap_dump_can_write(const GArray *file_encaps, guint32 required_comment_types)
{
- int ft;
+ int ft;
- for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
- /* To save a file with Wiretap, Wiretap has to handle that format,
- and its code to handle that format must be able to write a file
- with this file's encapsulation types. */
- if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
- /* OK, we can write it out in this type. */
- return TRUE;
- }
- }
+ for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
+ /* To save a file with Wiretap, Wiretap has to handle that format,
+ * and its code to handle that format must be able to write a file
+ * with this file's encapsulation types.
+ */
+ if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
+ /* OK, we can write it out in this type. */
+ return TRUE;
+ }
+ }
- /* No, we couldn't save it in any format. */
- return FALSE;
+ /* No, we couldn't save it in any format. */
+ return FALSE;
}
/**
/* Can we save this file in its own file type/subtype? */
if (wtap_dump_can_write_format(file_type_subtype, file_encaps,
- required_comment_types)) {
+ required_comment_types)) {
/* Yes - make that the default file type/subtype. */
default_file_type_subtype = file_type_subtype;
} else {
default_file_type_subtype = -1;
for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
if (wtap_dump_can_write_format(ft, file_encaps,
- required_comment_types)) {
+ required_comment_types)) {
/* OK, got it. */
default_file_type_subtype = ft;
}
pcap format. */
if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, file_encaps,
- required_comment_types))
+ required_comment_types))
other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
} else if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAP, file_encaps,
- required_comment_types))
+ required_comment_types))
other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
}
if (other_file_type_subtype != -1)
if (ft == default_file_type_subtype || ft == other_file_type_subtype)
continue; /* we've already done this one */
if (wtap_dump_can_write_format(ft, file_encaps,
- required_comment_types)) {
+ required_comment_types)) {
/* OK, we can write it out in this type. */
g_array_append_val(savable_file_types_subtypes, ft);
}
}
/* Name that should be somewhat descriptive. */
-const char *wtap_file_type_subtype_string(int file_type_subtype)
+const char *
+wtap_file_type_subtype_string(int file_type_subtype)
{
if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes) {
g_error("Unknown capture file type %d", file_type_subtype);
}
/* Name to use in, say, a command-line flag specifying the type/subtype. */
-const char *wtap_file_type_subtype_short_string(int file_type_subtype)
+const char *
+wtap_file_type_subtype_short_string(int file_type_subtype)
{
if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
return NULL;
}
/* Translate a short name to a capture file type/subtype. */
-int wtap_short_string_to_file_type_subtype(const char *short_name)
+int
+wtap_short_string_to_file_type_subtype(const char *short_name)
{
int file_type_subtype;
static GSList *
add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
- GSList *compressed_file_extensions)
+ const char **compressed_file_extensions)
{
gchar **extensions_set, **extensionp;
gchar *extension;
All strings in the list are allocated with g_malloc() and must be freed
with g_free(). */
-GSList *wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
+GSList *
+wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
{
- GSList *compressed_file_extensions;
GSList *extensions;
+ static const char *no_compressed_extensions[] = {
+ NULL
+ };
if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
return NULL; /* not a valid file type */
extensions = NULL; /* empty list, to start with */
- /*
- * If include_compressions is true, get the list of compressed-file
- * extensions.
- */
- if (include_compressed)
- compressed_file_extensions = wtap_get_compressed_file_extensions();
- else
- compressed_file_extensions = NULL;
-
/*
* Add all this file type's extensions, with compressed
- * variants.
+ * variants if include_compressed is true.
*/
extensions = add_extensions_for_file_type_subtype(file_type_subtype, extensions,
- compressed_file_extensions);
+ include_compressed ? compressed_file_extension_table : no_compressed_extensions);
- g_slist_free(compressed_file_extensions);
return extensions;
}
* Free a list returned by wtap_get_file_extension_type_extensions(),
* wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
*/
-void wtap_free_extensions_list(GSList *extensions)
+void
+wtap_free_extensions_list(GSList *extensions)
{
GSList *extension;
/* Return the default file extension to use with the specified file type;
that's just the extension, without any ".". */
-const char *wtap_default_file_extension(int file_type_subtype)
+const char *
+wtap_default_file_extension(int file_type_subtype)
{
if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
return NULL;
return dump_open_table[file_type_subtype].default_file_extension;
}
-gboolean wtap_dump_can_open(int file_type_subtype)
+gboolean
+wtap_dump_can_open(int file_type_subtype)
{
if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
|| dump_open_table[file_type_subtype].dump_open == NULL)
return TRUE;
}
-#ifdef HAVE_LIBZ
-gboolean wtap_dump_can_compress(int file_type_subtype)
+#ifdef HAVE_ZLIB
+gboolean
+wtap_dump_can_compress(int file_type_subtype)
{
/*
* If this is an unknown file type, or if we have to
return TRUE;
}
#else
-gboolean wtap_dump_can_compress(int file_type_subtype _U_)
+gboolean
+wtap_dump_can_compress(int file_type_subtype _U_)
{
return FALSE;
}
#endif
-gboolean wtap_dump_has_name_resolution(int file_type_subtype)
+gboolean
+wtap_dump_has_name_resolution(int file_type_subtype)
{
if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
|| dump_open_table[file_type_subtype].has_name_resolution == FALSE)
return TRUE;
}
-gboolean wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
+gboolean
+wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
{
guint32 supported_comment_types;
static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
static int wtap_dump_file_close(wtap_dumper *wdh);
-wtap_dumper* wtap_dump_open(const char *filename, int file_type_subtype, int encap,
- int snaplen, gboolean compressed, int *err)
-{
- return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, err);
-}
-
static wtap_dumper *
wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
- wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+ wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtap_optionblock_t nrb_hdr, int *err)
{
wtap_dumper *wdh;
+ wtap_optionblock_t descr, file_int_data;
+ wtapng_if_descr_mandatory_t *descr_mand, *file_int_data_mand;
+
+ /* Check whether we can open a capture file with that file type
+ and that encapsulation. */
+ if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
+ return NULL;
/* Allocate a data structure for the output stream. */
wdh = wtap_dump_alloc_wdh(file_type_subtype, encap, snaplen, compressed, err);
/* Set Section Header Block data */
wdh->shb_hdr = shb_hdr;
+ /* Set Name Resolution Block data */
+ wdh->nrb_hdr = nrb_hdr;
/* Set Interface Description Block data */
if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
- wdh->interface_data = idb_inf->interface_data;
+ guint itf_count;
+
+ /* XXX: what free's this stuff? */
+ wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
+ for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
+ file_int_data = g_array_index(idb_inf->interface_data, wtap_optionblock_t, itf_count);
+ file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(file_int_data);
+ descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+ wtap_optionblock_copy_options(descr, file_int_data);
+ if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data_mand->wtap_encap)) {
+ descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+ descr_mand->wtap_encap = encap;
+ descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
+ }
+ g_array_append_val(wdh->interface_data, descr);
+ }
} else {
- wtapng_if_descr_t descr;
-
- descr.wtap_encap = encap;
- descr.time_units_per_second = 1000000; /* default microsecond resolution */
- descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
- descr.snap_len = snaplen;
- descr.opt_comment = NULL;
- descr.if_name = g_strdup("Unknown/not available in original file format(libpcap)");
- descr.if_description = NULL;
- descr.if_speed = 0;
- descr.if_tsresol = 6;
- descr.if_filter_str= NULL;
- descr.bpf_filter_len= 0;
- descr.if_filter_bpf_bytes= NULL;
- descr.if_os = NULL;
- descr.if_fcslen = -1;
- descr.num_stat_entries = 0; /* Number of ISB:s */
- descr.interface_statistics = NULL;
- wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+ descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+ descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+ descr_mand->wtap_encap = encap;
+ descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+ descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
+ descr_mand->snap_len = snaplen;
+ wtap_optionblock_set_option_string(descr, OPT_IDB_NAME, "Unknown/not available in original file format(libpcap)",
+ strlen("Unknown/not available in original file format(libpcap)"));
+
+ descr_mand->num_stat_entries = 0; /* Number of ISB:s */
+ descr_mand->interface_statistics = NULL;
+ wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
g_array_append_val(wdh->interface_data, descr);
}
return wdh;
}
-wtap_dumper* wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
- int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+wtap_dumper *
+wtap_dump_open(const char *filename, int file_type_subtype, int encap,
+ int snaplen, gboolean compressed, int *err)
+{
+ return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
+}
+
+wtap_dumper *
+wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
+ int snaplen, gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtap_optionblock_t nrb_hdr, int *err)
{
wtap_dumper *wdh;
WFILE_T fh;
- /* Check whether we can open a capture file with that file type
- and that encapsulation. */
- if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
+ /* Allocate and initialize a data structure for the output stream. */
+ wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
+ shb_hdr, idb_inf, nrb_hdr, err);
+ if (wdh == NULL)
return NULL;
+ /* In case "fopen()" fails but doesn't set "errno", set "errno"
+ to a generic "the open failed" error. */
+ errno = WTAP_ERR_CANT_OPEN;
+ fh = wtap_dump_file_open(wdh, filename);
+ if (fh == NULL) {
+ *err = errno;
+ g_free(wdh);
+ return NULL; /* can't create file */
+ }
+ wdh->fh = fh;
+
+ if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
+ /* Get rid of the file we created; we couldn't finish
+ opening it. */
+ wtap_dump_file_close(wdh);
+ ws_unlink(filename);
+ g_free(wdh);
+ return NULL;
+ }
+ return wdh;
+}
+
+wtap_dumper *
+wtap_dump_open_tempfile(char **filenamep, const char *pfx,
+ int file_type_subtype, int encap,
+ int snaplen, gboolean compressed, int *err)
+{
+ return wtap_dump_open_tempfile_ng(filenamep, pfx, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
+}
+
+wtap_dumper *
+wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
+ int file_type_subtype, int encap,
+ int snaplen, gboolean compressed,
+ wtap_optionblock_t shb_hdr,
+ wtapng_iface_descriptions_t *idb_inf,
+ wtap_optionblock_t nrb_hdr, int *err)
+{
+ int fd;
+ char *tmpname;
+ wtap_dumper *wdh;
+ WFILE_T fh;
+
+ /* No path name for the temporary file yet. */
+ *filenamep = NULL;
+
/* Allocate and initialize a data structure for the output stream. */
wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
- shb_hdr, idb_inf, err);
+ shb_hdr, idb_inf, nrb_hdr, err);
if (wdh == NULL)
return NULL;
- /* "-" means stdout */
- if (strcmp(filename, "-") == 0) {
- if (compressed) {
- *err = EINVAL; /* XXX - return a Wiretap error code for this */
- g_free(wdh);
- return NULL; /* compress won't work on stdout */
- }
-#ifdef _WIN32
- if (_setmode(fileno(stdout), O_BINARY) == -1) {
- /* "Should not happen" */
- *err = errno;
- g_free(wdh);
- return NULL; /* couldn't put standard output in binary mode */
- }
-#endif
- wdh->fh = stdout;
- } else {
- /* In case "fopen()" fails but doesn't set "errno", set "errno"
- to a generic "the open failed" error. */
- errno = WTAP_ERR_CANT_OPEN;
- fh = wtap_dump_file_open(wdh, filename);
- if (fh == NULL) {
- *err = errno;
- g_free(wdh);
- return NULL; /* can't create file */
- }
- wdh->fh = fh;
+ /* Choose a random name for the file */
+ fd = create_tempfile(&tmpname, pfx);
+ if (fd == -1) {
+ *err = errno;
+ g_free(wdh);
+ return NULL; /* can't create file */
+ }
+ *filenamep = tmpname;
+
+ /* In case "fopen()" fails but doesn't set "errno", set "errno"
+ to a generic "the open failed" error. */
+ errno = WTAP_ERR_CANT_OPEN;
+ fh = wtap_dump_file_fdopen(wdh, fd);
+ if (fh == NULL) {
+ *err = errno;
+ ws_close(fd);
+ g_free(wdh);
+ return NULL; /* can't create file */
}
+ wdh->fh = fh;
if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
/* Get rid of the file we created; we couldn't finish
opening it. */
- if (wdh->fh != stdout) {
- wtap_dump_file_close(wdh);
- ws_unlink(filename);
- }
+ wtap_dump_file_close(wdh);
+ ws_unlink(tmpname);
g_free(wdh);
return NULL;
}
return wdh;
}
-wtap_dumper* wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
- gboolean compressed, int *err)
+wtap_dumper *
+wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
+ gboolean compressed, int *err)
{
- return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, err);
+ return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
}
-wtap_dumper* wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
- gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+wtap_dumper *
+wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
+ gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtap_optionblock_t nrb_hdr, int *err)
{
wtap_dumper *wdh;
WFILE_T fh;
- /* Check whether we can open a capture file with that file type
- and that encapsulation. */
- if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
+ /* Allocate and initialize a data structure for the output stream. */
+ wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
+ shb_hdr, idb_inf, nrb_hdr, err);
+ if (wdh == NULL)
return NULL;
+ /* In case "fopen()" fails but doesn't set "errno", set "errno"
+ to a generic "the open failed" error. */
+ errno = WTAP_ERR_CANT_OPEN;
+ fh = wtap_dump_file_fdopen(wdh, fd);
+ if (fh == NULL) {
+ *err = errno;
+ g_free(wdh);
+ return NULL; /* can't create standard I/O stream */
+ }
+ wdh->fh = fh;
+
+ if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
+ wtap_dump_file_close(wdh);
+ g_free(wdh);
+ return NULL;
+ }
+ return wdh;
+}
+
+wtap_dumper *
+wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
+ gboolean compressed, int *err)
+{
+ return wtap_dump_open_stdout_ng(file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
+}
+
+wtap_dumper *
+wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
+ gboolean compressed, wtap_optionblock_t shb_hdr,
+ wtapng_iface_descriptions_t *idb_inf,
+ wtap_optionblock_t nrb_hdr, int *err)
+{
+ wtap_dumper *wdh;
+ WFILE_T fh;
+
/* Allocate and initialize a data structure for the output stream. */
wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
- shb_hdr, idb_inf, err);
+ shb_hdr, idb_inf, nrb_hdr, err);
if (wdh == NULL)
return NULL;
#ifdef _WIN32
- if (fd == 1) {
- if (_setmode(fileno(stdout), O_BINARY) == -1) {
- /* "Should not happen" */
- *err = errno;
- g_free(wdh);
- return NULL; /* couldn't put standard output in binary mode */
- }
+ /*
+ * Put the standard output into binary mode.
+ *
+ * XXX - even if the file format we're writing is a text
+ * format?
+ */
+ if (_setmode(1, O_BINARY) == -1) {
+ /* "Should not happen" */
+ *err = errno;
+ g_free(wdh);
+ return NULL; /* couldn't put standard output in binary mode */
}
#endif
/* In case "fopen()" fails but doesn't set "errno", set "errno"
to a generic "the open failed" error. */
errno = WTAP_ERR_CANT_OPEN;
- fh = wtap_dump_file_fdopen(wdh, fd);
+ fh = wtap_dump_file_fdopen(wdh, 1);
if (fh == NULL) {
*err = errno;
g_free(wdh);
return NULL; /* can't create standard I/O stream */
}
wdh->fh = fh;
+ wdh->is_stdout = TRUE;
if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
wtap_dump_file_close(wdh);
return wdh;
}
-static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
+static gboolean
+wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
{
if (!wtap_dump_can_open(file_type_subtype)) {
/* Invalid type, or type we don't know how to write. */
- *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
+ *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
return FALSE;
}
return TRUE;
}
-static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen,
- gboolean compressed, int *err)
+static wtap_dumper *
+wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean compressed, int *err)
{
wtap_dumper *wdh;
return wdh;
}
-static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
+static gboolean
+wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
{
int fd;
gboolean cant_seek;
if(compressed) {
cant_seek = TRUE;
} else {
- fd = fileno((FILE *)wdh->fh);
- if (lseek(fd, 1, SEEK_CUR) == -1)
+ fd = ws_fileno((FILE *)wdh->fh);
+ if (ws_lseek64(fd, 1, SEEK_CUR) == (off_t) -1)
cant_seek = TRUE;
else {
/* Undo the seek. */
- lseek(fd, 0, SEEK_SET);
+ ws_lseek64(fd, 0, SEEK_SET);
cant_seek = FALSE;
}
}
return TRUE; /* success! */
}
-gboolean wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
- const guint8 *pd, int *err)
+gboolean
+wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+ const guint8 *pd, int *err, gchar **err_info)
{
- return (wdh->subtype_write)(wdh, phdr, pd, err);
+ *err = 0;
+ *err_info = NULL;
+ return (wdh->subtype_write)(wdh, phdr, pd, err, err_info);
}
-void wtap_dump_flush(wtap_dumper *wdh)
+void
+wtap_dump_flush(wtap_dumper *wdh)
{
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
if(wdh->compressed) {
gzwfile_flush((GZWFILE_T)wdh->fh);
} else
}
}
-gboolean wtap_dump_close(wtap_dumper *wdh, int *err)
+gboolean
+wtap_dump_close(wtap_dumper *wdh, int *err)
{
gboolean ret = TRUE;
- if (wdh->subtype_close != NULL) {
- /* There's a close routine for this dump stream. */
- if (!(wdh->subtype_close)(wdh, err))
+ if (wdh->subtype_finish != NULL) {
+ /* There's a finish routine for this dump stream. */
+ if (!(wdh->subtype_finish)(wdh, err))
ret = FALSE;
}
errno = WTAP_ERR_CANT_CLOSE;
- /* Don't close stdout */
- if (wdh->fh != stdout) {
- if (wtap_dump_file_close(wdh) == EOF) {
- if (ret) {
- /* The per-format close function succeeded,
- but the fclose didn't. Save the reason
- why, if our caller asked for it. */
- if (err != NULL)
- *err = errno;
- }
- ret = FALSE;
+ if (wtap_dump_file_close(wdh) == EOF) {
+ if (ret) {
+ /* The per-format finish function succeeded,
+ but the stream close didn't. Save the
+ reason why, if our caller asked for it. */
+ if (err != NULL)
+ *err = errno;
}
- } else {
- /* as we don't close stdout, at least try to flush it */
- wtap_dump_flush(wdh);
+ ret = FALSE;
}
if (wdh->priv != NULL)
g_free(wdh->priv);
return ret;
}
-gint64 wtap_get_bytes_dumped(wtap_dumper *wdh)
+gint64
+wtap_get_bytes_dumped(wtap_dumper *wdh)
{
return wdh->bytes_dumped;
}
-void wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
+void
+wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
{
wdh->bytes_dumped = bytes_dumped;
}
-gboolean wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
+gboolean
+wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
{
if (!wdh || wdh->file_type_subtype < 0 || wdh->file_type_subtype >= wtap_num_file_types_subtypes
|| dump_open_table[wdh->file_type_subtype].has_name_resolution == FALSE)
}
/* internally open a file for writing (compressed or not) */
-#ifdef HAVE_LIBZ
-static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
+#ifdef HAVE_ZLIB
+static WFILE_T
+wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
{
if(wdh->compressed) {
return gzwfile_open(filename);
}
}
#else
-static WFILE_T wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
+static WFILE_T
+wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
{
return ws_fopen(filename, "wb");
}
#endif
/* internally open a file for writing (compressed or not) */
-#ifdef HAVE_LIBZ
-static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
+#ifdef HAVE_ZLIB
+static WFILE_T
+wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
{
if(wdh->compressed) {
return gzwfile_fdopen(fd);
} else {
- return fdopen(fd, "wb");
+ return ws_fdopen(fd, "wb");
}
}
#else
-static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
+static WFILE_T
+wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
{
- return fdopen(fd, "wb");
+ return ws_fdopen(fd, "wb");
}
#endif
/* internally writing raw bytes (compressed or not) */
-gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize,
- int *err)
+gboolean
+wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize, int *err)
{
size_t nwritten;
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
if (wdh->compressed) {
- nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned) bufsize);
+ nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned int) bufsize);
/*
* gzwfile_write() returns 0 on error.
*/
} else
#endif
{
+ errno = WTAP_ERR_CANT_WRITE;
nwritten = fwrite(buf, 1, bufsize, (FILE *)wdh->fh);
/*
* At least according to the Mac OS X man page,
}
/* internally close a file for writing (compressed or not) */
-static int wtap_dump_file_close(wtap_dumper *wdh)
+static int
+wtap_dump_file_close(wtap_dumper *wdh)
{
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
if(wdh->compressed) {
- return gzwfile_close((GZWFILE_T)wdh->fh);
+ /*
+ * Tell gzwfile_close() whether to close the descriptor
+ * or not.
+ */
+ return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout);
} else
#endif
{
- return fclose((FILE *)wdh->fh);
+ /*
+ * Don't close the standard output.
+ *
+ * XXX - this really should do everything fclose() does,
+ * including freeing all allocated data structures,
+ * *except* for actually closing the file descriptor.
+ */
+ return wdh->is_stdout ? fflush((FILE *)wdh->fh) : fclose((FILE *)wdh->fh);
}
}
-gint64 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
+gint64
+wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
{
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
if(wdh->compressed) {
*err = WTAP_ERR_CANT_SEEK_COMPRESSED;
return -1;
}
}
}
-gint64 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
+
+gint64
+wtap_dump_file_tell(wtap_dumper *wdh, int *err)
{
gint64 rval;
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
if(wdh->compressed) {
*err = WTAP_ERR_CANT_SEEK_COMPRESSED;
return -1;
}
}
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */