4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <wsutil/file_util.h>
31 #include "file_wrappers.h"
32 #include <wsutil/buffer.h>
33 #include "lanalyzer.h"
34 #include "ngsniffer.h"
36 #include "ascendtext.h"
49 #include "peekclassic.h"
50 #include "peektagged.h"
52 #include "dbs-etherwatch.h"
59 #include "logcat_text.h"
61 #include "network_instruments.h"
64 #include "catapult_dct2000.h"
67 #include "netscreen.h"
73 #include "dct3trace.h"
74 #include "packetlogger.h"
75 #include "daintree-sna.h"
76 #include "netscaler.h"
77 #include "mime_file.h"
81 #include "stanag4607.h"
83 #include "pcap-encap.h"
84 #include "nettrace_3gpp_32_423.h"
87 * Add an extension, and all compressed versions thereof, to a GSList
91 add_extensions(GSList *extensions, const gchar *extension,
92 GSList *compressed_file_extensions)
94 GSList *compressed_file_extension;
97 * Add the specified extension.
99 extensions = g_slist_append(extensions, g_strdup(extension));
102 * Now add the extensions for compressed-file versions of
105 for (compressed_file_extension = compressed_file_extensions;
106 compressed_file_extension != NULL;
107 compressed_file_extension = g_slist_next(compressed_file_extension)) {
108 extensions = g_slist_append(extensions,
109 g_strdup_printf("%s.%s", extension,
110 (gchar *)compressed_file_extension->data));
117 * File types that can be identified by file extensions.
119 * These are used in file open dialogs to offer choices of extensions
120 * for which to filter. Note that the first field can list more than
121 * one type of file, because, for example, ".cap" is a popular
122 * extension used by a number of capture file types.
124 static const struct file_extension_info file_type_extensions_base[] = {
125 { "Wireshark/tcpdump/... - pcap", "pcap;cap;dmp" },
126 { "Wireshark/... - pcapng", "pcapng;ntar" },
127 { "Network Monitor, Surveyor, NetScaler", "cap" },
128 { "InfoVista 5View capture", "5vw" },
129 { "Sniffer (DOS)", "cap;enc;trc;fdc;syc" },
130 { "Cinco NetXRay, Sniffer (Windows)", "cap;caz" },
131 { "Endace ERF capture", "erf" },
132 { "EyeSDN USB S0/E1 ISDN trace format", "trc" },
133 { "HP-UX nettl trace", "trc0;trc1" },
134 { "Network Instruments Observer", "bfr" },
135 { "Colasoft Capsa", "cscpkt" },
136 { "Novell LANalyzer", "tr1" },
137 { "Tektronix K12xx 32-bit .rf5 format", "rf5" },
138 { "Savvius *Peek", "pkt;tpc;apc;wpz" },
139 { "Catapult DCT2000 trace (.out format)", "out" },
140 { "MPEG files", "mpg;mp3" },
141 { "TamoSoft CommView", "ncf" },
142 { "Symbian OS btsnoop", "log" },
143 { "Transport-Neutral Encapsulation Format", "tnef" },
144 { "XML files (including Gammu DCT3 traces)", "xml" },
145 { "OS X PacketLogger", "pklg" },
146 { "Daintree SNA", "dcf" },
147 { "JPEG/JFIF files", "jpg;jpeg;jfif" },
148 { "IPFIX File Format", "pfx;ipfix" },
149 { "Aethra .aps file", "aps" },
150 { "MPEG2 transport stream", "mp2t;ts;mpg" },
151 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr" },
152 { "CAM Inspector file", "camins" },
153 { "JavaScript Object Notation file", "json" }
156 #define N_FILE_TYPE_EXTENSIONS (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
158 static const struct file_extension_info* file_type_extensions = NULL;
160 static GArray* file_type_extensions_arr = NULL;
162 /* initialize the extensions array if it has not been initialized yet */
164 init_file_type_extensions(void)
167 if (file_type_extensions_arr) return;
169 file_type_extensions_arr = g_array_new(FALSE,TRUE,sizeof(struct file_extension_info));
171 g_array_append_vals(file_type_extensions_arr,file_type_extensions_base,N_FILE_TYPE_EXTENSIONS);
173 file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
177 wtap_register_file_type_extension(const struct file_extension_info *ei)
179 init_file_type_extensions();
181 g_array_append_val(file_type_extensions_arr,*ei);
183 file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
187 wtap_get_num_file_type_extensions(void)
189 return file_type_extensions_arr->len;
193 wtap_get_file_extension_type_name(int extension_type)
195 return file_type_extensions[extension_type].name;
199 add_extensions_for_file_extensions_type(int extension_type,
200 GSList *extensions, GSList *compressed_file_extensions)
202 gchar **extensions_set, **extensionp, *extension;
205 * Split the extension-list string into a set of extensions.
207 extensions_set = g_strsplit(file_type_extensions[extension_type].extensions,
211 * Add each of those extensions to the list.
213 for (extensionp = extensions_set; *extensionp != NULL; extensionp++) {
214 extension = *extensionp;
217 * Add the extension, and all compressed variants
220 extensions = add_extensions(extensions, extension,
221 compressed_file_extensions);
224 g_strfreev(extensions_set);
228 /* Return a list of file extensions that are used by the specified file
231 All strings in the list are allocated with g_malloc() and must be freed
234 wtap_get_file_extension_type_extensions(guint extension_type)
236 GSList *compressed_file_extensions;
239 if (extension_type >= file_type_extensions_arr->len)
240 return NULL; /* not a valid extension type */
242 extensions = NULL; /* empty list, to start with */
245 * Get the list of compressed-file extensions.
247 compressed_file_extensions = wtap_get_compressed_file_extensions();
250 * Add all this file extension type's extensions, with compressed
253 extensions = add_extensions_for_file_extensions_type(extension_type,
254 extensions, compressed_file_extensions);
256 g_slist_free(compressed_file_extensions);
260 /* Return a list of all extensions that are used by all file types,
261 including compressed extensions, e.g. not just "pcap" but also
262 "pcap.gz" if we can read gzipped files.
264 All strings in the list are allocated with g_malloc() and must be freed
267 wtap_get_all_file_extensions_list(void)
269 GSList *compressed_file_extensions;
273 init_file_type_extensions();
275 extensions = NULL; /* empty list, to start with */
278 * Get the list of compressed-file extensions.
280 compressed_file_extensions = wtap_get_compressed_file_extensions();
282 for (i = 0; i < file_type_extensions_arr->len; i++) {
284 * Add all this file extension type's extensions, with
285 * compressed variants.
287 extensions = add_extensions_for_file_extensions_type(i,
288 extensions, compressed_file_extensions);
291 g_slist_free(compressed_file_extensions);
296 * The open_file_* routines should return:
298 * -1 on an I/O error;
300 * 1 if the file they're reading is one of the types it handles;
302 * 0 if the file they're reading isn't the type they're checking for.
304 * If the routine handles this type of file, it should set the "file_type"
305 * field in the "struct wtap" to the type of the file.
307 * Note that the routine does not have to free the private data pointer on
308 * error. The caller takes care of that by calling wtap_close on error.
309 * (See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8518)
311 * However, the caller does have to free the private data pointer when
312 * returning 0, since the next file type will be called and will likely
313 * just overwrite the pointer.
315 * The names are used in file open dialogs to select, for files that
316 * don't have magic numbers and that could potentially be files of
317 * more than one type based on the heuristics, a particular file
318 * type to interpret it as, if the file name has no extension, the
319 * extension isn't sufficient to determine the appropriate file type,
320 * or the extension is wrong.
322 static struct open_info open_info_base[] = {
323 { "Wireshark/tcpdump/... - pcap", OPEN_INFO_MAGIC, libpcap_open, "pcap", NULL, NULL },
324 { "Wireshark/... - pcapng", OPEN_INFO_MAGIC, pcapng_open, "pcapng", NULL, NULL },
325 { "Sniffer (DOS)", OPEN_INFO_MAGIC, ngsniffer_open, NULL, NULL, NULL },
326 { "Snoop, Shomiti/Finisar Surveyor", OPEN_INFO_MAGIC, snoop_open, NULL, NULL, NULL },
327 { "AIX iptrace", OPEN_INFO_MAGIC, iptrace_open, NULL, NULL, NULL },
328 { "Microsoft Network Monitor", OPEN_INFO_MAGIC, netmon_open, NULL, NULL, NULL },
329 { "Cinco NetXray/Sniffer (Windows)", OPEN_INFO_MAGIC, netxray_open, NULL, NULL, NULL },
330 { "RADCOM WAN/LAN analyzer", OPEN_INFO_MAGIC, radcom_open, NULL, NULL, NULL },
331 { "HP-UX nettl trace", OPEN_INFO_MAGIC, nettl_open, NULL, NULL, NULL },
332 { "Visual Networks traffic capture", OPEN_INFO_MAGIC, visual_open, NULL, NULL, NULL },
333 { "InfoVista 5View capture", OPEN_INFO_MAGIC, _5views_open, NULL, NULL, NULL },
334 { "Network Instruments Observer", OPEN_INFO_MAGIC, network_instruments_open, NULL, NULL, NULL },
335 { "Savvius tagged", OPEN_INFO_MAGIC, peektagged_open, NULL, NULL, NULL },
336 { "Colasoft Capsa", OPEN_INFO_MAGIC, capsa_open, NULL, NULL, NULL },
337 { "DBS Etherwatch (VMS)", OPEN_INFO_MAGIC, dbs_etherwatch_open, NULL, NULL, NULL },
338 { "Tektronix K12xx 32-bit .rf5 format", OPEN_INFO_MAGIC, k12_open, NULL, NULL, NULL },
339 { "Catapult DCT2000 trace (.out format)", OPEN_INFO_MAGIC, catapult_dct2000_open, NULL, NULL, NULL },
340 { "Aethra .aps file", OPEN_INFO_MAGIC, aethra_open, NULL, NULL, NULL },
341 { "Symbian OS btsnoop", OPEN_INFO_MAGIC, btsnoop_open, "log", NULL, NULL },
342 { "EyeSDN USB S0/E1 ISDN trace format", OPEN_INFO_MAGIC, eyesdn_open, NULL, NULL, NULL },
343 { "Transport-Neutral Encapsulation Format", OPEN_INFO_MAGIC, tnef_open, NULL, NULL, NULL },
344 /* 3GPP TS 32.423 Trace must come before MIME Files as it's XML based*/
345 { "3GPP TS 32.423 Trace format", OPEN_INFO_MAGIC, nettrace_3gpp_32_423_file_open, NULL, NULL, NULL },
346 { "MIME Files Format", OPEN_INFO_MAGIC, mime_file_open, NULL, NULL, NULL },
347 { "Novell LANalyzer", OPEN_INFO_HEURISTIC, lanalyzer_open, "tr1", NULL, NULL },
349 * PacketLogger must come before MPEG, because its files
350 * are sometimes grabbed by mpeg_open.
352 { "OS X PacketLogger", OPEN_INFO_HEURISTIC, packetlogger_open, "pklg", NULL, NULL },
353 /* Some MPEG files have magic numbers, others just have heuristics. */
354 { "MPEG", OPEN_INFO_HEURISTIC, mpeg_open, "mpg;mp3", NULL, NULL },
355 { "Gammu DCT3 trace", OPEN_INFO_HEURISTIC, dct3trace_open, "xml", NULL, NULL },
356 { "Daintree SNA", OPEN_INFO_HEURISTIC, daintree_sna_open, "dcf", NULL, NULL },
357 { "STANAG 4607 Format", OPEN_INFO_HEURISTIC, stanag4607_open, NULL, NULL, NULL },
358 { "ASN.1 Basic Encoding Rules", OPEN_INFO_HEURISTIC, ber_open, NULL, NULL, NULL },
360 * I put NetScreen *before* erf, because there were some
361 * false positives with my test-files (Sake Blok, July 2007)
363 * I put VWR *after* ERF, because there were some cases where
364 * ERF files were misidentified as vwr files (Stephen
365 * Donnelly, August 2013; see bug 9054)
367 * I put VWR *after* Peek Classic, CommView, iSeries text,
368 * Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
369 * because there were some cases where files of those types were
370 * misidentified as vwr files (Guy Harris, December 2013)
372 { "NetScreen snoop text file", OPEN_INFO_HEURISTIC, netscreen_open, "txt", NULL, NULL },
373 { "Endace ERF capture", OPEN_INFO_HEURISTIC, erf_open, "erf", NULL, NULL },
374 { "IPFIX File Format", OPEN_INFO_HEURISTIC, ipfix_open, "pfx;ipfix",NULL, NULL },
375 { "K12 text file", OPEN_INFO_HEURISTIC, k12text_open, "txt", NULL, NULL },
376 { "Savvius classic", OPEN_INFO_HEURISTIC, peekclassic_open, "pkt;tpc;apc;wpz", NULL, NULL },
377 { "pppd log (pppdump format)", OPEN_INFO_HEURISTIC, pppdump_open, NULL, NULL, NULL },
378 { "IBM iSeries comm. trace", OPEN_INFO_HEURISTIC, iseries_open, "txt", NULL, NULL },
379 { "I4B ISDN trace", OPEN_INFO_HEURISTIC, i4btrace_open, NULL, NULL, NULL },
380 { "MPEG2 transport stream", OPEN_INFO_HEURISTIC, mp2t_open, "ts;mpg", NULL, NULL },
381 { "CSIDS IPLog", OPEN_INFO_HEURISTIC, csids_open, NULL, NULL, NULL },
382 { "TCPIPtrace (VMS)", OPEN_INFO_HEURISTIC, vms_open, "txt", NULL, NULL },
383 { "CoSine IPSX L2 capture", OPEN_INFO_HEURISTIC, cosine_open, "txt", NULL, NULL },
384 { "Bluetooth HCI dump", OPEN_INFO_HEURISTIC, hcidump_open, NULL, NULL, NULL },
385 { "TamoSoft CommView", OPEN_INFO_HEURISTIC, commview_open, "ncf", NULL, NULL },
386 { "NetScaler", OPEN_INFO_HEURISTIC, nstrace_open, "cap", NULL, NULL },
387 { "Android Logcat Binary format", OPEN_INFO_HEURISTIC, logcat_open, "logcat", NULL, NULL },
388 { "Android Logcat Text formats", OPEN_INFO_HEURISTIC, logcat_text_open, "txt", NULL, NULL },
389 /* ASCII trace files from Telnet sessions. */
390 { "Lucent/Ascend access server trace", OPEN_INFO_HEURISTIC, ascend_open, "txt", NULL, NULL },
391 { "Toshiba Compact ISDN Router snoop", OPEN_INFO_HEURISTIC, toshiba_open, "txt", NULL, NULL },
392 /* Extremely weak heuristics - put them at the end. */
393 { "Ixia IxVeriWave .vwr Raw Capture", OPEN_INFO_HEURISTIC, vwr_open, "vwr", NULL, NULL },
394 { "CAM Inspector file", OPEN_INFO_HEURISTIC, camins_open, "camins", NULL, NULL },
395 { "JavaScript Object Notation", OPEN_INFO_HEURISTIC, json_open, "json", NULL, NULL }
398 /* this is only used to build the dynamic array on load, do NOT use this
399 * for anything else, because the size of the actual array will change if
400 * Lua scripts register a new file reader.
402 #define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
404 static GArray *open_info_arr = NULL;
406 /* this always points to the top of the created array */
407 struct open_info *open_routines = NULL;
409 /* this points to the first OPEN_INFO_HEURISTIC type in the array */
410 static guint heuristic_open_routine_idx = 0;
413 set_heuristic_routine(void)
416 g_assert(open_info_arr != NULL);
418 for (i = 0; i < open_info_arr->len; i++) {
419 if (open_routines[i].type == OPEN_INFO_HEURISTIC) {
420 heuristic_open_routine_idx = i;
424 g_assert(open_routines[i].type == OPEN_INFO_MAGIC);
427 g_assert(heuristic_open_routine_idx > 0);
431 init_open_routines(void)
434 struct open_info *i_open;
439 open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
441 g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
443 open_routines = (struct open_info *)(void*) open_info_arr->data;
445 /* Populate the extensions_set list now */
446 for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
447 if (i_open->extensions != NULL)
448 i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
451 set_heuristic_routine();
455 * Registers a new file reader - currently only called by wslua code for Lua readers.
456 * If first_routine is true, it's added before other readers of its type (magic or heuristic).
457 * Also, it checks for an existing reader of the same name and errors if it finds one; if
458 * you want to handle that condition more gracefully, call wtap_has_open_info() first.
461 wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
463 init_open_routines();
465 if (!oi || !oi->name) {
466 g_error("No open_info name given to register");
470 /* verify name doesn't already exist */
471 if (wtap_has_open_info(oi->name)) {
472 g_error("Name given to register_open_info already exists");
476 if (oi->extensions != NULL)
477 oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
479 /* if it's magic and first, prepend it; if it's heuristic and not first,
480 append it; if it's anything else, stick it in the middle */
481 if (first_routine && oi->type == OPEN_INFO_MAGIC) {
482 g_array_prepend_val(open_info_arr, *oi);
483 } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
484 g_array_append_val(open_info_arr, *oi);
486 g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
489 open_routines = (struct open_info *)(void*) open_info_arr->data;
490 set_heuristic_routine();
493 /* De-registers a file reader by removign it from the GArray based on its name.
494 * This function must NOT be called during wtap_open_offline(), since it changes the array.
495 * Note: this function will error if it doesn't find the given name; if you want to handle
496 * that condition more gracefully, call wtap_has_open_info() first.
499 wtap_deregister_open_info(const gchar *name)
502 init_open_routines();
505 g_error("Missing open_info name to de-register");
509 for (i = 0; i < open_info_arr->len; i++) {
510 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
511 if (open_routines[i].extensions_set != NULL)
512 g_strfreev(open_routines[i].extensions_set);
513 open_info_arr = g_array_remove_index(open_info_arr, i);
514 set_heuristic_routine();
519 g_error("deregister_open_info: name not found");
522 /* Determines if a open routine short name already exists
525 wtap_has_open_info(const gchar *name)
528 init_open_routines();
531 g_error("No name given to wtap_has_open_info!");
536 for (i = 0; i < open_info_arr->len; i++) {
537 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
546 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
547 * define them either.)
549 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
552 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
555 #define S_IFIFO _S_IFIFO
558 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
561 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
564 /* returns the 'type' number to use for wtap_open_offline based on the
565 passed-in name (the name in the open_info struct). It returns WTAP_TYPE_AUTO
566 on failure, which is the number 0. The 'type' number is the entry's index+1,
567 because that's what wtap_open_offline() expects it to be. */
569 open_info_name_to_type(const char *name)
572 init_open_routines();
575 return WTAP_TYPE_AUTO;
577 for (i = 0; i < open_info_arr->len; i++) {
578 if (open_routines[i].name != NULL &&
579 strcmp(name, open_routines[i].name) == 0)
583 return WTAP_TYPE_AUTO; /* no such file type */
587 get_file_extension(const char *pathname)
592 GSList *compressed_file_extensions, *compressed_file_extension;
596 * Is the pathname empty?
598 if (strcmp(pathname, "") == 0)
599 return NULL; /* no extension */
602 * Find the last component of the pathname.
604 filename = g_path_get_basename(pathname);
607 * Does it have an extension?
609 if (strchr(filename, '.') == NULL) {
611 return NULL; /* no extension whatsoever */
615 * Yes. Split it into components separated by ".".
617 components = g_strsplit(filename, ".", 0);
621 * Count the components.
623 for (ncomponents = 0; components[ncomponents] != NULL; ncomponents++)
626 if (ncomponents == 0) {
627 g_strfreev(components);
628 return NULL; /* no components */
630 if (ncomponents == 1) {
631 g_strfreev(components);
632 return NULL; /* only one component, with no "." */
636 * Is the last component one of the extensions used for compressed
639 compressed_file_extensions = wtap_get_compressed_file_extensions();
640 if (compressed_file_extensions == NULL) {
642 * We don't support reading compressed files, so just
643 * return a copy of whatever extension we did find.
645 extensionp = g_strdup(components[ncomponents - 1]);
646 g_strfreev(components);
649 extensionp = components[ncomponents - 1];
650 for (compressed_file_extension = compressed_file_extensions;
651 compressed_file_extension != NULL;
652 compressed_file_extension = g_slist_next(compressed_file_extension)) {
653 if (strcmp(extensionp, (char *)compressed_file_extension->data) == 0) {
655 * Yes, it's one of the compressed-file extensions.
656 * Is there an extension before that?
658 if (ncomponents == 2) {
659 g_strfreev(components);
660 return NULL; /* no, only two components */
664 * Yes, return that extension.
666 extensionp = g_strdup(components[ncomponents - 2]);
667 g_strfreev(components);
673 * The extension isn't one of the compressed-file extensions;
676 extensionp = g_strdup(extensionp);
677 g_strfreev(components);
682 * Check if file extension is used in this heuristic
685 heuristic_uses_extension(unsigned int i, const char *extension)
690 * Does this file type *have* any extensions?
692 if (open_routines[i].extensions == NULL)
693 return FALSE; /* no */
696 * Check each of them against the specified extension.
698 for (extensionp = open_routines[i].extensions_set; *extensionp != NULL;
700 if (strcmp(extension, *extensionp) == 0) {
701 return TRUE; /* it's one of them */
705 return FALSE; /* it's not one of them */
708 /* Opens a file and prepares a wtap struct.
709 If "do_random" is TRUE, it opens the file twice; the second open
710 allows the application to do random-access I/O without moving
711 the seek offset for sequential I/O, which is used by Wireshark
712 so that it can do sequential I/O to a capture file that's being
713 written to as new packets arrive independently of random I/O done
714 to display protocol trees for packets when they're selected. */
716 wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
723 gboolean use_stdin = FALSE;
729 init_open_routines();
731 /* open standard input if filename is '-' */
732 if (strcmp(filename, "-") == 0)
735 /* First, make sure the file is valid */
737 if (ws_fstat64(0, &statb) < 0) {
742 if (ws_stat64(filename, &statb) < 0) {
747 if (S_ISFIFO(statb.st_mode)) {
749 * Opens of FIFOs are allowed only when not opening
752 * Currently, we do seeking when trying to find out
753 * the file type, but our I/O routines do some amount
754 * of buffering, and do backward seeks within the buffer
755 * if possible, so at least some file types can be
756 * opened from pipes, so we don't completely disallow opens
760 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
763 } else if (S_ISDIR(statb.st_mode)) {
765 * Return different errors for "this is a directory"
766 * and "this is some random special file type", so
767 * the user can get a potentially more helpful error.
771 } else if (! S_ISREG(statb.st_mode)) {
772 *err = WTAP_ERR_NOT_REGULAR_FILE;
777 * We need two independent descriptors for random access, so
778 * they have different file positions. If we're opening the
779 * standard input, we can only dup it to get additional
780 * descriptors, so we can't have two independent descriptors,
781 * and thus can't do random access.
783 if (use_stdin && do_random) {
784 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
789 wth = (wtap *)g_malloc0(sizeof(wtap));
792 errno = WTAP_ERR_CANT_OPEN;
795 * We dup FD 0, so that we don't have to worry about
796 * a file_close of wth->fh closing the standard
797 * input of the process.
806 if (_setmode(fd, O_BINARY) == -1) {
807 /* "Shouldn't happen" */
813 if (!(wth->fh = file_fdopen(fd))) {
820 if (!(wth->fh = file_open(filename))) {
828 if (!(wth->random_fh = file_open(filename))) {
835 wth->random_fh = NULL;
838 wth->file_encap = WTAP_ENCAP_UNKNOWN;
839 wth->subtype_sequential_close = NULL;
840 wth->subtype_close = NULL;
841 wth->file_tsprec = WTAP_TSPREC_USEC;
843 wth->wslua_data = NULL;
845 /* Initialize the array containing a list of interfaces. pcapng_open and
846 * erf_open needs this (and libpcap_open for ERF encapsulation types).
847 * Always initing it here saves checking for a NULL ptr later. */
848 wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
850 if (wth->random_fh) {
851 wth->fast_seek = g_ptr_array_new();
853 file_set_random_access(wth->fh, FALSE, wth->fast_seek);
854 file_set_random_access(wth->random_fh, TRUE, wth->fast_seek);
857 /* 'type' is 1 greater than the array index */
858 if (type != WTAP_TYPE_AUTO && type <= open_info_arr->len) {
861 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
862 /* I/O error - give up */
867 /* Set wth with wslua data if any - this is how we pass the data
868 * to the file reader, kinda like the priv member but not free'd later.
869 * It's ok for this to copy a NULL.
871 wth->wslua_data = open_routines[type - 1].wslua_data;
873 result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
876 case WTAP_OPEN_ERROR:
877 /* Error - give up */
881 case WTAP_OPEN_NOT_MINE:
882 /* No error, but not that type of file */
886 /* We found the file type */
891 /* Try all file types that support magic numbers */
892 for (i = 0; i < heuristic_open_routine_idx; i++) {
893 /* Seek back to the beginning of the file; the open routine
894 for the previous file type may have left the file
895 position somewhere other than the beginning, and the
896 open routine for this file type will probably want
897 to start reading at the beginning.
899 Initialize the data offset while we're at it. */
900 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
901 /* Error - give up */
906 /* Set wth with wslua data if any - this is how we pass the data
907 * to the file reader, kinda like the priv member but not free'd later.
908 * It's ok for this to copy a NULL.
910 wth->wslua_data = open_routines[i].wslua_data;
912 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
914 case WTAP_OPEN_ERROR:
915 /* Error - give up */
919 case WTAP_OPEN_NOT_MINE:
920 /* No error, but not that type of file */
924 /* We found the file type */
930 /* Does this file's name have an extension? */
931 extension = get_file_extension(filename);
932 if (extension != NULL) {
933 /* Yes - try the heuristic types that use that extension first. */
934 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
935 /* Does this type use that extension? */
936 if (heuristic_uses_extension(i, extension)) {
938 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
939 /* Error - give up */
945 /* Set wth with wslua data if any - this is how we pass the data
946 * to the file reader, kind of like priv but not free'd later.
948 wth->wslua_data = open_routines[i].wslua_data;
950 switch ((*open_routines[i].open_routine)(wth,
953 case WTAP_OPEN_ERROR:
954 /* Error - give up */
959 case WTAP_OPEN_NOT_MINE:
960 /* No error, but not that type of file */
964 /* We found the file type */
972 * Now try the heuristic types that have no extensions
973 * to check; we try those before the ones that have
974 * extensions that *don't* match this file's extension,
975 * on the theory that files of those types generally
976 * have one of the type's extensions, and, as this file
977 * *doesn't* have one of those extensions, it's probably
978 * *not* one of those files.
980 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
981 /* Does this type have any extensions? */
982 if (open_routines[i].extensions == NULL) {
984 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
985 /* Error - give up */
991 /* Set wth with wslua data if any - this is how we pass the data
992 * to the file reader, kind of like priv but not free'd later.
994 wth->wslua_data = open_routines[i].wslua_data;
996 switch ((*open_routines[i].open_routine)(wth,
999 case WTAP_OPEN_ERROR:
1000 /* Error - give up */
1005 case WTAP_OPEN_NOT_MINE:
1006 /* No error, but not that type of file */
1009 case WTAP_OPEN_MINE:
1010 /* We found the file type */
1018 * Now try the ones that have extensions where none of
1019 * them matches this file's extensions.
1021 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1023 * Does this type have extensions and is this file's
1024 * extension one of them?
1026 if (open_routines[i].extensions != NULL &&
1027 !heuristic_uses_extension(i, extension)) {
1029 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1030 /* Error - give up */
1036 /* Set wth with wslua data if any - this is how we pass the data
1037 * to the file reader, kind of like priv but not free'd later.
1039 wth->wslua_data = open_routines[i].wslua_data;
1041 switch ((*open_routines[i].open_routine)(wth,
1044 case WTAP_OPEN_ERROR:
1045 /* Error - give up */
1050 case WTAP_OPEN_NOT_MINE:
1051 /* No error, but not that type of file */
1054 case WTAP_OPEN_MINE:
1055 /* We found the file type */
1063 /* No - try all the heuristics types in order. */
1064 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1066 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1067 /* Error - give up */
1072 /* Set wth with wslua data if any - this is how we pass the data
1073 * to the file reader, kind of like priv but not free'd later.
1075 wth->wslua_data = open_routines[i].wslua_data;
1077 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
1079 case WTAP_OPEN_ERROR:
1080 /* Error - give up */
1084 case WTAP_OPEN_NOT_MINE:
1085 /* No error, but not that type of file */
1088 case WTAP_OPEN_MINE:
1089 /* We found the file type */
1097 /* Well, it's not one of the types of file we know about. */
1099 *err = WTAP_ERR_FILE_UNKNOWN_FORMAT;
1103 wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
1104 ws_buffer_init(wth->frame_buffer, 1500);
1106 if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
1107 (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
1109 wtapng_if_descr_t descr;
1111 descr.wtap_encap = wth->file_encap;
1112 if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
1113 descr.time_units_per_second = 1000000000; /* nanosecond resolution */
1114 descr.if_tsresol = 9;
1115 descr.tsprecision = WTAP_TSPREC_NSEC;
1117 descr.time_units_per_second = 1000000; /* default microsecond resolution */
1118 descr.if_tsresol = 6;
1119 descr.tsprecision = WTAP_TSPREC_USEC;
1121 descr.link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
1122 descr.snap_len = wth->snapshot_length;
1123 descr.opt_comment = NULL;
1124 descr.if_name = NULL;
1125 descr.if_description = NULL;
1127 descr.if_filter_str= NULL;
1128 descr.bpf_filter_len= 0;
1129 descr.if_filter_bpf_bytes= NULL;
1131 descr.if_fcslen = -1;
1132 descr.num_stat_entries = 0; /* Number of ISB:s */
1133 descr.interface_statistics = NULL;
1134 g_array_append_val(wth->interface_data, descr);
1141 * Given the pathname of the file we just closed with wtap_fdclose(), attempt
1142 * to reopen that file and assign the new file descriptor(s) to the sequential
1143 * stream and, if do_random is TRUE, to the random stream. Used on Windows
1144 * after the rename of a file we had open was done or if the rename of a
1145 * file on top of a file we had open failed.
1147 * This is only required by Wireshark, not TShark, and, at the point that
1148 * Wireshark is doing this, the sequential stream is closed, and the
1149 * random stream is open, so this refuses to open pipes, and only
1150 * reopens the random stream.
1153 wtap_fdreopen(wtap *wth, const char *filename, int *err)
1158 * We need two independent descriptors for random access, so
1159 * they have different file positions. If we're opening the
1160 * standard input, we can only dup it to get additional
1161 * descriptors, so we can't have two independent descriptors,
1162 * and thus can't do random access.
1164 if (strcmp(filename, "-") == 0) {
1165 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
1169 /* First, make sure the file is valid */
1170 if (ws_stat64(filename, &statb) < 0) {
1174 if (S_ISFIFO(statb.st_mode)) {
1176 * Opens of FIFOs are not allowed; see above.
1178 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
1180 } else if (S_ISDIR(statb.st_mode)) {
1182 * Return different errors for "this is a directory"
1183 * and "this is some random special file type", so
1184 * the user can get a potentially more helpful error.
1188 } else if (! S_ISREG(statb.st_mode)) {
1189 *err = WTAP_ERR_NOT_REGULAR_FILE;
1194 errno = WTAP_ERR_CANT_OPEN;
1195 if (!file_fdreopen(wth->random_fh, filename)) {
1202 /* Table of the file types and subtypes we know about.
1203 Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending
1206 These are used to report what type and subtype a given file is and
1207 to let the user select a format when writing out packets. */
1208 static const struct file_type_subtype_info dump_open_table_base[] = {
1209 /* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN (only used internally for initialization) */
1210 { NULL, NULL, NULL, NULL,
1214 /* WTAP_FILE_TYPE_SUBTYPE_PCAP */
1215 /* Gianluca Varenni suggests that we add "deprecated" to the description. */
1216 { "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp",
1218 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1220 /* WTAP_FILE_TYPE_SUBTYPE_PCAPNG */
1221 { "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
1222 FALSE, TRUE, WTAP_COMMENT_PER_SECTION|WTAP_COMMENT_PER_INTERFACE|WTAP_COMMENT_PER_PACKET,
1223 pcapng_dump_can_write_encap, pcapng_dump_open, NULL },
1225 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC */
1226 { "Wireshark - nanosecond libpcap", "nseclibpcap", "pcap", "cap;dmp",
1228 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1230 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX */
1231 { "AIX tcpdump - libpcap", "aixlibpcap", "pcap", "cap;dmp",
1235 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029 */
1236 { "Modified tcpdump - libpcap", "modlibpcap", "pcap", "cap;dmp",
1238 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1240 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA */
1241 { "Nokia tcpdump - libpcap ", "nokialibpcap", "pcap", "cap;dmp",
1243 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1245 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417 */
1246 { "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "pcap", "cap;dmp",
1248 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1250 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915 */
1251 { "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "pcap", "cap;dmp",
1253 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1255 /* WTAP_FILE_TYPE_SUBTYPE_5VIEWS */
1256 { "InfoVista 5View capture", "5views", "5vw", NULL,
1258 _5views_dump_can_write_encap, _5views_dump_open, NULL },
1260 /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_1_0 */
1261 { "AIX iptrace 1.0", "iptrace_1", NULL, NULL,
1265 /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_2_0 */
1266 { "AIX iptrace 2.0", "iptrace_2", NULL, NULL,
1270 /* WTAP_FILE_TYPE_SUBTYPE_BER */
1271 { "ASN.1 Basic Encoding Rules", "ber", NULL, NULL,
1275 /* WTAP_FILE_TYPE_SUBTYPE_HCIDUMP */
1276 { "Bluetooth HCI dump", "hcidump", NULL, NULL,
1280 /* WTAP_FILE_TYPE_SUBTYPE_CATAPULT_DCT2000 */
1281 { "Catapult DCT2000 trace (.out format)", "dct2000", "out", NULL,
1283 catapult_dct2000_dump_can_write_encap, catapult_dct2000_dump_open, NULL },
1285 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_OLD */
1286 { "Cinco Networks NetXRay 1.x", "netxray1", "cap", NULL,
1290 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_0 */
1291 { "Cinco Networks NetXRay 2.0 or later", "netxray2", "cap", NULL,
1295 /* WTAP_FILE_TYPE_SUBTYPE_COSINE */
1296 { "CoSine IPSX L2 capture", "cosine", "txt", NULL,
1300 /* WTAP_FILE_TYPE_SUBTYPE_CSIDS */
1301 { "CSIDS IPLog", "csids", NULL, NULL,
1305 /* WTAP_FILE_TYPE_SUBTYPE_DBS_ETHERWATCH */
1306 { "DBS Etherwatch (VMS)", "etherwatch", "txt", NULL,
1310 /* WTAP_FILE_TYPE_SUBTYPE_ERF */
1311 { "Endace ERF capture", "erf", "erf", NULL,
1313 erf_dump_can_write_encap, erf_dump_open, NULL },
1315 /* WTAP_FILE_TYPE_SUBTYPE_EYESDN */
1316 { "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "trc", NULL,
1318 eyesdn_dump_can_write_encap, eyesdn_dump_open, NULL },
1320 /* WTAP_FILE_TYPE_SUBTYPE_NETTL */
1321 { "HP-UX nettl trace", "nettl", "trc0", "trc1",
1323 nettl_dump_can_write_encap, nettl_dump_open, NULL },
1325 /* WTAP_FILE_TYPE_SUBTYPE_ISERIES */
1326 { "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "txt", NULL,
1330 /* WTAP_FILE_TYPE_SUBTYPE_ISERIES_UNICODE */
1331 { "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "txt", NULL,
1335 /* WTAP_FILE_TYPE_SUBTYPE_I4BTRACE */
1336 { "I4B ISDN trace", "i4btrace", NULL, NULL,
1340 /* WTAP_FILE_TYPE_SUBTYPE_ASCEND */
1341 { "Lucent/Ascend access server trace", "ascend", "txt", NULL,
1345 /* WTAP_FILE_TYPE_SUBTYPE_NETMON_1_x */
1346 { "Microsoft NetMon 1.x", "netmon1", "cap", NULL,
1348 netmon_dump_can_write_encap_1_x, netmon_dump_open, NULL },
1350 /* WTAP_FILE_TYPE_SUBTYPE_NETMON_2_x */
1351 { "Microsoft NetMon 2.x", "netmon2", "cap", NULL,
1353 netmon_dump_can_write_encap_2_x, netmon_dump_open, NULL },
1355 /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_UNCOMPRESSED */
1356 { "Sniffer (DOS)", "ngsniffer", "cap", "enc;trc;fdc;syc",
1358 ngsniffer_dump_can_write_encap, ngsniffer_dump_open, NULL },
1360 /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_COMPRESSED */
1361 { "Sniffer (DOS), compressed", "ngsniffer_comp", "cap", "enc;trc;fdc;syc",
1365 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_1 */
1366 { "NetXray, Sniffer (Windows) 1.1", "ngwsniffer_1_1", "cap", NULL,
1368 netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1, NULL },
1370 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x */
1371 { "Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "cap", "caz",
1373 netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0, NULL },
1375 /* WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS */
1376 { "Network Instruments Observer", "niobserver", "bfr", NULL,
1378 network_instruments_dump_can_write_encap, network_instruments_dump_open, NULL },
1380 /* WTAP_FILE_TYPE_SUBTYPE_LANALYZER */
1381 { "Novell LANalyzer","lanalyzer", "tr1", NULL,
1383 lanalyzer_dump_can_write_encap, lanalyzer_dump_open, NULL },
1385 /* WTAP_FILE_TYPE_SUBTYPE_PPPDUMP */
1386 { "pppd log (pppdump format)", "pppd", NULL, NULL,
1390 /* WTAP_FILE_TYPE_SUBTYPE_RADCOM */
1391 { "RADCOM WAN/LAN analyzer", "radcom", NULL, NULL,
1395 /* WTAP_FILE_TYPE_SUBTYPE_SNOOP */
1396 { "Sun snoop", "snoop", "snoop", "cap",
1398 snoop_dump_can_write_encap, snoop_dump_open, NULL },
1400 /* WTAP_FILE_TYPE_SUBTYPE_SHOMITI */
1401 { "Shomiti/Finisar Surveyor", "shomiti", "cap", NULL,
1405 /* WTAP_FILE_TYPE_SUBTYPE_VMS */
1406 { "TCPIPtrace (VMS)", "tcpiptrace", "txt", NULL,
1410 /* WTAP_FILE_TYPE_SUBTYPE_K12 */
1411 { "Tektronix K12xx 32-bit .rf5 format", "rf5", "rf5", NULL,
1413 k12_dump_can_write_encap, k12_dump_open, NULL },
1415 /* WTAP_FILE_TYPE_SUBTYPE_TOSHIBA */
1416 { "Toshiba Compact ISDN Router snoop", "toshiba", "txt", NULL,
1420 /* WTAP_FILE_TYPE_SUBTYPE_VISUAL_NETWORKS */
1421 { "Visual Networks traffic capture", "visual", NULL, NULL,
1423 visual_dump_can_write_encap, visual_dump_open, NULL },
1425 /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V56 */
1426 { "Savvius classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
1430 /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V7 */
1431 { "Savvius classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
1435 /* WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED */
1436 { "Savvius tagged", "peektagged", "pkt", "tpc;apc;wpz",
1440 /* WTAP_FILE_TYPE_SUBTYPE_MPEG */
1441 { "MPEG", "mpeg", "mpeg", "mpg;mp3",
1445 /* WTAP_FILE_TYPE_SUBTYPE_K12TEXT */
1446 { "K12 text file", "k12text", "txt", NULL,
1448 k12text_dump_can_write_encap, k12text_dump_open, NULL },
1450 /* WTAP_FILE_TYPE_SUBTYPE_NETSCREEN */
1451 { "NetScreen snoop text file", "netscreen", "txt", NULL,
1455 /* WTAP_FILE_TYPE_SUBTYPE_COMMVIEW */
1456 { "TamoSoft CommView", "commview", "ncf", NULL,
1458 commview_dump_can_write_encap, commview_dump_open, NULL },
1460 /* WTAP_FILE_TYPE_SUBTYPE_BTSNOOP */
1461 { "Symbian OS btsnoop", "btsnoop", "log", NULL,
1463 btsnoop_dump_can_write_encap, btsnoop_dump_open_h4, NULL },
1465 /* WTAP_FILE_TYPE_SUBTYPE_TNEF */
1466 { "Transport-Neutral Encapsulation Format", "tnef", NULL, NULL,
1470 /* WTAP_FILE_TYPE_SUBTYPE_DCT3TRACE */
1471 { "Gammu DCT3 trace", "dct3trace", "xml", NULL,
1475 /* WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER */
1476 { "OS X PacketLogger", "pklg", "pklg", NULL,
1480 /* WTAP_FILE_TYPE_SUBTYPE_DAINTREE_SNA */
1481 { "Daintree SNA", "dsna", "dcf", NULL,
1485 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0 */
1486 { "NetScaler Trace (Version 1.0)", "nstrace10", NULL, NULL,
1488 nstrace_10_dump_can_write_encap, nstrace_dump_open, NULL },
1490 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0 */
1491 { "NetScaler Trace (Version 2.0)", "nstrace20", "cap", NULL,
1493 nstrace_20_dump_can_write_encap, nstrace_dump_open, NULL },
1495 /* WTAP_FILE_TYPE_SUBTYPE_JPEG_JFIF */
1496 { "JPEG/JFIF", "jpeg", "jpg", "jpeg;jfif",
1500 /* WTAP_FILE_TYPE_SUBTYPE_IPFIX */
1501 { "IPFIX File Format", "ipfix", "pfx", "ipfix",
1505 /* WTAP_ENCAP_MIME */
1506 { "MIME File Format", "mime", NULL, NULL,
1510 /* WTAP_FILE_TYPE_SUBTYPE_AETHRA */
1511 { "Aethra .aps file", "aethra", "aps", NULL,
1515 /* WTAP_FILE_TYPE_SUBTYPE_MPEG_2_TS */
1516 { "MPEG2 transport stream", "mp2t", "mp2t", "ts;mpg",
1520 /* WTAP_FILE_TYPE_SUBTYPE_VWR_80211 */
1521 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr80211", "vwr", NULL,
1525 /* WTAP_FILE_TYPE_SUBTYPE_VWR_ETH */
1526 { "Ixia IxVeriWave .vwr Raw Ethernet Capture", "vwreth", "vwr", NULL,
1530 /* WTAP_FILE_TYPE_SUBTYPE_CAMINS */
1531 { "CAM Inspector file", "camins", "camins", NULL,
1535 /* WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 */
1536 { "STANAG 4607 Format", "stanag4607", NULL, NULL,
1540 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 */
1541 { "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
1543 nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
1545 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT */
1546 { "Android Logcat Binary format", "logcat", "logcat", NULL,
1548 logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
1550 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF */
1551 { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
1553 logcat_text_brief_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
1555 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS */
1556 { "Android Logcat Process text format", "logcat-process", NULL, NULL,
1558 logcat_text_process_dump_can_write_encap, logcat_text_process_dump_open, NULL },
1560 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG */
1561 { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
1563 logcat_text_tag_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
1565 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD */
1566 { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
1568 logcat_text_thread_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
1570 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME */
1571 { "Android Logcat Time text format", "logcat-time", NULL, NULL,
1573 logcat_text_time_dump_can_write_encap, logcat_text_time_dump_open, NULL },
1575 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME */
1576 { "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
1578 logcat_text_threadtime_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
1580 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG */
1581 { "Android Logcat Long text format", "logcat-long", NULL, NULL,
1583 logcat_text_long_dump_can_write_encap, logcat_text_long_dump_open, NULL },
1585 /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA */
1586 { "Colasoft Capsa format", "capsa", "cscpkt", NULL,
1590 /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER */
1591 { "Colasoft Packet Builder format", "colasoft-pb", "cscpkt", NULL,
1595 /* WTAP_FILE_TYPE_SUBTYPE_JSON */
1596 { "JavaScript Object Notation", "json", "json", "NULL",
1600 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 */
1601 { "NetScaler Trace (Version 3.5)", "nstrace35", "cap", NULL,
1603 nstrace_35_dump_can_write_encap, nstrace_dump_open, NULL },
1605 /* WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423 */
1606 { "3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
1611 gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
1613 static GArray* dump_open_table_arr = NULL;
1614 static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
1616 /* initialize the file types array if it has not being initialized yet */
1618 init_file_types_subtypes(void)
1621 if (dump_open_table_arr) return;
1623 dump_open_table_arr = g_array_new(FALSE,TRUE,sizeof(struct file_type_subtype_info));
1625 g_array_append_vals(dump_open_table_arr,dump_open_table_base,wtap_num_file_types_subtypes);
1627 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1630 /* if subtype is WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, then create a new subtype as well as register it, else replace the
1631 existing entry in that spot */
1633 wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype)
1635 struct file_type_subtype_info* finfo;
1636 init_file_types_subtypes();
1638 if (!fi || !fi->name || !fi->short_name || subtype > wtap_num_file_types_subtypes) {
1639 g_error("no file type info or invalid file type to register");
1643 /* do we want a new registration? */
1644 if (subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
1645 /* register a new one; first verify there isn't one named this already */
1646 if (wtap_short_string_to_file_type_subtype(fi->short_name) > -1 ) {
1647 g_error("file type short name already exists");
1651 g_array_append_val(dump_open_table_arr,*fi);
1653 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1655 return wtap_num_file_types_subtypes++;
1658 /* re-register an existing one - verify the short names do match (sanity check really) */
1659 if (!dump_open_table[subtype].short_name || strcmp(dump_open_table[subtype].short_name,fi->short_name) != 0) {
1660 g_error("invalid file type name given to register");
1664 /* yes, we're going to cast to change its const-ness */
1665 finfo = (struct file_type_subtype_info*)(&dump_open_table[subtype]);
1666 /*finfo->name = fi->name;*/
1667 /*finfo->short_name = fi->short_name;*/
1668 finfo->default_file_extension = fi->default_file_extension;
1669 finfo->additional_file_extensions = fi->additional_file_extensions;
1670 finfo->writing_must_seek = fi->writing_must_seek;
1671 finfo->has_name_resolution = fi->has_name_resolution;
1672 finfo->supported_comment_types = fi->supported_comment_types;
1673 finfo->can_write_encap = fi->can_write_encap;
1674 finfo->dump_open = fi->dump_open;
1675 finfo->wslua_info = fi->wslua_info;
1680 /* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
1683 wtap_deregister_file_type_subtype(const int subtype)
1685 struct file_type_subtype_info* finfo;
1687 if (subtype < 0 || subtype >= wtap_num_file_types_subtypes) {
1688 g_error("invalid file type to de-register");
1692 /* yes, we're going to cast to change its const-ness */
1693 finfo = (struct file_type_subtype_info*)(&dump_open_table[subtype]);
1694 /* unfortunately, it's not safe to null-out the name or short_name; bunch of other code doesn't guard aainst that, afaict */
1695 /*finfo->name = NULL;*/
1696 /*finfo->short_name = NULL;*/
1697 finfo->default_file_extension = NULL;
1698 finfo->additional_file_extensions = NULL;
1699 finfo->writing_must_seek = FALSE;
1700 finfo->has_name_resolution = FALSE;
1701 finfo->supported_comment_types = 0;
1702 finfo->can_write_encap = NULL;
1703 finfo->dump_open = NULL;
1704 finfo->wslua_info = NULL;
1708 wtap_get_num_file_types_subtypes(void)
1710 return wtap_num_file_types_subtypes;
1714 * Given a GArray of WTAP_ENCAP_ types, return the per-file encapsulation
1715 * type that would be needed to write out a file with those types. If
1716 * there's only one type, it's that type, otherwise it's
1717 * WTAP_ENCAP_PER_PACKET.
1720 wtap_dump_file_encap_type(const GArray *file_encaps)
1724 encap = WTAP_ENCAP_PER_PACKET;
1725 if (file_encaps->len == 1) {
1726 /* OK, use the one-and-only encapsulation type. */
1727 encap = g_array_index(file_encaps, gint, 0);
1733 wtap_dump_can_write_encap(int filetype, int encap)
1737 if (filetype < 0 || filetype >= wtap_num_file_types_subtypes
1738 || dump_open_table[filetype].can_write_encap == NULL)
1741 result = (*dump_open_table[filetype].can_write_encap)(encap);
1744 /* if the err said to check wslua's can_write_encap, try that */
1745 if (result == WTAP_ERR_CHECK_WSLUA
1746 && dump_open_table[filetype].wslua_info != NULL
1747 && dump_open_table[filetype].wslua_info->wslua_can_write_encap != NULL) {
1749 result = (*dump_open_table[filetype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[filetype].wslua_info->wslua_data);
1761 * Return TRUE if a capture with a given GArray of encapsulation types
1762 * and a given bitset of comment types can be written in a specified
1763 * format, and FALSE if it can't.
1766 wtap_dump_can_write_format(int ft, const GArray *file_encaps,
1767 guint32 required_comment_types)
1772 * Can we write in this format?
1774 if (!wtap_dump_can_open(ft)) {
1780 * Yes. Can we write out all the required comments in this
1783 if (!wtap_dump_supports_comment_types(ft, required_comment_types)) {
1789 * Yes. Is the required per-file encapsulation type supported?
1790 * This might be WTAP_ENCAP_PER_PACKET.
1792 if (!wtap_dump_can_write_encap(ft, wtap_dump_file_encap_type(file_encaps))) {
1798 * Yes. Are all the individual encapsulation types supported?
1800 for (i = 0; i < file_encaps->len; i++) {
1801 if (!wtap_dump_can_write_encap(ft,
1802 g_array_index(file_encaps, int, i))) {
1803 /* No - one of them isn't. */
1808 /* Yes - we're OK. */
1813 * Return TRUE if we can write a file with the given GArray of
1814 * encapsulation types and the given bitmask of comment types.
1817 wtap_dump_can_write(const GArray *file_encaps, guint32 required_comment_types)
1821 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1822 /* To save a file with Wiretap, Wiretap has to handle that format,
1823 * and its code to handle that format must be able to write a file
1824 * with this file's encapsulation types.
1826 if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
1827 /* OK, we can write it out in this type. */
1832 /* No, we couldn't save it in any format. */
1837 * Get a GArray of WTAP_FILE_TYPE_SUBTYPE_ values for file types/subtypes
1838 * that can be used to save a file of a given type/subtype with a given
1839 * GArray of encapsulation types and the given bitmask of comment types.
1842 wtap_get_savable_file_types_subtypes(int file_type_subtype,
1843 const GArray *file_encaps, guint32 required_comment_types)
1845 GArray *savable_file_types_subtypes;
1847 int default_file_type_subtype = -1;
1848 int other_file_type_subtype = -1;
1850 /* Can we save this file in its own file type/subtype? */
1851 if (wtap_dump_can_write_format(file_type_subtype, file_encaps,
1852 required_comment_types)) {
1853 /* Yes - make that the default file type/subtype. */
1854 default_file_type_subtype = file_type_subtype;
1856 /* OK, find the first file type/subtype we *can* save it as. */
1857 default_file_type_subtype = -1;
1858 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1859 if (wtap_dump_can_write_format(ft, file_encaps,
1860 required_comment_types)) {
1862 default_file_type_subtype = ft;
1867 if (default_file_type_subtype == -1) {
1868 /* We don't support writing this file as any file type/subtype. */
1872 /* Allocate the array. */
1873 savable_file_types_subtypes = g_array_new(FALSE, FALSE, (guint)sizeof (int));
1875 /* Put the default file type/subtype first in the list. */
1876 g_array_append_val(savable_file_types_subtypes, default_file_type_subtype);
1878 /* If the default is pcap, put pcap-NG right after it if we can
1879 also write it in pcap-NG format; otherwise, if the default is
1880 pcap-NG, put pcap right after it if we can also write it in
1882 if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
1883 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, file_encaps,
1884 required_comment_types))
1885 other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
1886 } else if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
1887 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAP, file_encaps,
1888 required_comment_types))
1889 other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
1891 if (other_file_type_subtype != -1)
1892 g_array_append_val(savable_file_types_subtypes, other_file_type_subtype);
1894 /* Add all the other file types/subtypes that work. */
1895 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1896 if (ft == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1897 continue; /* not a real file type */
1898 if (ft == default_file_type_subtype || ft == other_file_type_subtype)
1899 continue; /* we've already done this one */
1900 if (wtap_dump_can_write_format(ft, file_encaps,
1901 required_comment_types)) {
1902 /* OK, we can write it out in this type. */
1903 g_array_append_val(savable_file_types_subtypes, ft);
1907 return savable_file_types_subtypes;
1910 /* Name that should be somewhat descriptive. */
1912 wtap_file_type_subtype_string(int file_type_subtype)
1914 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes) {
1915 g_error("Unknown capture file type %d", file_type_subtype);
1916 /** g_error() does an abort() and thus never returns **/
1919 return dump_open_table[file_type_subtype].name;
1922 /* Name to use in, say, a command-line flag specifying the type/subtype. */
1924 wtap_file_type_subtype_short_string(int file_type_subtype)
1926 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
1929 return dump_open_table[file_type_subtype].short_name;
1932 /* Translate a short name to a capture file type/subtype. */
1934 wtap_short_string_to_file_type_subtype(const char *short_name)
1936 int file_type_subtype;
1938 for (file_type_subtype = 0; file_type_subtype < wtap_num_file_types_subtypes; file_type_subtype++) {
1939 if (dump_open_table[file_type_subtype].short_name != NULL &&
1940 strcmp(short_name, dump_open_table[file_type_subtype].short_name) == 0)
1941 return file_type_subtype;
1945 * We now call the "libpcap" file format just "pcap", but we
1946 * allow it to be specified as "libpcap" as well, for
1947 * backwards compatibility.
1949 if (strcmp(short_name, "libpcap") == 0)
1950 return WTAP_FILE_TYPE_SUBTYPE_PCAP;
1952 return -1; /* no such file type, or we can't write it */
1956 add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
1957 GSList *compressed_file_extensions)
1959 gchar **extensions_set, **extensionp;
1963 * Add the default extension, and all compressed variants of
1966 extensions = add_extensions(extensions,
1967 dump_open_table[file_type_subtype].default_file_extension,
1968 compressed_file_extensions);
1970 if (dump_open_table[file_type_subtype].additional_file_extensions != NULL) {
1972 * We have additional extensions; add them.
1974 * First, split the extension-list string into a set of
1977 extensions_set = g_strsplit(dump_open_table[file_type_subtype].additional_file_extensions,
1981 * Add each of those extensions to the list.
1983 for (extensionp = extensions_set; *extensionp != NULL;
1985 extension = *extensionp;
1988 * Add the extension, and all compressed variants
1991 extensions = add_extensions(extensions, extension,
1992 compressed_file_extensions);
1995 g_strfreev(extensions_set);
2000 /* Return a list of file extensions that are used by the specified file type.
2002 If include_compressed is TRUE, the list will include compressed
2003 extensions, e.g. not just "pcap" but also "pcap.gz" if we can read
2006 All strings in the list are allocated with g_malloc() and must be freed
2009 wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
2011 GSList *compressed_file_extensions;
2014 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2015 return NULL; /* not a valid file type */
2017 if (dump_open_table[file_type_subtype].default_file_extension == NULL)
2018 return NULL; /* valid, but no extensions known */
2020 extensions = NULL; /* empty list, to start with */
2023 * If include_compressions is true, get the list of compressed-file
2026 if (include_compressed)
2027 compressed_file_extensions = wtap_get_compressed_file_extensions();
2029 compressed_file_extensions = NULL;
2032 * Add all this file type's extensions, with compressed
2035 extensions = add_extensions_for_file_type_subtype(file_type_subtype, extensions,
2036 compressed_file_extensions);
2038 g_slist_free(compressed_file_extensions);
2043 * Free a list returned by wtap_get_file_extension_type_extensions(),
2044 * wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
2047 wtap_free_extensions_list(GSList *extensions)
2051 for (extension = extensions; extension != NULL;
2052 extension = g_slist_next(extension)) {
2053 g_free(extension->data);
2055 g_slist_free(extensions);
2058 /* Return the default file extension to use with the specified file type;
2059 that's just the extension, without any ".". */
2061 wtap_default_file_extension(int file_type_subtype)
2063 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2066 return dump_open_table[file_type_subtype].default_file_extension;
2070 wtap_dump_can_open(int file_type_subtype)
2072 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2073 || dump_open_table[file_type_subtype].dump_open == NULL)
2081 wtap_dump_can_compress(int file_type_subtype)
2084 * If this is an unknown file type, or if we have to
2085 * seek when writing out a file with this file type,
2088 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2089 || dump_open_table[file_type_subtype].writing_must_seek)
2096 wtap_dump_can_compress(int file_type_subtype _U_)
2103 wtap_dump_has_name_resolution(int file_type_subtype)
2105 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2106 || dump_open_table[file_type_subtype].has_name_resolution == FALSE)
2113 wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
2115 guint32 supported_comment_types;
2117 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2120 supported_comment_types = dump_open_table[file_type_subtype].supported_comment_types;
2122 if ((comment_types & supported_comment_types) == comment_types)
2127 static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean comressed, int *err);
2128 static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen,
2129 gboolean compressed, int *err);
2130 static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err);
2132 static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename);
2133 static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
2134 static int wtap_dump_file_close(wtap_dumper *wdh);
2137 wtap_dump_open(const char *filename, int file_type_subtype, int encap,
2138 int snaplen, gboolean compressed, int *err)
2140 return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2143 static wtap_dumper *
2144 wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
2145 wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2146 wtapng_name_res_t *nrb_hdr, int *err)
2149 wtapng_if_descr_t descr, *file_int_data;
2151 /* Allocate a data structure for the output stream. */
2152 wdh = wtap_dump_alloc_wdh(file_type_subtype, encap, snaplen, compressed, err);
2154 return NULL; /* couldn't allocate it */
2156 /* Set Section Header Block data */
2157 wdh->shb_hdr = shb_hdr;
2158 /* Set Name Resolution Block data */
2159 wdh->nrb_hdr = nrb_hdr;
2160 /* Set Interface Description Block data */
2161 if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
2164 /* XXX: what free's this stuff? */
2165 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
2166 for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
2167 file_int_data = &g_array_index(idb_inf->interface_data, wtapng_if_descr_t, itf_count);
2168 if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data->wtap_encap)) {
2169 /* XXX: this does a shallow copy, not a true clone; e.g., comments are not duped */
2170 memcpy(&descr, file_int_data, sizeof(wtapng_if_descr_t));
2171 descr.wtap_encap = encap;
2172 descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
2173 g_array_append_val(wdh->interface_data, descr);
2175 g_array_append_val(wdh->interface_data, *file_int_data);
2179 descr.wtap_encap = encap;
2180 descr.time_units_per_second = 1000000; /* default microsecond resolution */
2181 descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
2182 descr.snap_len = snaplen;
2183 descr.opt_comment = NULL;
2184 descr.if_name = g_strdup("Unknown/not available in original file format(libpcap)");
2185 descr.if_description = NULL;
2187 descr.if_tsresol = 6;
2188 descr.if_filter_str= NULL;
2189 descr.bpf_filter_len= 0;
2190 descr.if_filter_bpf_bytes= NULL;
2192 descr.if_fcslen = -1;
2193 descr.num_stat_entries = 0; /* Number of ISB:s */
2194 descr.interface_statistics = NULL;
2195 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
2196 g_array_append_val(wdh->interface_data, descr);
2202 wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
2203 int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2204 wtapng_name_res_t *nrb_hdr, int *err)
2209 /* Check whether we can open a capture file with that file type
2210 and that encapsulation. */
2211 if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
2214 /* Allocate and initialize a data structure for the output stream. */
2215 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2216 shb_hdr, idb_inf, nrb_hdr, err);
2220 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2221 to a generic "the open failed" error. */
2222 errno = WTAP_ERR_CANT_OPEN;
2223 fh = wtap_dump_file_open(wdh, filename);
2227 return NULL; /* can't create file */
2231 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2232 /* Get rid of the file we created; we couldn't finish
2234 if (wdh->fh != stdout) {
2235 wtap_dump_file_close(wdh);
2236 ws_unlink(filename);
2245 wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
2246 gboolean compressed, int *err)
2248 return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2252 wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
2253 gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2254 wtapng_name_res_t *nrb_hdr, int *err)
2259 /* Check whether we can open a capture file with that file type
2260 and that encapsulation. */
2261 if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
2264 /* Allocate and initialize a data structure for the output stream. */
2265 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2266 shb_hdr, idb_inf, nrb_hdr, err);
2272 if (_setmode(fileno(stdout), O_BINARY) == -1) {
2273 /* "Should not happen" */
2276 return NULL; /* couldn't put standard output in binary mode */
2281 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2282 to a generic "the open failed" error. */
2283 errno = WTAP_ERR_CANT_OPEN;
2284 fh = wtap_dump_file_fdopen(wdh, fd);
2288 return NULL; /* can't create standard I/O stream */
2292 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2293 wtap_dump_file_close(wdh);
2301 wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
2303 if (!wtap_dump_can_open(file_type_subtype)) {
2304 /* Invalid type, or type we don't know how to write. */
2305 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2309 /* OK, we know how to write that type; can we write the specified
2310 encapsulation type? */
2311 *err = (*dump_open_table[file_type_subtype].can_write_encap)(encap);
2312 /* if the err said to check wslua's can_write_encap, try that */
2313 if (*err == WTAP_ERR_CHECK_WSLUA
2314 && dump_open_table[file_type_subtype].wslua_info != NULL
2315 && dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap != NULL) {
2317 *err = (*dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[file_type_subtype].wslua_info->wslua_data);
2324 /* if compression is wanted, do we support this for this file_type_subtype? */
2325 if(compressed && !wtap_dump_can_compress(file_type_subtype)) {
2326 *err = WTAP_ERR_COMPRESSION_NOT_SUPPORTED;
2330 /* All systems go! */
2334 static wtap_dumper *
2335 wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean compressed, int *err)
2339 wdh = (wtap_dumper *)g_malloc0(sizeof (wtap_dumper));
2345 wdh->file_type_subtype = file_type_subtype;
2346 wdh->snaplen = snaplen;
2348 wdh->compressed = compressed;
2349 wdh->wslua_data = NULL;
2354 wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
2359 /* Can we do a seek on the file descriptor?
2360 If not, note that fact. */
2364 fd = fileno((FILE *)wdh->fh);
2365 if (ws_lseek64(fd, 1, SEEK_CUR) == (off_t) -1)
2368 /* Undo the seek. */
2369 ws_lseek64(fd, 0, SEEK_SET);
2374 /* If this file type requires seeking, and we can't seek, fail. */
2375 if (dump_open_table[file_type_subtype].writing_must_seek && cant_seek) {
2376 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
2380 /* Set wdh with wslua data if any - this is how we pass the data
2381 * to the file writer.
2383 if (dump_open_table[file_type_subtype].wslua_info)
2384 wdh->wslua_data = dump_open_table[file_type_subtype].wslua_info->wslua_data;
2386 /* Now try to open the file for writing. */
2387 if (!(*dump_open_table[file_type_subtype].dump_open)(wdh, err)) {
2391 return TRUE; /* success! */
2395 wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2396 const guint8 *pd, int *err, gchar **err_info)
2400 return (wdh->subtype_write)(wdh, phdr, pd, err, err_info);
2404 wtap_dump_flush(wtap_dumper *wdh)
2407 if(wdh->compressed) {
2408 gzwfile_flush((GZWFILE_T)wdh->fh);
2412 fflush((FILE *)wdh->fh);
2417 wtap_dump_close(wtap_dumper *wdh, int *err)
2419 gboolean ret = TRUE;
2421 if (wdh->subtype_finish != NULL) {
2422 /* There's a finish routine for this dump stream. */
2423 if (!(wdh->subtype_finish)(wdh, err))
2426 errno = WTAP_ERR_CANT_CLOSE;
2427 /* Don't close stdout */
2428 if (wdh->fh != stdout) {
2429 if (wtap_dump_file_close(wdh) == EOF) {
2431 /* The per-format close function succeeded,
2432 but the fclose didn't. Save the reason
2433 why, if our caller asked for it. */
2440 /* as we don't close stdout, at least try to flush it */
2441 wtap_dump_flush(wdh);
2443 if (wdh->priv != NULL)
2450 wtap_get_bytes_dumped(wtap_dumper *wdh)
2452 return wdh->bytes_dumped;
2456 wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
2458 wdh->bytes_dumped = bytes_dumped;
2462 wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
2464 if (!wdh || wdh->file_type_subtype < 0 || wdh->file_type_subtype >= wtap_num_file_types_subtypes
2465 || dump_open_table[wdh->file_type_subtype].has_name_resolution == FALSE)
2467 wdh->addrinfo_lists = addrinfo_lists;
2471 /* internally open a file for writing (compressed or not) */
2474 wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
2476 if(wdh->compressed) {
2477 return gzwfile_open(filename);
2479 return ws_fopen(filename, "wb");
2484 wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
2486 return ws_fopen(filename, "wb");
2490 /* internally open a file for writing (compressed or not) */
2493 wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
2495 if(wdh->compressed) {
2496 return gzwfile_fdopen(fd);
2498 return ws_fdopen(fd, "wb");
2503 wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
2505 return ws_fdopen(fd, "wb");
2509 /* internally writing raw bytes (compressed or not) */
2511 wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize, int *err)
2516 if (wdh->compressed) {
2517 nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned int) bufsize);
2519 * gzwfile_write() returns 0 on error.
2521 if (nwritten == 0) {
2522 *err = gzwfile_geterr((GZWFILE_T)wdh->fh);
2528 errno = WTAP_ERR_CANT_WRITE;
2529 nwritten = fwrite(buf, 1, bufsize, (FILE *)wdh->fh);
2531 * At least according to the Mac OS X man page,
2532 * this can return a short count on an error.
2534 if (nwritten != bufsize) {
2535 if (ferror((FILE *)wdh->fh))
2538 *err = WTAP_ERR_SHORT_WRITE;
2545 /* internally close a file for writing (compressed or not) */
2547 wtap_dump_file_close(wtap_dumper *wdh)
2550 if(wdh->compressed) {
2551 return gzwfile_close((GZWFILE_T)wdh->fh);
2555 return fclose((FILE *)wdh->fh);
2560 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
2563 if(wdh->compressed) {
2564 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2569 if (-1 == fseek((FILE *)wdh->fh, (long)offset, whence)) {
2580 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
2584 if(wdh->compressed) {
2585 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2590 if (-1 == (rval = ftell((FILE *)wdh->fh))) {
2601 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2606 * indent-tabs-mode: t
2609 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2610 * :indentSize=8:tabSize=8:noTabs=false: