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>
29 #include <wsutil/tempfile.h>
32 #include "file_wrappers.h"
33 #include <wsutil/buffer.h>
34 #include "lanalyzer.h"
35 #include "ngsniffer.h"
37 #include "ascendtext.h"
50 #include "peekclassic.h"
51 #include "peektagged.h"
53 #include "dbs-etherwatch.h"
60 #include "logcat_text.h"
62 #include "network_instruments.h"
65 #include "catapult_dct2000.h"
68 #include "netscreen.h"
74 #include "dct3trace.h"
75 #include "packetlogger.h"
76 #include "daintree-sna.h"
77 #include "netscaler.h"
78 #include "mime_file.h"
82 #include "stanag4607.h"
84 #include "pcap-encap.h"
85 #include "nettrace_3gpp_32_423.h"
89 * Add an extension, and all compressed versions thereof, to a GSList
93 add_extensions(GSList *extensions, const gchar *extension,
94 const char **compressed_file_extensions)
96 const char **compressed_file_extensionp;
99 * Add the specified extension.
101 extensions = g_slist_append(extensions, g_strdup(extension));
104 * Now add the extensions for compressed-file versions of
107 for (compressed_file_extensionp = compressed_file_extensions;
108 *compressed_file_extensionp != NULL;
109 compressed_file_extensionp++) {
110 extensions = g_slist_append(extensions,
111 g_strdup_printf("%s.%s", extension,
112 *compressed_file_extensionp));
119 * File types that can be identified by file extensions.
121 * These are used in file open dialogs to offer choices of extensions
122 * for which to filter. Note that the first field can list more than
123 * one type of file, because, for example, ".cap" is a popular
124 * extension used by a number of capture file types.
126 static const struct file_extension_info file_type_extensions_base[] = {
127 { "Wireshark/tcpdump/... - pcap", "pcap;cap;dmp" },
128 { "Wireshark/... - pcapng", "pcapng;ntar" },
129 { "Network Monitor, Surveyor, NetScaler", "cap" },
130 { "InfoVista 5View capture", "5vw" },
131 { "Sniffer (DOS)", "cap;enc;trc;fdc;syc" },
132 { "Cinco NetXRay, Sniffer (Windows)", "cap;caz" },
133 { "Endace ERF capture", "erf" },
134 { "EyeSDN USB S0/E1 ISDN trace format", "trc" },
135 { "HP-UX nettl trace", "trc0;trc1" },
136 { "Network Instruments Observer", "bfr" },
137 { "Colasoft Capsa", "cscpkt" },
138 { "Novell LANalyzer", "tr1" },
139 { "Tektronix K12xx 32-bit .rf5 format", "rf5" },
140 { "Savvius *Peek", "pkt;tpc;apc;wpz" },
141 { "Catapult DCT2000 trace (.out format)", "out" },
142 { "Micropross mplog", "mplog" },
143 { "MPEG files", "mpg;mp3" },
144 { "TamoSoft CommView", "ncf" },
145 { "Symbian OS btsnoop", "log" },
146 { "Transport-Neutral Encapsulation Format", "tnef" },
147 { "XML files (including Gammu DCT3 traces)", "xml" },
148 { "OS X PacketLogger", "pklg" },
149 { "Daintree SNA", "dcf" },
150 { "JPEG/JFIF files", "jpg;jpeg;jfif" },
151 { "IPFIX File Format", "pfx;ipfix" },
152 { "Aethra .aps file", "aps" },
153 { "MPEG2 transport stream", "mp2t;ts;mpg" },
154 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr" },
155 { "CAM Inspector file", "camins" },
156 { "JavaScript Object Notation file", "json" }
159 #define N_FILE_TYPE_EXTENSIONS (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
161 static const struct file_extension_info* file_type_extensions = NULL;
163 static GArray* file_type_extensions_arr = NULL;
165 /* initialize the extensions array if it has not been initialized yet */
167 init_file_type_extensions(void)
170 if (file_type_extensions_arr) return;
172 file_type_extensions_arr = g_array_new(FALSE,TRUE,sizeof(struct file_extension_info));
174 g_array_append_vals(file_type_extensions_arr,file_type_extensions_base,N_FILE_TYPE_EXTENSIONS);
176 file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
180 wtap_register_file_type_extension(const struct file_extension_info *ei)
182 init_file_type_extensions();
184 g_array_append_val(file_type_extensions_arr,*ei);
186 file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
190 wtap_get_num_file_type_extensions(void)
192 return file_type_extensions_arr->len;
196 wtap_get_file_extension_type_name(int extension_type)
198 return file_type_extensions[extension_type].name;
202 add_extensions_for_file_extensions_type(int extension_type,
203 GSList *extensions, const char **compressed_file_extensions)
205 gchar **extensions_set, **extensionp, *extension;
208 * Split the extension-list string into a set of extensions.
210 extensions_set = g_strsplit(file_type_extensions[extension_type].extensions,
214 * Add each of those extensions to the list.
216 for (extensionp = extensions_set; *extensionp != NULL; extensionp++) {
217 extension = *extensionp;
220 * Add the extension, and all compressed variants
223 extensions = add_extensions(extensions, extension,
224 compressed_file_extensions);
227 g_strfreev(extensions_set);
231 /* Return a list of file extensions that are used by the specified file
234 All strings in the list are allocated with g_malloc() and must be freed
237 wtap_get_file_extension_type_extensions(guint extension_type)
241 if (extension_type >= file_type_extensions_arr->len)
242 return NULL; /* not a valid extension type */
244 extensions = NULL; /* empty list, to start with */
247 * Add all this file extension type's extensions, with compressed
250 extensions = add_extensions_for_file_extensions_type(extension_type,
251 extensions, compressed_file_extension_table);
256 /* Return a list of all extensions that are used by all file types,
257 including compressed extensions, e.g. not just "pcap" but also
258 "pcap.gz" if we can read gzipped files.
260 All strings in the list are allocated with g_malloc() and must be freed
263 wtap_get_all_file_extensions_list(void)
268 init_file_type_extensions();
270 extensions = NULL; /* empty list, to start with */
272 for (i = 0; i < file_type_extensions_arr->len; i++) {
274 * Add all this file extension type's extensions, with
275 * compressed variants.
277 extensions = add_extensions_for_file_extensions_type(i,
278 extensions, compressed_file_extension_table);
285 * The open_file_* routines should return:
287 * -1 on an I/O error;
289 * 1 if the file they're reading is one of the types it handles;
291 * 0 if the file they're reading isn't the type they're checking for.
293 * If the routine handles this type of file, it should set the "file_type"
294 * field in the "struct wtap" to the type of the file.
296 * Note that the routine does not have to free the private data pointer on
297 * error. The caller takes care of that by calling wtap_close on error.
298 * (See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8518)
300 * However, the caller does have to free the private data pointer when
301 * returning 0, since the next file type will be called and will likely
302 * just overwrite the pointer.
304 * The names are used in file open dialogs to select, for files that
305 * don't have magic numbers and that could potentially be files of
306 * more than one type based on the heuristics, a particular file
307 * type to interpret it as, if the file name has no extension, the
308 * extension isn't sufficient to determine the appropriate file type,
309 * or the extension is wrong.
311 * NOTE: when adding file formats to this list you may also want to add them
312 * to the following files so that the various desktop environments will
313 * know that Wireshark can open the file:
314 * 1) wireshark-mime-package.xml (for freedesktop.org environments)
315 * 2) packaging/macosx/Info.plist.in (for OS X)
316 * 3) packaging/nsis/AdditionalTasksPage.ini, packaging/nsis/common.nsh,
317 * and packaging/wix/ComponentGroups.wxi (for Windows)
319 * If your file format has an expected extension (e.g., ".pcap") then you
320 * should probably also add it to file_type_extensions_base[] (in this file).
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 /* Gammu DCT3 trace must come before MIME files as it's XML based*/
347 { "Gammu DCT3 trace", OPEN_INFO_MAGIC, dct3trace_open, NULL, NULL, NULL },
348 { "MIME Files Format", OPEN_INFO_MAGIC, mime_file_open, NULL, NULL, NULL },
349 { "Micropross mplog", OPEN_INFO_MAGIC, mplog_open, "mplog", NULL, NULL },
350 { "Novell LANalyzer", OPEN_INFO_HEURISTIC, lanalyzer_open, "tr1", NULL, NULL },
352 * PacketLogger must come before MPEG, because its files
353 * are sometimes grabbed by mpeg_open.
355 { "OS X PacketLogger", OPEN_INFO_HEURISTIC, packetlogger_open, "pklg", NULL, NULL },
356 /* Some MPEG files have magic numbers, others just have heuristics. */
357 { "MPEG", OPEN_INFO_HEURISTIC, mpeg_open, "mpg;mp3", NULL, NULL },
358 { "Daintree SNA", OPEN_INFO_HEURISTIC, daintree_sna_open, "dcf", NULL, NULL },
359 { "STANAG 4607 Format", OPEN_INFO_HEURISTIC, stanag4607_open, NULL, NULL, NULL },
360 { "ASN.1 Basic Encoding Rules", OPEN_INFO_HEURISTIC, ber_open, NULL, NULL, NULL },
362 * I put NetScreen *before* erf, because there were some
363 * false positives with my test-files (Sake Blok, July 2007)
365 * I put VWR *after* ERF, because there were some cases where
366 * ERF files were misidentified as vwr files (Stephen
367 * Donnelly, August 2013; see bug 9054)
369 * I put VWR *after* Peek Classic, CommView, iSeries text,
370 * Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
371 * because there were some cases where files of those types were
372 * misidentified as vwr files (Guy Harris, December 2013)
374 { "NetScreen snoop text file", OPEN_INFO_HEURISTIC, netscreen_open, "txt", NULL, NULL },
375 { "Endace ERF capture", OPEN_INFO_HEURISTIC, erf_open, "erf", NULL, NULL },
376 { "IPFIX File Format", OPEN_INFO_HEURISTIC, ipfix_open, "pfx;ipfix",NULL, NULL },
377 { "K12 text file", OPEN_INFO_HEURISTIC, k12text_open, "txt", NULL, NULL },
378 { "Savvius classic", OPEN_INFO_HEURISTIC, peekclassic_open, "pkt;tpc;apc;wpz", NULL, NULL },
379 { "pppd log (pppdump format)", OPEN_INFO_HEURISTIC, pppdump_open, NULL, NULL, NULL },
380 { "IBM iSeries comm. trace", OPEN_INFO_HEURISTIC, iseries_open, "txt", NULL, NULL },
381 { "I4B ISDN trace", OPEN_INFO_HEURISTIC, i4btrace_open, NULL, NULL, NULL },
382 { "MPEG2 transport stream", OPEN_INFO_HEURISTIC, mp2t_open, "ts;mpg", NULL, NULL },
383 { "CSIDS IPLog", OPEN_INFO_HEURISTIC, csids_open, NULL, NULL, NULL },
384 { "TCPIPtrace (VMS)", OPEN_INFO_HEURISTIC, vms_open, "txt", NULL, NULL },
385 { "CoSine IPSX L2 capture", OPEN_INFO_HEURISTIC, cosine_open, "txt", NULL, NULL },
386 { "Bluetooth HCI dump", OPEN_INFO_HEURISTIC, hcidump_open, NULL, NULL, NULL },
387 { "TamoSoft CommView", OPEN_INFO_HEURISTIC, commview_open, "ncf", NULL, NULL },
388 { "NetScaler", OPEN_INFO_HEURISTIC, nstrace_open, "cap", NULL, NULL },
389 { "Android Logcat Binary format", OPEN_INFO_HEURISTIC, logcat_open, "logcat", NULL, NULL },
390 { "Android Logcat Text formats", OPEN_INFO_HEURISTIC, logcat_text_open, "txt", NULL, NULL },
391 /* ASCII trace files from Telnet sessions. */
392 { "Lucent/Ascend access server trace", OPEN_INFO_HEURISTIC, ascend_open, "txt", NULL, NULL },
393 { "Toshiba Compact ISDN Router snoop", OPEN_INFO_HEURISTIC, toshiba_open, "txt", NULL, NULL },
394 /* Extremely weak heuristics - put them at the end. */
395 { "Ixia IxVeriWave .vwr Raw Capture", OPEN_INFO_HEURISTIC, vwr_open, "vwr", NULL, NULL },
396 { "CAM Inspector file", OPEN_INFO_HEURISTIC, camins_open, "camins", NULL, NULL },
397 { "JavaScript Object Notation", OPEN_INFO_HEURISTIC, json_open, "json", NULL, NULL }
400 /* this is only used to build the dynamic array on load, do NOT use this
401 * for anything else, because the size of the actual array will change if
402 * Lua scripts register a new file reader.
404 #define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
406 static GArray *open_info_arr = NULL;
408 /* this always points to the top of the created array */
409 struct open_info *open_routines = NULL;
411 /* this points to the first OPEN_INFO_HEURISTIC type in the array */
412 static guint heuristic_open_routine_idx = 0;
415 set_heuristic_routine(void)
418 g_assert(open_info_arr != NULL);
420 for (i = 0; i < open_info_arr->len; i++) {
421 if (open_routines[i].type == OPEN_INFO_HEURISTIC) {
422 heuristic_open_routine_idx = i;
426 g_assert(open_routines[i].type == OPEN_INFO_MAGIC);
429 g_assert(heuristic_open_routine_idx > 0);
433 init_open_routines(void)
436 struct open_info *i_open;
441 open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
443 g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
445 open_routines = (struct open_info *)(void*) open_info_arr->data;
447 /* Populate the extensions_set list now */
448 for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
449 if (i_open->extensions != NULL)
450 i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
453 set_heuristic_routine();
457 * Registers a new file reader - currently only called by wslua code for Lua readers.
458 * If first_routine is true, it's added before other readers of its type (magic or heuristic).
459 * Also, it checks for an existing reader of the same name and errors if it finds one; if
460 * you want to handle that condition more gracefully, call wtap_has_open_info() first.
463 wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
465 init_open_routines();
467 if (!oi || !oi->name) {
468 g_error("No open_info name given to register");
472 /* verify name doesn't already exist */
473 if (wtap_has_open_info(oi->name)) {
474 g_error("Name given to register_open_info already exists");
478 if (oi->extensions != NULL)
479 oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
481 /* if it's magic and first, prepend it; if it's heuristic and not first,
482 append it; if it's anything else, stick it in the middle */
483 if (first_routine && oi->type == OPEN_INFO_MAGIC) {
484 g_array_prepend_val(open_info_arr, *oi);
485 } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
486 g_array_append_val(open_info_arr, *oi);
488 g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
491 open_routines = (struct open_info *)(void*) open_info_arr->data;
492 set_heuristic_routine();
495 /* De-registers a file reader by removign it from the GArray based on its name.
496 * This function must NOT be called during wtap_open_offline(), since it changes the array.
497 * Note: this function will error if it doesn't find the given name; if you want to handle
498 * that condition more gracefully, call wtap_has_open_info() first.
501 wtap_deregister_open_info(const gchar *name)
504 init_open_routines();
507 g_error("Missing open_info name to de-register");
511 for (i = 0; i < open_info_arr->len; i++) {
512 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
513 if (open_routines[i].extensions_set != NULL)
514 g_strfreev(open_routines[i].extensions_set);
515 open_info_arr = g_array_remove_index(open_info_arr, i);
516 set_heuristic_routine();
521 g_error("deregister_open_info: name not found");
524 /* Determines if a open routine short name already exists
527 wtap_has_open_info(const gchar *name)
530 init_open_routines();
533 g_error("No name given to wtap_has_open_info!");
538 for (i = 0; i < open_info_arr->len; i++) {
539 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
548 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
549 * define them either.)
551 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
554 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
557 #define S_IFIFO _S_IFIFO
560 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
563 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
566 /* returns the 'type' number to use for wtap_open_offline based on the
567 passed-in name (the name in the open_info struct). It returns WTAP_TYPE_AUTO
568 on failure, which is the number 0. The 'type' number is the entry's index+1,
569 because that's what wtap_open_offline() expects it to be. */
571 open_info_name_to_type(const char *name)
574 init_open_routines();
577 return WTAP_TYPE_AUTO;
579 for (i = 0; i < open_info_arr->len; i++) {
580 if (open_routines[i].name != NULL &&
581 strcmp(name, open_routines[i].name) == 0)
585 return WTAP_TYPE_AUTO; /* no such file type */
589 get_file_extension(const char *pathname)
594 const char **compressed_file_extensionp;
598 * Is the pathname empty?
600 if (strcmp(pathname, "") == 0)
601 return NULL; /* no extension */
604 * Find the last component of the pathname.
606 filename = g_path_get_basename(pathname);
609 * Does it have an extension?
611 if (strchr(filename, '.') == NULL) {
613 return NULL; /* no extension whatsoever */
617 * Yes. Split it into components separated by ".".
619 components = g_strsplit(filename, ".", 0);
623 * Count the components.
625 for (ncomponents = 0; components[ncomponents] != NULL; ncomponents++)
628 if (ncomponents == 0) {
629 g_strfreev(components);
630 return NULL; /* no components */
632 if (ncomponents == 1) {
633 g_strfreev(components);
634 return NULL; /* only one component, with no "." */
638 * Is the last component one of the extensions used for compressed
641 extensionp = components[ncomponents - 1];
642 for (compressed_file_extensionp = compressed_file_extension_table;
643 *compressed_file_extensionp != NULL;
644 compressed_file_extensionp++) {
645 if (strcmp(extensionp, *compressed_file_extensionp) == 0) {
647 * Yes, it's one of the compressed-file extensions.
648 * Is there an extension before that?
650 if (ncomponents == 2) {
651 g_strfreev(components);
652 return NULL; /* no, only two components */
656 * Yes, return that extension.
658 extensionp = g_strdup(components[ncomponents - 2]);
659 g_strfreev(components);
665 * The extension isn't one of the compressed-file extensions;
668 extensionp = g_strdup(extensionp);
669 g_strfreev(components);
674 * Check if file extension is used in this heuristic
677 heuristic_uses_extension(unsigned int i, const char *extension)
682 * Does this file type *have* any extensions?
684 if (open_routines[i].extensions == NULL)
685 return FALSE; /* no */
688 * Check each of them against the specified extension.
690 for (extensionp = open_routines[i].extensions_set; *extensionp != NULL;
692 if (strcmp(extension, *extensionp) == 0) {
693 return TRUE; /* it's one of them */
697 return FALSE; /* it's not one of them */
700 /* Opens a file and prepares a wtap struct.
701 If "do_random" is TRUE, it opens the file twice; the second open
702 allows the application to do random-access I/O without moving
703 the seek offset for sequential I/O, which is used by Wireshark
704 so that it can do sequential I/O to a capture file that's being
705 written to as new packets arrive independently of random I/O done
706 to display protocol trees for packets when they're selected. */
708 wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
715 gboolean use_stdin = FALSE;
717 wtap_optionblock_t shb;
722 init_open_routines();
724 /* open standard input if filename is '-' */
725 if (strcmp(filename, "-") == 0)
728 /* First, make sure the file is valid */
730 if (ws_fstat64(0, &statb) < 0) {
735 if (ws_stat64(filename, &statb) < 0) {
740 if (S_ISFIFO(statb.st_mode)) {
742 * Opens of FIFOs are allowed only when not opening
745 * Currently, we do seeking when trying to find out
746 * the file type, but our I/O routines do some amount
747 * of buffering, and do backward seeks within the buffer
748 * if possible, so at least some file types can be
749 * opened from pipes, so we don't completely disallow opens
753 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
756 } else if (S_ISDIR(statb.st_mode)) {
758 * Return different errors for "this is a directory"
759 * and "this is some random special file type", so
760 * the user can get a potentially more helpful error.
764 } else if (! S_ISREG(statb.st_mode)) {
765 *err = WTAP_ERR_NOT_REGULAR_FILE;
770 * We need two independent descriptors for random access, so
771 * they have different file positions. If we're opening the
772 * standard input, we can only dup it to get additional
773 * descriptors, so we can't have two independent descriptors,
774 * and thus can't do random access.
776 if (use_stdin && do_random) {
777 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
782 wth = (wtap *)g_malloc0(sizeof(wtap));
785 errno = WTAP_ERR_CANT_OPEN;
788 * We dup FD 0, so that we don't have to worry about
789 * a file_close of wth->fh closing the standard
790 * input of the process.
799 if (_setmode(fd, O_BINARY) == -1) {
800 /* "Shouldn't happen" */
806 if (!(wth->fh = file_fdopen(fd))) {
813 if (!(wth->fh = file_open(filename))) {
821 if (!(wth->random_fh = file_open(filename))) {
828 wth->random_fh = NULL;
831 wth->file_encap = WTAP_ENCAP_UNKNOWN;
832 wth->subtype_sequential_close = NULL;
833 wth->subtype_close = NULL;
834 wth->file_tsprec = WTAP_TSPREC_USEC;
836 wth->wslua_data = NULL;
837 wth->shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
838 shb = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
840 g_array_append_val(wth->shb_hdrs, shb);
842 /* Initialize the array containing a list of interfaces. pcapng_open and
843 * erf_open needs this (and libpcap_open for ERF encapsulation types).
844 * Always initing it here saves checking for a NULL ptr later. */
845 wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
847 if (wth->random_fh) {
848 wth->fast_seek = g_ptr_array_new();
850 file_set_random_access(wth->fh, FALSE, wth->fast_seek);
851 file_set_random_access(wth->random_fh, TRUE, wth->fast_seek);
854 /* 'type' is 1 greater than the array index */
855 if (type != WTAP_TYPE_AUTO && type <= open_info_arr->len) {
858 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
859 /* I/O error - give up */
864 /* Set wth with wslua data if any - this is how we pass the data
865 * to the file reader, kinda like the priv member but not free'd later.
866 * It's ok for this to copy a NULL.
868 wth->wslua_data = open_routines[type - 1].wslua_data;
870 result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
873 case WTAP_OPEN_ERROR:
874 /* Error - give up */
878 case WTAP_OPEN_NOT_MINE:
879 /* No error, but not that type of file */
883 /* We found the file type */
888 /* Try all file types that support magic numbers */
889 for (i = 0; i < heuristic_open_routine_idx; i++) {
890 /* Seek back to the beginning of the file; the open routine
891 for the previous file type may have left the file
892 position somewhere other than the beginning, and the
893 open routine for this file type will probably want
894 to start reading at the beginning.
896 Initialize the data offset while we're at it. */
897 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
898 /* Error - give up */
903 /* Set wth with wslua data if any - this is how we pass the data
904 * to the file reader, kinda like the priv member but not free'd later.
905 * It's ok for this to copy a NULL.
907 wth->wslua_data = open_routines[i].wslua_data;
909 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
911 case WTAP_OPEN_ERROR:
912 /* Error - give up */
916 case WTAP_OPEN_NOT_MINE:
917 /* No error, but not that type of file */
921 /* We found the file type */
927 /* Does this file's name have an extension? */
928 extension = get_file_extension(filename);
929 if (extension != NULL) {
930 /* Yes - try the heuristic types that use that extension first. */
931 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
932 /* Does this type use that extension? */
933 if (heuristic_uses_extension(i, extension)) {
935 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
936 /* Error - give up */
942 /* Set wth with wslua data if any - this is how we pass the data
943 * to the file reader, kind of like priv but not free'd later.
945 wth->wslua_data = open_routines[i].wslua_data;
947 switch ((*open_routines[i].open_routine)(wth,
950 case WTAP_OPEN_ERROR:
951 /* Error - give up */
956 case WTAP_OPEN_NOT_MINE:
957 /* No error, but not that type of file */
961 /* We found the file type */
969 * Now try the heuristic types that have no extensions
970 * to check; we try those before the ones that have
971 * extensions that *don't* match this file's extension,
972 * on the theory that files of those types generally
973 * have one of the type's extensions, and, as this file
974 * *doesn't* have one of those extensions, it's probably
975 * *not* one of those files.
977 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
978 /* Does this type have any extensions? */
979 if (open_routines[i].extensions == NULL) {
981 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
982 /* Error - give up */
988 /* Set wth with wslua data if any - this is how we pass the data
989 * to the file reader, kind of like priv but not free'd later.
991 wth->wslua_data = open_routines[i].wslua_data;
993 switch ((*open_routines[i].open_routine)(wth,
996 case WTAP_OPEN_ERROR:
997 /* Error - give up */
1002 case WTAP_OPEN_NOT_MINE:
1003 /* No error, but not that type of file */
1006 case WTAP_OPEN_MINE:
1007 /* We found the file type */
1015 * Now try the ones that have extensions where none of
1016 * them matches this file's extensions.
1018 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1020 * Does this type have extensions and is this file's
1021 * extension one of them?
1023 if (open_routines[i].extensions != NULL &&
1024 !heuristic_uses_extension(i, extension)) {
1026 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1027 /* Error - give up */
1033 /* Set wth with wslua data if any - this is how we pass the data
1034 * to the file reader, kind of like priv but not free'd later.
1036 wth->wslua_data = open_routines[i].wslua_data;
1038 switch ((*open_routines[i].open_routine)(wth,
1041 case WTAP_OPEN_ERROR:
1042 /* Error - give up */
1047 case WTAP_OPEN_NOT_MINE:
1048 /* No error, but not that type of file */
1051 case WTAP_OPEN_MINE:
1052 /* We found the file type */
1060 /* No - try all the heuristics types in order. */
1061 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1063 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1064 /* Error - give up */
1069 /* Set wth with wslua data if any - this is how we pass the data
1070 * to the file reader, kind of like priv but not free'd later.
1072 wth->wslua_data = open_routines[i].wslua_data;
1074 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
1076 case WTAP_OPEN_ERROR:
1077 /* Error - give up */
1081 case WTAP_OPEN_NOT_MINE:
1082 /* No error, but not that type of file */
1085 case WTAP_OPEN_MINE:
1086 /* We found the file type */
1094 /* Well, it's not one of the types of file we know about. */
1096 *err = WTAP_ERR_FILE_UNKNOWN_FORMAT;
1100 wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
1101 ws_buffer_init(wth->frame_buffer, 1500);
1103 if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
1104 (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
1106 wtap_optionblock_t descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
1107 wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
1109 descr_mand->wtap_encap = wth->file_encap;
1110 if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
1111 descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */
1112 wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9);
1113 descr_mand->tsprecision = WTAP_TSPREC_NSEC;
1115 descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
1116 wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6);
1117 descr_mand->tsprecision = WTAP_TSPREC_USEC;
1119 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
1120 descr_mand->snap_len = wth->snapshot_length;
1122 descr_mand->num_stat_entries = 0; /* Number of ISB:s */
1123 descr_mand->interface_statistics = NULL;
1124 g_array_append_val(wth->interface_data, descr);
1131 * Given the pathname of the file we just closed with wtap_fdclose(), attempt
1132 * to reopen that file and assign the new file descriptor(s) to the sequential
1133 * stream and, if do_random is TRUE, to the random stream. Used on Windows
1134 * after the rename of a file we had open was done or if the rename of a
1135 * file on top of a file we had open failed.
1137 * This is only required by Wireshark, not TShark, and, at the point that
1138 * Wireshark is doing this, the sequential stream is closed, and the
1139 * random stream is open, so this refuses to open pipes, and only
1140 * reopens the random stream.
1143 wtap_fdreopen(wtap *wth, const char *filename, int *err)
1148 * We need two independent descriptors for random access, so
1149 * they have different file positions. If we're opening the
1150 * standard input, we can only dup it to get additional
1151 * descriptors, so we can't have two independent descriptors,
1152 * and thus can't do random access.
1154 if (strcmp(filename, "-") == 0) {
1155 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
1159 /* First, make sure the file is valid */
1160 if (ws_stat64(filename, &statb) < 0) {
1164 if (S_ISFIFO(statb.st_mode)) {
1166 * Opens of FIFOs are not allowed; see above.
1168 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
1170 } else if (S_ISDIR(statb.st_mode)) {
1172 * Return different errors for "this is a directory"
1173 * and "this is some random special file type", so
1174 * the user can get a potentially more helpful error.
1178 } else if (! S_ISREG(statb.st_mode)) {
1179 *err = WTAP_ERR_NOT_REGULAR_FILE;
1184 errno = WTAP_ERR_CANT_OPEN;
1185 if (!file_fdreopen(wth->random_fh, filename)) {
1192 /* Table of the file types and subtypes for which we have built-in support.
1193 Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending
1196 These are used to report what type and subtype a given file is and
1197 to let the user select a format when writing out packets.
1199 This table is what we start with, but it can be modified.
1200 If we need to modify it, we allocate a GArray, copy the entries
1201 in the above table to that GArray, use the copy as the table, and
1202 make all changes to the copy. */
1203 static const struct file_type_subtype_info dump_open_table_base[] = {
1204 /* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN (only used internally for initialization) */
1205 { NULL, NULL, NULL, NULL,
1209 /* WTAP_FILE_TYPE_SUBTYPE_PCAP */
1210 /* Gianluca Varenni suggests that we add "deprecated" to the description. */
1211 { "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp",
1213 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1215 /* WTAP_FILE_TYPE_SUBTYPE_PCAPNG */
1216 { "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
1217 FALSE, TRUE, WTAP_COMMENT_PER_SECTION|WTAP_COMMENT_PER_INTERFACE|WTAP_COMMENT_PER_PACKET,
1218 pcapng_dump_can_write_encap, pcapng_dump_open, NULL },
1220 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC */
1221 { "Wireshark - nanosecond libpcap", "nseclibpcap", "pcap", "cap;dmp",
1223 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1225 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX */
1226 { "AIX tcpdump - libpcap", "aixlibpcap", "pcap", "cap;dmp",
1230 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029 */
1231 { "Modified tcpdump - libpcap", "modlibpcap", "pcap", "cap;dmp",
1233 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1235 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA */
1236 { "Nokia tcpdump - libpcap ", "nokialibpcap", "pcap", "cap;dmp",
1238 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1240 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417 */
1241 { "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "pcap", "cap;dmp",
1243 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1245 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915 */
1246 { "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "pcap", "cap;dmp",
1248 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1250 /* WTAP_FILE_TYPE_SUBTYPE_5VIEWS */
1251 { "InfoVista 5View capture", "5views", "5vw", NULL,
1253 _5views_dump_can_write_encap, _5views_dump_open, NULL },
1255 /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_1_0 */
1256 { "AIX iptrace 1.0", "iptrace_1", NULL, NULL,
1260 /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_2_0 */
1261 { "AIX iptrace 2.0", "iptrace_2", NULL, NULL,
1265 /* WTAP_FILE_TYPE_SUBTYPE_BER */
1266 { "ASN.1 Basic Encoding Rules", "ber", NULL, NULL,
1270 /* WTAP_FILE_TYPE_SUBTYPE_HCIDUMP */
1271 { "Bluetooth HCI dump", "hcidump", NULL, NULL,
1275 /* WTAP_FILE_TYPE_SUBTYPE_CATAPULT_DCT2000 */
1276 { "Catapult DCT2000 trace (.out format)", "dct2000", "out", NULL,
1278 catapult_dct2000_dump_can_write_encap, catapult_dct2000_dump_open, NULL },
1280 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_OLD */
1281 { "Cinco Networks NetXRay 1.x", "netxray1", "cap", NULL,
1285 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_0 */
1286 { "Cinco Networks NetXRay 2.0 or later", "netxray2", "cap", NULL,
1290 /* WTAP_FILE_TYPE_SUBTYPE_COSINE */
1291 { "CoSine IPSX L2 capture", "cosine", "txt", NULL,
1295 /* WTAP_FILE_TYPE_SUBTYPE_CSIDS */
1296 { "CSIDS IPLog", "csids", NULL, NULL,
1300 /* WTAP_FILE_TYPE_SUBTYPE_DBS_ETHERWATCH */
1301 { "DBS Etherwatch (VMS)", "etherwatch", "txt", NULL,
1305 /* WTAP_FILE_TYPE_SUBTYPE_ERF */
1306 { "Endace ERF capture", "erf", "erf", NULL,
1308 erf_dump_can_write_encap, erf_dump_open, NULL },
1310 /* WTAP_FILE_TYPE_SUBTYPE_EYESDN */
1311 { "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "trc", NULL,
1313 eyesdn_dump_can_write_encap, eyesdn_dump_open, NULL },
1315 /* WTAP_FILE_TYPE_SUBTYPE_NETTL */
1316 { "HP-UX nettl trace", "nettl", "trc0", "trc1",
1318 nettl_dump_can_write_encap, nettl_dump_open, NULL },
1320 /* WTAP_FILE_TYPE_SUBTYPE_ISERIES */
1321 { "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "txt", NULL,
1325 /* WTAP_FILE_TYPE_SUBTYPE_ISERIES_UNICODE */
1326 { "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "txt", NULL,
1330 /* WTAP_FILE_TYPE_SUBTYPE_I4BTRACE */
1331 { "I4B ISDN trace", "i4btrace", NULL, NULL,
1335 /* WTAP_FILE_TYPE_SUBTYPE_ASCEND */
1336 { "Lucent/Ascend access server trace", "ascend", "txt", NULL,
1340 /* WTAP_FILE_TYPE_SUBTYPE_NETMON_1_x */
1341 { "Microsoft NetMon 1.x", "netmon1", "cap", NULL,
1343 netmon_dump_can_write_encap_1_x, netmon_dump_open, NULL },
1345 /* WTAP_FILE_TYPE_SUBTYPE_NETMON_2_x */
1346 { "Microsoft NetMon 2.x", "netmon2", "cap", NULL,
1348 netmon_dump_can_write_encap_2_x, netmon_dump_open, NULL },
1350 /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_UNCOMPRESSED */
1351 { "Sniffer (DOS)", "ngsniffer", "cap", "enc;trc;fdc;syc",
1353 ngsniffer_dump_can_write_encap, ngsniffer_dump_open, NULL },
1355 /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_COMPRESSED */
1356 { "Sniffer (DOS), compressed", "ngsniffer_comp", "cap", "enc;trc;fdc;syc",
1360 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_1 */
1361 { "NetXray, Sniffer (Windows) 1.1", "ngwsniffer_1_1", "cap", NULL,
1363 netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1, NULL },
1365 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x */
1366 { "Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "cap", "caz",
1368 netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0, NULL },
1370 /* WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS */
1371 { "Network Instruments Observer", "niobserver", "bfr", NULL,
1373 network_instruments_dump_can_write_encap, network_instruments_dump_open, NULL },
1375 /* WTAP_FILE_TYPE_SUBTYPE_LANALYZER */
1376 { "Novell LANalyzer","lanalyzer", "tr1", NULL,
1378 lanalyzer_dump_can_write_encap, lanalyzer_dump_open, NULL },
1380 /* WTAP_FILE_TYPE_SUBTYPE_PPPDUMP */
1381 { "pppd log (pppdump format)", "pppd", NULL, NULL,
1385 /* WTAP_FILE_TYPE_SUBTYPE_RADCOM */
1386 { "RADCOM WAN/LAN analyzer", "radcom", NULL, NULL,
1390 /* WTAP_FILE_TYPE_SUBTYPE_SNOOP */
1391 { "Sun snoop", "snoop", "snoop", "cap",
1393 snoop_dump_can_write_encap, snoop_dump_open, NULL },
1395 /* WTAP_FILE_TYPE_SUBTYPE_SHOMITI */
1396 { "Shomiti/Finisar Surveyor", "shomiti", "cap", NULL,
1400 /* WTAP_FILE_TYPE_SUBTYPE_VMS */
1401 { "TCPIPtrace (VMS)", "tcpiptrace", "txt", NULL,
1405 /* WTAP_FILE_TYPE_SUBTYPE_K12 */
1406 { "Tektronix K12xx 32-bit .rf5 format", "rf5", "rf5", NULL,
1408 k12_dump_can_write_encap, k12_dump_open, NULL },
1410 /* WTAP_FILE_TYPE_SUBTYPE_TOSHIBA */
1411 { "Toshiba Compact ISDN Router snoop", "toshiba", "txt", NULL,
1415 /* WTAP_FILE_TYPE_SUBTYPE_VISUAL_NETWORKS */
1416 { "Visual Networks traffic capture", "visual", NULL, NULL,
1418 visual_dump_can_write_encap, visual_dump_open, NULL },
1420 /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V56 */
1421 { "Savvius classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
1425 /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V7 */
1426 { "Savvius classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
1430 /* WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED */
1431 { "Savvius tagged", "peektagged", "pkt", "tpc;apc;wpz",
1435 /* WTAP_FILE_TYPE_SUBTYPE_MPEG */
1436 { "MPEG", "mpeg", "mpeg", "mpg;mp3",
1440 /* WTAP_FILE_TYPE_SUBTYPE_K12TEXT */
1441 { "K12 text file", "k12text", "txt", NULL,
1443 k12text_dump_can_write_encap, k12text_dump_open, NULL },
1445 /* WTAP_FILE_TYPE_SUBTYPE_NETSCREEN */
1446 { "NetScreen snoop text file", "netscreen", "txt", NULL,
1450 /* WTAP_FILE_TYPE_SUBTYPE_COMMVIEW */
1451 { "TamoSoft CommView", "commview", "ncf", NULL,
1453 commview_dump_can_write_encap, commview_dump_open, NULL },
1455 /* WTAP_FILE_TYPE_SUBTYPE_BTSNOOP */
1456 { "Symbian OS btsnoop", "btsnoop", "log", NULL,
1458 btsnoop_dump_can_write_encap, btsnoop_dump_open_h4, NULL },
1460 /* WTAP_FILE_TYPE_SUBTYPE_TNEF */
1461 { "Transport-Neutral Encapsulation Format", "tnef", NULL, NULL,
1465 /* WTAP_FILE_TYPE_SUBTYPE_DCT3TRACE */
1466 { "Gammu DCT3 trace", "dct3trace", "xml", NULL,
1470 /* WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER */
1471 { "OS X PacketLogger", "pklg", "pklg", NULL,
1475 /* WTAP_FILE_TYPE_SUBTYPE_DAINTREE_SNA */
1476 { "Daintree SNA", "dsna", "dcf", NULL,
1480 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0 */
1481 { "NetScaler Trace (Version 1.0)", "nstrace10", NULL, NULL,
1483 nstrace_10_dump_can_write_encap, nstrace_dump_open, NULL },
1485 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0 */
1486 { "NetScaler Trace (Version 2.0)", "nstrace20", "cap", NULL,
1488 nstrace_20_dump_can_write_encap, nstrace_dump_open, NULL },
1490 /* WTAP_FILE_TYPE_SUBTYPE_JPEG_JFIF */
1491 { "JPEG/JFIF", "jpeg", "jpg", "jpeg;jfif",
1495 /* WTAP_FILE_TYPE_SUBTYPE_IPFIX */
1496 { "IPFIX File Format", "ipfix", "pfx", "ipfix",
1500 /* WTAP_ENCAP_MIME */
1501 { "MIME File Format", "mime", NULL, NULL,
1505 /* WTAP_FILE_TYPE_SUBTYPE_AETHRA */
1506 { "Aethra .aps file", "aethra", "aps", NULL,
1510 /* WTAP_FILE_TYPE_SUBTYPE_MPEG_2_TS */
1511 { "MPEG2 transport stream", "mp2t", "mp2t", "ts;mpg",
1515 /* WTAP_FILE_TYPE_SUBTYPE_VWR_80211 */
1516 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr80211", "vwr", NULL,
1520 /* WTAP_FILE_TYPE_SUBTYPE_VWR_ETH */
1521 { "Ixia IxVeriWave .vwr Raw Ethernet Capture", "vwreth", "vwr", NULL,
1525 /* WTAP_FILE_TYPE_SUBTYPE_CAMINS */
1526 { "CAM Inspector file", "camins", "camins", NULL,
1530 /* WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 */
1531 { "STANAG 4607 Format", "stanag4607", NULL, NULL,
1535 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 */
1536 { "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
1538 nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
1540 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT */
1541 { "Android Logcat Binary format", "logcat", "logcat", NULL,
1543 logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
1545 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF */
1546 { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
1548 logcat_text_brief_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
1550 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS */
1551 { "Android Logcat Process text format", "logcat-process", NULL, NULL,
1553 logcat_text_process_dump_can_write_encap, logcat_text_process_dump_open, NULL },
1555 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG */
1556 { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
1558 logcat_text_tag_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
1560 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD */
1561 { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
1563 logcat_text_thread_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
1565 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME */
1566 { "Android Logcat Time text format", "logcat-time", NULL, NULL,
1568 logcat_text_time_dump_can_write_encap, logcat_text_time_dump_open, NULL },
1570 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME */
1571 { "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
1573 logcat_text_threadtime_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
1575 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG */
1576 { "Android Logcat Long text format", "logcat-long", NULL, NULL,
1578 logcat_text_long_dump_can_write_encap, logcat_text_long_dump_open, NULL },
1580 /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA */
1581 { "Colasoft Capsa format", "capsa", "cscpkt", NULL,
1585 /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER */
1586 { "Colasoft Packet Builder format", "colasoft-pb", "cscpkt", NULL,
1590 /* WTAP_FILE_TYPE_SUBTYPE_JSON */
1591 { "JavaScript Object Notation", "json", "json", "NULL",
1595 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 */
1596 { "NetScaler Trace (Version 3.5)", "nstrace35", "cap", NULL,
1598 nstrace_35_dump_can_write_encap, nstrace_dump_open, NULL },
1600 /* WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423 */
1601 { "3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
1605 /* WTAP_FILE_TYPE_MPLOG */
1606 { "Micropross mplog file", "mplog", "mplog", NULL,
1612 * Pointer to the table we're currently using. It's initialized to point
1613 * to the static table, but, if we have to allocate the GArray, it's
1614 * changed to point to the data in the GArray.
1616 static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
1619 * Number of elements in the table we're currently using. It's initialized
1620 * to the number of elements in the static table, but, if we have to
1621 * allocate the GArray, it's changed to have the size of the GArray.
1623 gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
1626 * Pointer to the GArray; NULL until it's needed.
1628 static GArray* dump_open_table_arr = NULL;
1631 * Create the GArray from the static table if it hasn't already been created.
1634 init_file_types_subtypes_garray(void)
1636 if (dump_open_table_arr) return;
1638 dump_open_table_arr = g_array_new(FALSE,TRUE,sizeof(struct file_type_subtype_info));
1640 g_array_append_vals(dump_open_table_arr,dump_open_table_base,wtap_num_file_types_subtypes);
1642 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1645 /* if subtype is WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, then create a new subtype as well as register it, else replace the
1646 existing entry in that spot */
1648 wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype)
1650 struct file_type_subtype_info* finfo;
1652 if (!fi || !fi->name || !fi->short_name || subtype > wtap_num_file_types_subtypes) {
1653 g_error("no file type info or invalid file type to register");
1657 /* do we want a new registration? */
1658 if (subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
1659 /* register a new one; first verify there isn't one named this already */
1660 if (wtap_short_string_to_file_type_subtype(fi->short_name) > -1 ) {
1661 g_error("file type short name already exists");
1666 * Create the GArray if it hasn't already been created.
1668 init_file_types_subtypes_garray();
1670 g_array_append_val(dump_open_table_arr,*fi);
1672 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1674 return wtap_num_file_types_subtypes++;
1677 /* re-register an existing one - verify the short names do match (sanity check really) */
1678 if (!dump_open_table[subtype].short_name || strcmp(dump_open_table[subtype].short_name,fi->short_name) != 0) {
1679 g_error("invalid file type name given to register");
1684 * Create the GArray if it hasn't already been created.
1686 init_file_types_subtypes_garray();
1689 * Get the pointer from the GArray, so that we get a non-const
1692 finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
1693 /*finfo->name = fi->name;*/
1694 /*finfo->short_name = fi->short_name;*/
1695 finfo->default_file_extension = fi->default_file_extension;
1696 finfo->additional_file_extensions = fi->additional_file_extensions;
1697 finfo->writing_must_seek = fi->writing_must_seek;
1698 finfo->has_name_resolution = fi->has_name_resolution;
1699 finfo->supported_comment_types = fi->supported_comment_types;
1700 finfo->can_write_encap = fi->can_write_encap;
1701 finfo->dump_open = fi->dump_open;
1702 finfo->wslua_info = fi->wslua_info;
1707 /* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
1710 wtap_deregister_file_type_subtype(const int subtype)
1712 struct file_type_subtype_info* finfo;
1714 if (subtype < 0 || subtype >= wtap_num_file_types_subtypes) {
1715 g_error("invalid file type to de-register");
1720 * Create the GArray if it hasn't already been created.
1722 init_file_types_subtypes_garray();
1725 * Get the pointer from the GArray, so that we get a non-const
1728 finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
1729 /* unfortunately, it's not safe to null-out the name or short_name; bunch of other code doesn't guard aainst that, afaict */
1730 /*finfo->name = NULL;*/
1731 /*finfo->short_name = NULL;*/
1732 finfo->default_file_extension = NULL;
1733 finfo->additional_file_extensions = NULL;
1734 finfo->writing_must_seek = FALSE;
1735 finfo->has_name_resolution = FALSE;
1736 finfo->supported_comment_types = 0;
1737 finfo->can_write_encap = NULL;
1738 finfo->dump_open = NULL;
1739 finfo->wslua_info = NULL;
1743 wtap_get_num_file_types_subtypes(void)
1745 return wtap_num_file_types_subtypes;
1749 * Given a GArray of WTAP_ENCAP_ types, return the per-file encapsulation
1750 * type that would be needed to write out a file with those types. If
1751 * there's only one type, it's that type, otherwise it's
1752 * WTAP_ENCAP_PER_PACKET.
1755 wtap_dump_file_encap_type(const GArray *file_encaps)
1759 encap = WTAP_ENCAP_PER_PACKET;
1760 if (file_encaps->len == 1) {
1761 /* OK, use the one-and-only encapsulation type. */
1762 encap = g_array_index(file_encaps, gint, 0);
1768 wtap_dump_can_write_encap(int filetype, int encap)
1772 if (filetype < 0 || filetype >= wtap_num_file_types_subtypes
1773 || dump_open_table[filetype].can_write_encap == NULL)
1776 result = (*dump_open_table[filetype].can_write_encap)(encap);
1779 /* if the err said to check wslua's can_write_encap, try that */
1780 if (result == WTAP_ERR_CHECK_WSLUA
1781 && dump_open_table[filetype].wslua_info != NULL
1782 && dump_open_table[filetype].wslua_info->wslua_can_write_encap != NULL) {
1784 result = (*dump_open_table[filetype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[filetype].wslua_info->wslua_data);
1796 * Return TRUE if a capture with a given GArray of encapsulation types
1797 * and a given bitset of comment types can be written in a specified
1798 * format, and FALSE if it can't.
1801 wtap_dump_can_write_format(int ft, const GArray *file_encaps,
1802 guint32 required_comment_types)
1807 * Can we write in this format?
1809 if (!wtap_dump_can_open(ft)) {
1815 * Yes. Can we write out all the required comments in this
1818 if (!wtap_dump_supports_comment_types(ft, required_comment_types)) {
1824 * Yes. Is the required per-file encapsulation type supported?
1825 * This might be WTAP_ENCAP_PER_PACKET.
1827 if (!wtap_dump_can_write_encap(ft, wtap_dump_file_encap_type(file_encaps))) {
1833 * Yes. Are all the individual encapsulation types supported?
1835 for (i = 0; i < file_encaps->len; i++) {
1836 if (!wtap_dump_can_write_encap(ft,
1837 g_array_index(file_encaps, int, i))) {
1838 /* No - one of them isn't. */
1843 /* Yes - we're OK. */
1848 * Return TRUE if we can write a file with the given GArray of
1849 * encapsulation types and the given bitmask of comment types.
1852 wtap_dump_can_write(const GArray *file_encaps, guint32 required_comment_types)
1856 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1857 /* To save a file with Wiretap, Wiretap has to handle that format,
1858 * and its code to handle that format must be able to write a file
1859 * with this file's encapsulation types.
1861 if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
1862 /* OK, we can write it out in this type. */
1867 /* No, we couldn't save it in any format. */
1872 * Get a GArray of WTAP_FILE_TYPE_SUBTYPE_ values for file types/subtypes
1873 * that can be used to save a file of a given type/subtype with a given
1874 * GArray of encapsulation types and the given bitmask of comment types.
1877 wtap_get_savable_file_types_subtypes(int file_type_subtype,
1878 const GArray *file_encaps, guint32 required_comment_types)
1880 GArray *savable_file_types_subtypes;
1882 int default_file_type_subtype = -1;
1883 int other_file_type_subtype = -1;
1885 /* Can we save this file in its own file type/subtype? */
1886 if (wtap_dump_can_write_format(file_type_subtype, file_encaps,
1887 required_comment_types)) {
1888 /* Yes - make that the default file type/subtype. */
1889 default_file_type_subtype = file_type_subtype;
1891 /* OK, find the first file type/subtype we *can* save it as. */
1892 default_file_type_subtype = -1;
1893 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1894 if (wtap_dump_can_write_format(ft, file_encaps,
1895 required_comment_types)) {
1897 default_file_type_subtype = ft;
1902 if (default_file_type_subtype == -1) {
1903 /* We don't support writing this file as any file type/subtype. */
1907 /* Allocate the array. */
1908 savable_file_types_subtypes = g_array_new(FALSE, FALSE, (guint)sizeof (int));
1910 /* Put the default file type/subtype first in the list. */
1911 g_array_append_val(savable_file_types_subtypes, default_file_type_subtype);
1913 /* If the default is pcap, put pcap-NG right after it if we can
1914 also write it in pcap-NG format; otherwise, if the default is
1915 pcap-NG, put pcap right after it if we can also write it in
1917 if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
1918 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, file_encaps,
1919 required_comment_types))
1920 other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
1921 } else if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
1922 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAP, file_encaps,
1923 required_comment_types))
1924 other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
1926 if (other_file_type_subtype != -1)
1927 g_array_append_val(savable_file_types_subtypes, other_file_type_subtype);
1929 /* Add all the other file types/subtypes that work. */
1930 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1931 if (ft == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1932 continue; /* not a real file type */
1933 if (ft == default_file_type_subtype || ft == other_file_type_subtype)
1934 continue; /* we've already done this one */
1935 if (wtap_dump_can_write_format(ft, file_encaps,
1936 required_comment_types)) {
1937 /* OK, we can write it out in this type. */
1938 g_array_append_val(savable_file_types_subtypes, ft);
1942 return savable_file_types_subtypes;
1945 /* Name that should be somewhat descriptive. */
1947 wtap_file_type_subtype_string(int file_type_subtype)
1949 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes) {
1950 g_error("Unknown capture file type %d", file_type_subtype);
1951 /** g_error() does an abort() and thus never returns **/
1954 return dump_open_table[file_type_subtype].name;
1957 /* Name to use in, say, a command-line flag specifying the type/subtype. */
1959 wtap_file_type_subtype_short_string(int file_type_subtype)
1961 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
1964 return dump_open_table[file_type_subtype].short_name;
1967 /* Translate a short name to a capture file type/subtype. */
1969 wtap_short_string_to_file_type_subtype(const char *short_name)
1971 int file_type_subtype;
1973 for (file_type_subtype = 0; file_type_subtype < wtap_num_file_types_subtypes; file_type_subtype++) {
1974 if (dump_open_table[file_type_subtype].short_name != NULL &&
1975 strcmp(short_name, dump_open_table[file_type_subtype].short_name) == 0)
1976 return file_type_subtype;
1980 * We now call the "libpcap" file format just "pcap", but we
1981 * allow it to be specified as "libpcap" as well, for
1982 * backwards compatibility.
1984 if (strcmp(short_name, "libpcap") == 0)
1985 return WTAP_FILE_TYPE_SUBTYPE_PCAP;
1987 return -1; /* no such file type, or we can't write it */
1991 add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
1992 const char **compressed_file_extensions)
1994 gchar **extensions_set, **extensionp;
1998 * Add the default extension, and all compressed variants of
2001 extensions = add_extensions(extensions,
2002 dump_open_table[file_type_subtype].default_file_extension,
2003 compressed_file_extensions);
2005 if (dump_open_table[file_type_subtype].additional_file_extensions != NULL) {
2007 * We have additional extensions; add them.
2009 * First, split the extension-list string into a set of
2012 extensions_set = g_strsplit(dump_open_table[file_type_subtype].additional_file_extensions,
2016 * Add each of those extensions to the list.
2018 for (extensionp = extensions_set; *extensionp != NULL;
2020 extension = *extensionp;
2023 * Add the extension, and all compressed variants
2026 extensions = add_extensions(extensions, extension,
2027 compressed_file_extensions);
2030 g_strfreev(extensions_set);
2035 /* Return a list of file extensions that are used by the specified file type.
2037 If include_compressed is TRUE, the list will include compressed
2038 extensions, e.g. not just "pcap" but also "pcap.gz" if we can read
2041 All strings in the list are allocated with g_malloc() and must be freed
2044 wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
2047 static const char *no_compressed_extensions[] = {
2051 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2052 return NULL; /* not a valid file type */
2054 if (dump_open_table[file_type_subtype].default_file_extension == NULL)
2055 return NULL; /* valid, but no extensions known */
2057 extensions = NULL; /* empty list, to start with */
2060 * Add all this file type's extensions, with compressed
2061 * variants if include_compressed is true.
2063 extensions = add_extensions_for_file_type_subtype(file_type_subtype, extensions,
2064 include_compressed ? compressed_file_extension_table : no_compressed_extensions);
2070 * Free a list returned by wtap_get_file_extension_type_extensions(),
2071 * wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
2074 wtap_free_extensions_list(GSList *extensions)
2078 for (extension = extensions; extension != NULL;
2079 extension = g_slist_next(extension)) {
2080 g_free(extension->data);
2082 g_slist_free(extensions);
2085 /* Return the default file extension to use with the specified file type;
2086 that's just the extension, without any ".". */
2088 wtap_default_file_extension(int file_type_subtype)
2090 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2093 return dump_open_table[file_type_subtype].default_file_extension;
2097 wtap_dump_can_open(int file_type_subtype)
2099 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2100 || dump_open_table[file_type_subtype].dump_open == NULL)
2108 wtap_dump_can_compress(int file_type_subtype)
2111 * If this is an unknown file type, or if we have to
2112 * seek when writing out a file with this file type,
2115 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2116 || dump_open_table[file_type_subtype].writing_must_seek)
2123 wtap_dump_can_compress(int file_type_subtype _U_)
2130 wtap_dump_has_name_resolution(int file_type_subtype)
2132 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2133 || dump_open_table[file_type_subtype].has_name_resolution == FALSE)
2140 wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
2142 guint32 supported_comment_types;
2144 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2147 supported_comment_types = dump_open_table[file_type_subtype].supported_comment_types;
2149 if ((comment_types & supported_comment_types) == comment_types)
2154 static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean comressed, int *err);
2155 static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen,
2156 gboolean compressed, int *err);
2157 static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err);
2159 static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename);
2160 static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
2161 static int wtap_dump_file_close(wtap_dumper *wdh);
2163 static wtap_dumper *
2164 wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
2165 GArray* shb_hdrs, wtapng_iface_descriptions_t *idb_inf,
2166 GArray* nrb_hdrs, int *err)
2169 wtap_optionblock_t descr, file_int_data;
2170 wtapng_if_descr_mandatory_t *descr_mand, *file_int_data_mand;
2172 /* Check whether we can open a capture file with that file type
2173 and that encapsulation. */
2174 if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
2177 /* Allocate a data structure for the output stream. */
2178 wdh = wtap_dump_alloc_wdh(file_type_subtype, encap, snaplen, compressed, err);
2180 return NULL; /* couldn't allocate it */
2182 /* Set Section Header Block data */
2183 wdh->shb_hdrs = shb_hdrs;
2184 /* Set Name Resolution Block data */
2185 wdh->nrb_hdrs = nrb_hdrs;
2186 /* Set Interface Description Block data */
2187 if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
2190 /* XXX: what free's this stuff? */
2191 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2192 for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
2193 file_int_data = g_array_index(idb_inf->interface_data, wtap_optionblock_t, itf_count);
2194 file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(file_int_data);
2195 descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2196 wtap_optionblock_copy_options(descr, file_int_data);
2197 if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data_mand->wtap_encap)) {
2198 descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
2199 descr_mand->wtap_encap = encap;
2200 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
2202 g_array_append_val(wdh->interface_data, descr);
2205 descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2206 descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
2207 descr_mand->wtap_encap = encap;
2208 descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
2209 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
2210 descr_mand->snap_len = snaplen;
2211 wtap_optionblock_set_option_string(descr, OPT_IDB_NAME, "Unknown/not available in original file format(libpcap)",
2212 strlen("Unknown/not available in original file format(libpcap)"));
2214 descr_mand->num_stat_entries = 0; /* Number of ISB:s */
2215 descr_mand->interface_statistics = NULL;
2216 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2217 g_array_append_val(wdh->interface_data, descr);
2223 wtap_dump_open(const char *filename, int file_type_subtype, int encap,
2224 int snaplen, gboolean compressed, int *err)
2226 return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2230 wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
2231 int snaplen, gboolean compressed, GArray* shb_hdrs, wtapng_iface_descriptions_t *idb_inf,
2232 GArray* nrb_hdrs, int *err)
2237 /* Allocate and initialize a data structure for the output stream. */
2238 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2239 shb_hdrs, idb_inf, nrb_hdrs, err);
2243 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2244 to a generic "the open failed" error. */
2245 errno = WTAP_ERR_CANT_OPEN;
2246 fh = wtap_dump_file_open(wdh, filename);
2250 return NULL; /* can't create file */
2254 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2255 /* Get rid of the file we created; we couldn't finish
2257 wtap_dump_file_close(wdh);
2258 ws_unlink(filename);
2266 wtap_dump_open_tempfile(char **filenamep, const char *pfx,
2267 int file_type_subtype, int encap,
2268 int snaplen, gboolean compressed, int *err)
2270 return wtap_dump_open_tempfile_ng(filenamep, pfx, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2274 wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
2275 int file_type_subtype, int encap,
2276 int snaplen, gboolean compressed,
2278 wtapng_iface_descriptions_t *idb_inf,
2279 GArray* nrb_hdrs, int *err)
2286 /* No path name for the temporary file yet. */
2289 /* Allocate and initialize a data structure for the output stream. */
2290 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2291 shb_hdrs, idb_inf, nrb_hdrs, err);
2295 /* Choose a random name for the file */
2296 fd = create_tempfile(&tmpname, pfx, ".pcapng");
2300 return NULL; /* can't create file */
2302 *filenamep = tmpname;
2304 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2305 to a generic "the open failed" error. */
2306 errno = WTAP_ERR_CANT_OPEN;
2307 fh = wtap_dump_file_fdopen(wdh, fd);
2312 return NULL; /* can't create file */
2316 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2317 /* Get rid of the file we created; we couldn't finish
2319 wtap_dump_file_close(wdh);
2328 wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
2329 gboolean compressed, int *err)
2331 return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2335 wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
2336 gboolean compressed, GArray* shb_hdrs, wtapng_iface_descriptions_t *idb_inf,
2337 GArray* nrb_hdrs, int *err)
2342 /* Allocate and initialize a data structure for the output stream. */
2343 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2344 shb_hdrs, idb_inf, nrb_hdrs, err);
2348 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2349 to a generic "the open failed" error. */
2350 errno = WTAP_ERR_CANT_OPEN;
2351 fh = wtap_dump_file_fdopen(wdh, fd);
2355 return NULL; /* can't create standard I/O stream */
2359 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2360 wtap_dump_file_close(wdh);
2368 wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
2369 gboolean compressed, int *err)
2371 return wtap_dump_open_stdout_ng(file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2375 wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
2376 gboolean compressed, GArray* shb_hdrs,
2377 wtapng_iface_descriptions_t *idb_inf,
2378 GArray* nrb_hdrs, int *err)
2383 /* Allocate and initialize a data structure for the output stream. */
2384 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2385 shb_hdrs, idb_inf, nrb_hdrs, err);
2391 * Put the standard output into binary mode.
2393 * XXX - even if the file format we're writing is a text
2396 if (_setmode(1, O_BINARY) == -1) {
2397 /* "Should not happen" */
2400 return NULL; /* couldn't put standard output in binary mode */
2404 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2405 to a generic "the open failed" error. */
2406 errno = WTAP_ERR_CANT_OPEN;
2407 fh = wtap_dump_file_fdopen(wdh, 1);
2411 return NULL; /* can't create standard I/O stream */
2414 wdh->is_stdout = TRUE;
2416 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2417 wtap_dump_file_close(wdh);
2425 wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
2427 if (!wtap_dump_can_open(file_type_subtype)) {
2428 /* Invalid type, or type we don't know how to write. */
2429 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2433 /* OK, we know how to write that type; can we write the specified
2434 encapsulation type? */
2435 *err = (*dump_open_table[file_type_subtype].can_write_encap)(encap);
2436 /* if the err said to check wslua's can_write_encap, try that */
2437 if (*err == WTAP_ERR_CHECK_WSLUA
2438 && dump_open_table[file_type_subtype].wslua_info != NULL
2439 && dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap != NULL) {
2441 *err = (*dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[file_type_subtype].wslua_info->wslua_data);
2448 /* if compression is wanted, do we support this for this file_type_subtype? */
2449 if(compressed && !wtap_dump_can_compress(file_type_subtype)) {
2450 *err = WTAP_ERR_COMPRESSION_NOT_SUPPORTED;
2454 /* All systems go! */
2458 static wtap_dumper *
2459 wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean compressed, int *err)
2463 wdh = (wtap_dumper *)g_malloc0(sizeof (wtap_dumper));
2469 wdh->file_type_subtype = file_type_subtype;
2470 wdh->snaplen = snaplen;
2472 wdh->compressed = compressed;
2473 wdh->wslua_data = NULL;
2478 wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
2483 /* Can we do a seek on the file descriptor?
2484 If not, note that fact. */
2488 fd = ws_fileno((FILE *)wdh->fh);
2489 if (ws_lseek64(fd, 1, SEEK_CUR) == (off_t) -1)
2492 /* Undo the seek. */
2493 ws_lseek64(fd, 0, SEEK_SET);
2498 /* If this file type requires seeking, and we can't seek, fail. */
2499 if (dump_open_table[file_type_subtype].writing_must_seek && cant_seek) {
2500 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
2504 /* Set wdh with wslua data if any - this is how we pass the data
2505 * to the file writer.
2507 if (dump_open_table[file_type_subtype].wslua_info)
2508 wdh->wslua_data = dump_open_table[file_type_subtype].wslua_info->wslua_data;
2510 /* Now try to open the file for writing. */
2511 if (!(*dump_open_table[file_type_subtype].dump_open)(wdh, err)) {
2515 return TRUE; /* success! */
2519 wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2520 const guint8 *pd, int *err, gchar **err_info)
2524 return (wdh->subtype_write)(wdh, phdr, pd, err, err_info);
2528 wtap_dump_flush(wtap_dumper *wdh)
2531 if(wdh->compressed) {
2532 gzwfile_flush((GZWFILE_T)wdh->fh);
2536 fflush((FILE *)wdh->fh);
2541 wtap_dump_close(wtap_dumper *wdh, int *err)
2543 gboolean ret = TRUE;
2545 if (wdh->subtype_finish != NULL) {
2546 /* There's a finish routine for this dump stream. */
2547 if (!(wdh->subtype_finish)(wdh, err))
2550 errno = WTAP_ERR_CANT_CLOSE;
2551 if (wtap_dump_file_close(wdh) == EOF) {
2553 /* The per-format finish function succeeded,
2554 but the stream close didn't. Save the
2555 reason why, if our caller asked for it. */
2561 if (wdh->priv != NULL)
2568 wtap_get_bytes_dumped(wtap_dumper *wdh)
2570 return wdh->bytes_dumped;
2574 wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
2576 wdh->bytes_dumped = bytes_dumped;
2580 wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
2582 if (!wdh || wdh->file_type_subtype < 0 || wdh->file_type_subtype >= wtap_num_file_types_subtypes
2583 || dump_open_table[wdh->file_type_subtype].has_name_resolution == FALSE)
2585 wdh->addrinfo_lists = addrinfo_lists;
2589 /* internally open a file for writing (compressed or not) */
2592 wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
2594 if(wdh->compressed) {
2595 return gzwfile_open(filename);
2597 return ws_fopen(filename, "wb");
2602 wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
2604 return ws_fopen(filename, "wb");
2608 /* internally open a file for writing (compressed or not) */
2611 wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
2613 if(wdh->compressed) {
2614 return gzwfile_fdopen(fd);
2616 return ws_fdopen(fd, "wb");
2621 wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
2623 return ws_fdopen(fd, "wb");
2627 /* internally writing raw bytes (compressed or not) */
2629 wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize, int *err)
2634 if (wdh->compressed) {
2635 nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned int) bufsize);
2637 * gzwfile_write() returns 0 on error.
2639 if (nwritten == 0) {
2640 *err = gzwfile_geterr((GZWFILE_T)wdh->fh);
2646 errno = WTAP_ERR_CANT_WRITE;
2647 nwritten = fwrite(buf, 1, bufsize, (FILE *)wdh->fh);
2649 * At least according to the Mac OS X man page,
2650 * this can return a short count on an error.
2652 if (nwritten != bufsize) {
2653 if (ferror((FILE *)wdh->fh))
2656 *err = WTAP_ERR_SHORT_WRITE;
2663 /* internally close a file for writing (compressed or not) */
2665 wtap_dump_file_close(wtap_dumper *wdh)
2668 if(wdh->compressed) {
2670 * Tell gzwfile_close() whether to close the descriptor
2673 return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout);
2678 * Don't close the standard output.
2680 * XXX - this really should do everything fclose() does,
2681 * including freeing all allocated data structures,
2682 * *except* for actually closing the file descriptor.
2684 return wdh->is_stdout ? fflush((FILE *)wdh->fh) : fclose((FILE *)wdh->fh);
2689 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
2692 if(wdh->compressed) {
2693 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2698 if (-1 == fseek((FILE *)wdh->fh, (long)offset, whence)) {
2709 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
2713 if(wdh->compressed) {
2714 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2719 if (-1 == (rval = ftell((FILE *)wdh->fh))) {
2730 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2735 * indent-tabs-mode: t
2738 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2739 * :indentSize=8:tabSize=8:noTabs=false: