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"
88 * Add an extension, and all compressed versions thereof, to a GSList
92 add_extensions(GSList *extensions, const gchar *extension,
93 const char **compressed_file_extensions)
95 const char **compressed_file_extensionp;
98 * Add the specified extension.
100 extensions = g_slist_append(extensions, g_strdup(extension));
103 * Now add the extensions for compressed-file versions of
106 for (compressed_file_extensionp = compressed_file_extensions;
107 *compressed_file_extensionp != NULL;
108 compressed_file_extensionp++) {
109 extensions = g_slist_append(extensions,
110 g_strdup_printf("%s.%s", extension,
111 *compressed_file_extensionp));
118 * File types that can be identified by file extensions.
120 * These are used in file open dialogs to offer choices of extensions
121 * for which to filter. Note that the first field can list more than
122 * one type of file, because, for example, ".cap" is a popular
123 * extension used by a number of capture file types.
125 static const struct file_extension_info file_type_extensions_base[] = {
126 { "Wireshark/tcpdump/... - pcap", "pcap;cap;dmp" },
127 { "Wireshark/... - pcapng", "pcapng;ntar" },
128 { "Network Monitor, Surveyor, NetScaler", "cap" },
129 { "InfoVista 5View capture", "5vw" },
130 { "Sniffer (DOS)", "cap;enc;trc;fdc;syc" },
131 { "Cinco NetXRay, Sniffer (Windows)", "cap;caz" },
132 { "Endace ERF capture", "erf" },
133 { "EyeSDN USB S0/E1 ISDN trace format", "trc" },
134 { "HP-UX nettl trace", "trc0;trc1" },
135 { "Network Instruments Observer", "bfr" },
136 { "Colasoft Capsa", "cscpkt" },
137 { "Novell LANalyzer", "tr1" },
138 { "Tektronix K12xx 32-bit .rf5 format", "rf5" },
139 { "Savvius *Peek", "pkt;tpc;apc;wpz" },
140 { "Catapult DCT2000 trace (.out format)", "out" },
141 { "MPEG files", "mpg;mp3" },
142 { "TamoSoft CommView", "ncf" },
143 { "Symbian OS btsnoop", "log" },
144 { "Transport-Neutral Encapsulation Format", "tnef" },
145 { "XML files (including Gammu DCT3 traces)", "xml" },
146 { "OS X PacketLogger", "pklg" },
147 { "Daintree SNA", "dcf" },
148 { "JPEG/JFIF files", "jpg;jpeg;jfif" },
149 { "IPFIX File Format", "pfx;ipfix" },
150 { "Aethra .aps file", "aps" },
151 { "MPEG2 transport stream", "mp2t;ts;mpg" },
152 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr" },
153 { "CAM Inspector file", "camins" },
154 { "JavaScript Object Notation file", "json" }
157 #define N_FILE_TYPE_EXTENSIONS (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
159 static const struct file_extension_info* file_type_extensions = NULL;
161 static GArray* file_type_extensions_arr = NULL;
163 /* initialize the extensions array if it has not been initialized yet */
165 init_file_type_extensions(void)
168 if (file_type_extensions_arr) return;
170 file_type_extensions_arr = g_array_new(FALSE,TRUE,sizeof(struct file_extension_info));
172 g_array_append_vals(file_type_extensions_arr,file_type_extensions_base,N_FILE_TYPE_EXTENSIONS);
174 file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
178 wtap_register_file_type_extension(const struct file_extension_info *ei)
180 init_file_type_extensions();
182 g_array_append_val(file_type_extensions_arr,*ei);
184 file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
188 wtap_get_num_file_type_extensions(void)
190 return file_type_extensions_arr->len;
194 wtap_get_file_extension_type_name(int extension_type)
196 return file_type_extensions[extension_type].name;
200 add_extensions_for_file_extensions_type(int extension_type,
201 GSList *extensions, const char **compressed_file_extensions)
203 gchar **extensions_set, **extensionp, *extension;
206 * Split the extension-list string into a set of extensions.
208 extensions_set = g_strsplit(file_type_extensions[extension_type].extensions,
212 * Add each of those extensions to the list.
214 for (extensionp = extensions_set; *extensionp != NULL; extensionp++) {
215 extension = *extensionp;
218 * Add the extension, and all compressed variants
221 extensions = add_extensions(extensions, extension,
222 compressed_file_extensions);
225 g_strfreev(extensions_set);
229 /* Return a list of file extensions that are used by the specified file
232 All strings in the list are allocated with g_malloc() and must be freed
235 wtap_get_file_extension_type_extensions(guint extension_type)
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 * Add all this file extension type's extensions, with compressed
248 extensions = add_extensions_for_file_extensions_type(extension_type,
249 extensions, compressed_file_extension_table);
254 /* Return a list of all extensions that are used by all file types,
255 including compressed extensions, e.g. not just "pcap" but also
256 "pcap.gz" if we can read gzipped files.
258 All strings in the list are allocated with g_malloc() and must be freed
261 wtap_get_all_file_extensions_list(void)
266 init_file_type_extensions();
268 extensions = NULL; /* empty list, to start with */
270 for (i = 0; i < file_type_extensions_arr->len; i++) {
272 * Add all this file extension type's extensions, with
273 * compressed variants.
275 extensions = add_extensions_for_file_extensions_type(i,
276 extensions, compressed_file_extension_table);
283 * The open_file_* routines should return:
285 * -1 on an I/O error;
287 * 1 if the file they're reading is one of the types it handles;
289 * 0 if the file they're reading isn't the type they're checking for.
291 * If the routine handles this type of file, it should set the "file_type"
292 * field in the "struct wtap" to the type of the file.
294 * Note that the routine does not have to free the private data pointer on
295 * error. The caller takes care of that by calling wtap_close on error.
296 * (See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8518)
298 * However, the caller does have to free the private data pointer when
299 * returning 0, since the next file type will be called and will likely
300 * just overwrite the pointer.
302 * The names are used in file open dialogs to select, for files that
303 * don't have magic numbers and that could potentially be files of
304 * more than one type based on the heuristics, a particular file
305 * type to interpret it as, if the file name has no extension, the
306 * extension isn't sufficient to determine the appropriate file type,
307 * or the extension is wrong.
309 static struct open_info open_info_base[] = {
310 { "Wireshark/tcpdump/... - pcap", OPEN_INFO_MAGIC, libpcap_open, "pcap", NULL, NULL },
311 { "Wireshark/... - pcapng", OPEN_INFO_MAGIC, pcapng_open, "pcapng", NULL, NULL },
312 { "Sniffer (DOS)", OPEN_INFO_MAGIC, ngsniffer_open, NULL, NULL, NULL },
313 { "Snoop, Shomiti/Finisar Surveyor", OPEN_INFO_MAGIC, snoop_open, NULL, NULL, NULL },
314 { "AIX iptrace", OPEN_INFO_MAGIC, iptrace_open, NULL, NULL, NULL },
315 { "Microsoft Network Monitor", OPEN_INFO_MAGIC, netmon_open, NULL, NULL, NULL },
316 { "Cinco NetXray/Sniffer (Windows)", OPEN_INFO_MAGIC, netxray_open, NULL, NULL, NULL },
317 { "RADCOM WAN/LAN analyzer", OPEN_INFO_MAGIC, radcom_open, NULL, NULL, NULL },
318 { "HP-UX nettl trace", OPEN_INFO_MAGIC, nettl_open, NULL, NULL, NULL },
319 { "Visual Networks traffic capture", OPEN_INFO_MAGIC, visual_open, NULL, NULL, NULL },
320 { "InfoVista 5View capture", OPEN_INFO_MAGIC, _5views_open, NULL, NULL, NULL },
321 { "Network Instruments Observer", OPEN_INFO_MAGIC, network_instruments_open, NULL, NULL, NULL },
322 { "Savvius tagged", OPEN_INFO_MAGIC, peektagged_open, NULL, NULL, NULL },
323 { "Colasoft Capsa", OPEN_INFO_MAGIC, capsa_open, NULL, NULL, NULL },
324 { "DBS Etherwatch (VMS)", OPEN_INFO_MAGIC, dbs_etherwatch_open, NULL, NULL, NULL },
325 { "Tektronix K12xx 32-bit .rf5 format", OPEN_INFO_MAGIC, k12_open, NULL, NULL, NULL },
326 { "Catapult DCT2000 trace (.out format)", OPEN_INFO_MAGIC, catapult_dct2000_open, NULL, NULL, NULL },
327 { "Aethra .aps file", OPEN_INFO_MAGIC, aethra_open, NULL, NULL, NULL },
328 { "Symbian OS btsnoop", OPEN_INFO_MAGIC, btsnoop_open, "log", NULL, NULL },
329 { "EyeSDN USB S0/E1 ISDN trace format", OPEN_INFO_MAGIC, eyesdn_open, NULL, NULL, NULL },
330 { "Transport-Neutral Encapsulation Format", OPEN_INFO_MAGIC, tnef_open, NULL, NULL, NULL },
331 /* 3GPP TS 32.423 Trace must come before MIME Files as it's XML based*/
332 { "3GPP TS 32.423 Trace format", OPEN_INFO_MAGIC, nettrace_3gpp_32_423_file_open, NULL, NULL, NULL },
333 /* Gammu DCT3 trace must come before MIME files as it's XML based*/
334 { "Gammu DCT3 trace", OPEN_INFO_MAGIC, dct3trace_open, NULL, NULL, NULL },
335 { "MIME Files Format", OPEN_INFO_MAGIC, mime_file_open, NULL, NULL, NULL },
336 { "Novell LANalyzer", OPEN_INFO_HEURISTIC, lanalyzer_open, "tr1", NULL, NULL },
338 * PacketLogger must come before MPEG, because its files
339 * are sometimes grabbed by mpeg_open.
341 { "OS X PacketLogger", OPEN_INFO_HEURISTIC, packetlogger_open, "pklg", NULL, NULL },
342 /* Some MPEG files have magic numbers, others just have heuristics. */
343 { "MPEG", OPEN_INFO_HEURISTIC, mpeg_open, "mpg;mp3", NULL, NULL },
344 { "Daintree SNA", OPEN_INFO_HEURISTIC, daintree_sna_open, "dcf", NULL, NULL },
345 { "STANAG 4607 Format", OPEN_INFO_HEURISTIC, stanag4607_open, NULL, NULL, NULL },
346 { "ASN.1 Basic Encoding Rules", OPEN_INFO_HEURISTIC, ber_open, NULL, NULL, NULL },
348 * I put NetScreen *before* erf, because there were some
349 * false positives with my test-files (Sake Blok, July 2007)
351 * I put VWR *after* ERF, because there were some cases where
352 * ERF files were misidentified as vwr files (Stephen
353 * Donnelly, August 2013; see bug 9054)
355 * I put VWR *after* Peek Classic, CommView, iSeries text,
356 * Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
357 * because there were some cases where files of those types were
358 * misidentified as vwr files (Guy Harris, December 2013)
360 { "NetScreen snoop text file", OPEN_INFO_HEURISTIC, netscreen_open, "txt", NULL, NULL },
361 { "Endace ERF capture", OPEN_INFO_HEURISTIC, erf_open, "erf", NULL, NULL },
362 { "IPFIX File Format", OPEN_INFO_HEURISTIC, ipfix_open, "pfx;ipfix",NULL, NULL },
363 { "K12 text file", OPEN_INFO_HEURISTIC, k12text_open, "txt", NULL, NULL },
364 { "Savvius classic", OPEN_INFO_HEURISTIC, peekclassic_open, "pkt;tpc;apc;wpz", NULL, NULL },
365 { "pppd log (pppdump format)", OPEN_INFO_HEURISTIC, pppdump_open, NULL, NULL, NULL },
366 { "IBM iSeries comm. trace", OPEN_INFO_HEURISTIC, iseries_open, "txt", NULL, NULL },
367 { "I4B ISDN trace", OPEN_INFO_HEURISTIC, i4btrace_open, NULL, NULL, NULL },
368 { "MPEG2 transport stream", OPEN_INFO_HEURISTIC, mp2t_open, "ts;mpg", NULL, NULL },
369 { "CSIDS IPLog", OPEN_INFO_HEURISTIC, csids_open, NULL, NULL, NULL },
370 { "TCPIPtrace (VMS)", OPEN_INFO_HEURISTIC, vms_open, "txt", NULL, NULL },
371 { "CoSine IPSX L2 capture", OPEN_INFO_HEURISTIC, cosine_open, "txt", NULL, NULL },
372 { "Bluetooth HCI dump", OPEN_INFO_HEURISTIC, hcidump_open, NULL, NULL, NULL },
373 { "TamoSoft CommView", OPEN_INFO_HEURISTIC, commview_open, "ncf", NULL, NULL },
374 { "NetScaler", OPEN_INFO_HEURISTIC, nstrace_open, "cap", NULL, NULL },
375 { "Android Logcat Binary format", OPEN_INFO_HEURISTIC, logcat_open, "logcat", NULL, NULL },
376 { "Android Logcat Text formats", OPEN_INFO_HEURISTIC, logcat_text_open, "txt", NULL, NULL },
377 /* ASCII trace files from Telnet sessions. */
378 { "Lucent/Ascend access server trace", OPEN_INFO_HEURISTIC, ascend_open, "txt", NULL, NULL },
379 { "Toshiba Compact ISDN Router snoop", OPEN_INFO_HEURISTIC, toshiba_open, "txt", NULL, NULL },
380 /* Extremely weak heuristics - put them at the end. */
381 { "Ixia IxVeriWave .vwr Raw Capture", OPEN_INFO_HEURISTIC, vwr_open, "vwr", NULL, NULL },
382 { "CAM Inspector file", OPEN_INFO_HEURISTIC, camins_open, "camins", NULL, NULL },
383 { "JavaScript Object Notation", OPEN_INFO_HEURISTIC, json_open, "json", NULL, NULL }
386 /* this is only used to build the dynamic array on load, do NOT use this
387 * for anything else, because the size of the actual array will change if
388 * Lua scripts register a new file reader.
390 #define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
392 static GArray *open_info_arr = NULL;
394 /* this always points to the top of the created array */
395 struct open_info *open_routines = NULL;
397 /* this points to the first OPEN_INFO_HEURISTIC type in the array */
398 static guint heuristic_open_routine_idx = 0;
401 set_heuristic_routine(void)
404 g_assert(open_info_arr != NULL);
406 for (i = 0; i < open_info_arr->len; i++) {
407 if (open_routines[i].type == OPEN_INFO_HEURISTIC) {
408 heuristic_open_routine_idx = i;
412 g_assert(open_routines[i].type == OPEN_INFO_MAGIC);
415 g_assert(heuristic_open_routine_idx > 0);
419 init_open_routines(void)
422 struct open_info *i_open;
427 open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
429 g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
431 open_routines = (struct open_info *)(void*) open_info_arr->data;
433 /* Populate the extensions_set list now */
434 for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
435 if (i_open->extensions != NULL)
436 i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
439 set_heuristic_routine();
443 * Registers a new file reader - currently only called by wslua code for Lua readers.
444 * If first_routine is true, it's added before other readers of its type (magic or heuristic).
445 * Also, it checks for an existing reader of the same name and errors if it finds one; if
446 * you want to handle that condition more gracefully, call wtap_has_open_info() first.
449 wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
451 init_open_routines();
453 if (!oi || !oi->name) {
454 g_error("No open_info name given to register");
458 /* verify name doesn't already exist */
459 if (wtap_has_open_info(oi->name)) {
460 g_error("Name given to register_open_info already exists");
464 if (oi->extensions != NULL)
465 oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
467 /* if it's magic and first, prepend it; if it's heuristic and not first,
468 append it; if it's anything else, stick it in the middle */
469 if (first_routine && oi->type == OPEN_INFO_MAGIC) {
470 g_array_prepend_val(open_info_arr, *oi);
471 } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
472 g_array_append_val(open_info_arr, *oi);
474 g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
477 open_routines = (struct open_info *)(void*) open_info_arr->data;
478 set_heuristic_routine();
481 /* De-registers a file reader by removign it from the GArray based on its name.
482 * This function must NOT be called during wtap_open_offline(), since it changes the array.
483 * Note: this function will error if it doesn't find the given name; if you want to handle
484 * that condition more gracefully, call wtap_has_open_info() first.
487 wtap_deregister_open_info(const gchar *name)
490 init_open_routines();
493 g_error("Missing open_info name to de-register");
497 for (i = 0; i < open_info_arr->len; i++) {
498 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
499 if (open_routines[i].extensions_set != NULL)
500 g_strfreev(open_routines[i].extensions_set);
501 open_info_arr = g_array_remove_index(open_info_arr, i);
502 set_heuristic_routine();
507 g_error("deregister_open_info: name not found");
510 /* Determines if a open routine short name already exists
513 wtap_has_open_info(const gchar *name)
516 init_open_routines();
519 g_error("No name given to wtap_has_open_info!");
524 for (i = 0; i < open_info_arr->len; i++) {
525 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
534 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
535 * define them either.)
537 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
540 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
543 #define S_IFIFO _S_IFIFO
546 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
549 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
552 /* returns the 'type' number to use for wtap_open_offline based on the
553 passed-in name (the name in the open_info struct). It returns WTAP_TYPE_AUTO
554 on failure, which is the number 0. The 'type' number is the entry's index+1,
555 because that's what wtap_open_offline() expects it to be. */
557 open_info_name_to_type(const char *name)
560 init_open_routines();
563 return WTAP_TYPE_AUTO;
565 for (i = 0; i < open_info_arr->len; i++) {
566 if (open_routines[i].name != NULL &&
567 strcmp(name, open_routines[i].name) == 0)
571 return WTAP_TYPE_AUTO; /* no such file type */
575 get_file_extension(const char *pathname)
580 const char **compressed_file_extensionp;
584 * Is the pathname empty?
586 if (strcmp(pathname, "") == 0)
587 return NULL; /* no extension */
590 * Find the last component of the pathname.
592 filename = g_path_get_basename(pathname);
595 * Does it have an extension?
597 if (strchr(filename, '.') == NULL) {
599 return NULL; /* no extension whatsoever */
603 * Yes. Split it into components separated by ".".
605 components = g_strsplit(filename, ".", 0);
609 * Count the components.
611 for (ncomponents = 0; components[ncomponents] != NULL; ncomponents++)
614 if (ncomponents == 0) {
615 g_strfreev(components);
616 return NULL; /* no components */
618 if (ncomponents == 1) {
619 g_strfreev(components);
620 return NULL; /* only one component, with no "." */
624 * Is the last component one of the extensions used for compressed
627 extensionp = components[ncomponents - 1];
628 for (compressed_file_extensionp = compressed_file_extension_table;
629 *compressed_file_extensionp != NULL;
630 compressed_file_extensionp++) {
631 if (strcmp(extensionp, *compressed_file_extensionp) == 0) {
633 * Yes, it's one of the compressed-file extensions.
634 * Is there an extension before that?
636 if (ncomponents == 2) {
637 g_strfreev(components);
638 return NULL; /* no, only two components */
642 * Yes, return that extension.
644 extensionp = g_strdup(components[ncomponents - 2]);
645 g_strfreev(components);
651 * The extension isn't one of the compressed-file extensions;
654 extensionp = g_strdup(extensionp);
655 g_strfreev(components);
660 * Check if file extension is used in this heuristic
663 heuristic_uses_extension(unsigned int i, const char *extension)
668 * Does this file type *have* any extensions?
670 if (open_routines[i].extensions == NULL)
671 return FALSE; /* no */
674 * Check each of them against the specified extension.
676 for (extensionp = open_routines[i].extensions_set; *extensionp != NULL;
678 if (strcmp(extension, *extensionp) == 0) {
679 return TRUE; /* it's one of them */
683 return FALSE; /* it's not one of them */
686 /* Opens a file and prepares a wtap struct.
687 If "do_random" is TRUE, it opens the file twice; the second open
688 allows the application to do random-access I/O without moving
689 the seek offset for sequential I/O, which is used by Wireshark
690 so that it can do sequential I/O to a capture file that's being
691 written to as new packets arrive independently of random I/O done
692 to display protocol trees for packets when they're selected. */
694 wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
701 gboolean use_stdin = FALSE;
707 init_open_routines();
709 /* open standard input if filename is '-' */
710 if (strcmp(filename, "-") == 0)
713 /* First, make sure the file is valid */
715 if (ws_fstat64(0, &statb) < 0) {
720 if (ws_stat64(filename, &statb) < 0) {
725 if (S_ISFIFO(statb.st_mode)) {
727 * Opens of FIFOs are allowed only when not opening
730 * Currently, we do seeking when trying to find out
731 * the file type, but our I/O routines do some amount
732 * of buffering, and do backward seeks within the buffer
733 * if possible, so at least some file types can be
734 * opened from pipes, so we don't completely disallow opens
738 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
741 } else if (S_ISDIR(statb.st_mode)) {
743 * Return different errors for "this is a directory"
744 * and "this is some random special file type", so
745 * the user can get a potentially more helpful error.
749 } else if (! S_ISREG(statb.st_mode)) {
750 *err = WTAP_ERR_NOT_REGULAR_FILE;
755 * We need two independent descriptors for random access, so
756 * they have different file positions. If we're opening the
757 * standard input, we can only dup it to get additional
758 * descriptors, so we can't have two independent descriptors,
759 * and thus can't do random access.
761 if (use_stdin && do_random) {
762 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
767 wth = (wtap *)g_malloc0(sizeof(wtap));
770 errno = WTAP_ERR_CANT_OPEN;
773 * We dup FD 0, so that we don't have to worry about
774 * a file_close of wth->fh closing the standard
775 * input of the process.
784 if (_setmode(fd, O_BINARY) == -1) {
785 /* "Shouldn't happen" */
791 if (!(wth->fh = file_fdopen(fd))) {
798 if (!(wth->fh = file_open(filename))) {
806 if (!(wth->random_fh = file_open(filename))) {
813 wth->random_fh = NULL;
816 wth->file_encap = WTAP_ENCAP_UNKNOWN;
817 wth->subtype_sequential_close = NULL;
818 wth->subtype_close = NULL;
819 wth->file_tsprec = WTAP_TSPREC_USEC;
821 wth->wslua_data = NULL;
822 wth->shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
824 /* Initialize the array containing a list of interfaces. pcapng_open and
825 * erf_open needs this (and libpcap_open for ERF encapsulation types).
826 * Always initing it here saves checking for a NULL ptr later. */
827 wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
829 if (wth->random_fh) {
830 wth->fast_seek = g_ptr_array_new();
832 file_set_random_access(wth->fh, FALSE, wth->fast_seek);
833 file_set_random_access(wth->random_fh, TRUE, wth->fast_seek);
836 /* 'type' is 1 greater than the array index */
837 if (type != WTAP_TYPE_AUTO && type <= open_info_arr->len) {
840 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
841 /* I/O error - give up */
846 /* Set wth with wslua data if any - this is how we pass the data
847 * to the file reader, kinda like the priv member but not free'd later.
848 * It's ok for this to copy a NULL.
850 wth->wslua_data = open_routines[type - 1].wslua_data;
852 result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
855 case WTAP_OPEN_ERROR:
856 /* Error - give up */
860 case WTAP_OPEN_NOT_MINE:
861 /* No error, but not that type of file */
865 /* We found the file type */
870 /* Try all file types that support magic numbers */
871 for (i = 0; i < heuristic_open_routine_idx; i++) {
872 /* Seek back to the beginning of the file; the open routine
873 for the previous file type may have left the file
874 position somewhere other than the beginning, and the
875 open routine for this file type will probably want
876 to start reading at the beginning.
878 Initialize the data offset while we're at it. */
879 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
880 /* Error - give up */
885 /* Set wth with wslua data if any - this is how we pass the data
886 * to the file reader, kinda like the priv member but not free'd later.
887 * It's ok for this to copy a NULL.
889 wth->wslua_data = open_routines[i].wslua_data;
891 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
893 case WTAP_OPEN_ERROR:
894 /* Error - give up */
898 case WTAP_OPEN_NOT_MINE:
899 /* No error, but not that type of file */
903 /* We found the file type */
909 /* Does this file's name have an extension? */
910 extension = get_file_extension(filename);
911 if (extension != NULL) {
912 /* Yes - try the heuristic types that use that extension first. */
913 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
914 /* Does this type use that extension? */
915 if (heuristic_uses_extension(i, extension)) {
917 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
918 /* Error - give up */
924 /* Set wth with wslua data if any - this is how we pass the data
925 * to the file reader, kind of like priv but not free'd later.
927 wth->wslua_data = open_routines[i].wslua_data;
929 switch ((*open_routines[i].open_routine)(wth,
932 case WTAP_OPEN_ERROR:
933 /* Error - give up */
938 case WTAP_OPEN_NOT_MINE:
939 /* No error, but not that type of file */
943 /* We found the file type */
951 * Now try the heuristic types that have no extensions
952 * to check; we try those before the ones that have
953 * extensions that *don't* match this file's extension,
954 * on the theory that files of those types generally
955 * have one of the type's extensions, and, as this file
956 * *doesn't* have one of those extensions, it's probably
957 * *not* one of those files.
959 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
960 /* Does this type have any extensions? */
961 if (open_routines[i].extensions == NULL) {
963 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
964 /* Error - give up */
970 /* Set wth with wslua data if any - this is how we pass the data
971 * to the file reader, kind of like priv but not free'd later.
973 wth->wslua_data = open_routines[i].wslua_data;
975 switch ((*open_routines[i].open_routine)(wth,
978 case WTAP_OPEN_ERROR:
979 /* Error - give up */
984 case WTAP_OPEN_NOT_MINE:
985 /* No error, but not that type of file */
989 /* We found the file type */
997 * Now try the ones that have extensions where none of
998 * them matches this file's extensions.
1000 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1002 * Does this type have extensions and is this file's
1003 * extension one of them?
1005 if (open_routines[i].extensions != NULL &&
1006 !heuristic_uses_extension(i, extension)) {
1008 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1009 /* Error - give up */
1015 /* Set wth with wslua data if any - this is how we pass the data
1016 * to the file reader, kind of like priv but not free'd later.
1018 wth->wslua_data = open_routines[i].wslua_data;
1020 switch ((*open_routines[i].open_routine)(wth,
1023 case WTAP_OPEN_ERROR:
1024 /* Error - give up */
1029 case WTAP_OPEN_NOT_MINE:
1030 /* No error, but not that type of file */
1033 case WTAP_OPEN_MINE:
1034 /* We found the file type */
1042 /* No - try all the heuristics types in order. */
1043 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1045 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1046 /* Error - give up */
1051 /* Set wth with wslua data if any - this is how we pass the data
1052 * to the file reader, kind of like priv but not free'd later.
1054 wth->wslua_data = open_routines[i].wslua_data;
1056 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
1058 case WTAP_OPEN_ERROR:
1059 /* Error - give up */
1063 case WTAP_OPEN_NOT_MINE:
1064 /* No error, but not that type of file */
1067 case WTAP_OPEN_MINE:
1068 /* We found the file type */
1076 /* Well, it's not one of the types of file we know about. */
1078 *err = WTAP_ERR_FILE_UNKNOWN_FORMAT;
1082 wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
1083 ws_buffer_init(wth->frame_buffer, 1500);
1085 if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
1086 (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
1088 wtap_optionblock_t descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
1089 wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
1091 descr_mand->wtap_encap = wth->file_encap;
1092 if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
1093 descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */
1094 wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9);
1095 descr_mand->tsprecision = WTAP_TSPREC_NSEC;
1097 descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
1098 wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6);
1099 descr_mand->tsprecision = WTAP_TSPREC_USEC;
1101 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
1102 descr_mand->snap_len = wth->snapshot_length;
1104 descr_mand->num_stat_entries = 0; /* Number of ISB:s */
1105 descr_mand->interface_statistics = NULL;
1106 g_array_append_val(wth->interface_data, descr);
1113 * Given the pathname of the file we just closed with wtap_fdclose(), attempt
1114 * to reopen that file and assign the new file descriptor(s) to the sequential
1115 * stream and, if do_random is TRUE, to the random stream. Used on Windows
1116 * after the rename of a file we had open was done or if the rename of a
1117 * file on top of a file we had open failed.
1119 * This is only required by Wireshark, not TShark, and, at the point that
1120 * Wireshark is doing this, the sequential stream is closed, and the
1121 * random stream is open, so this refuses to open pipes, and only
1122 * reopens the random stream.
1125 wtap_fdreopen(wtap *wth, const char *filename, int *err)
1130 * We need two independent descriptors for random access, so
1131 * they have different file positions. If we're opening the
1132 * standard input, we can only dup it to get additional
1133 * descriptors, so we can't have two independent descriptors,
1134 * and thus can't do random access.
1136 if (strcmp(filename, "-") == 0) {
1137 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
1141 /* First, make sure the file is valid */
1142 if (ws_stat64(filename, &statb) < 0) {
1146 if (S_ISFIFO(statb.st_mode)) {
1148 * Opens of FIFOs are not allowed; see above.
1150 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
1152 } else if (S_ISDIR(statb.st_mode)) {
1154 * Return different errors for "this is a directory"
1155 * and "this is some random special file type", so
1156 * the user can get a potentially more helpful error.
1160 } else if (! S_ISREG(statb.st_mode)) {
1161 *err = WTAP_ERR_NOT_REGULAR_FILE;
1166 errno = WTAP_ERR_CANT_OPEN;
1167 if (!file_fdreopen(wth->random_fh, filename)) {
1174 /* Table of the file types and subtypes for which we have built-in support.
1175 Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending
1178 These are used to report what type and subtype a given file is and
1179 to let the user select a format when writing out packets.
1181 This table is what we start with, but it can be modified.
1182 If we need to modify it, we allocate a GArray, copy the entries
1183 in the above table to that GArray, use the copy as the table, and
1184 make all changes to the copy. */
1185 static const struct file_type_subtype_info dump_open_table_base[] = {
1186 /* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN (only used internally for initialization) */
1187 { NULL, NULL, NULL, NULL,
1191 /* WTAP_FILE_TYPE_SUBTYPE_PCAP */
1192 /* Gianluca Varenni suggests that we add "deprecated" to the description. */
1193 { "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp",
1195 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1197 /* WTAP_FILE_TYPE_SUBTYPE_PCAPNG */
1198 { "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
1199 FALSE, TRUE, WTAP_COMMENT_PER_SECTION|WTAP_COMMENT_PER_INTERFACE|WTAP_COMMENT_PER_PACKET,
1200 pcapng_dump_can_write_encap, pcapng_dump_open, NULL },
1202 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC */
1203 { "Wireshark - nanosecond libpcap", "nseclibpcap", "pcap", "cap;dmp",
1205 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1207 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX */
1208 { "AIX tcpdump - libpcap", "aixlibpcap", "pcap", "cap;dmp",
1212 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029 */
1213 { "Modified tcpdump - libpcap", "modlibpcap", "pcap", "cap;dmp",
1215 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1217 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA */
1218 { "Nokia tcpdump - libpcap ", "nokialibpcap", "pcap", "cap;dmp",
1220 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1222 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417 */
1223 { "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "pcap", "cap;dmp",
1225 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1227 /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915 */
1228 { "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "pcap", "cap;dmp",
1230 libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1232 /* WTAP_FILE_TYPE_SUBTYPE_5VIEWS */
1233 { "InfoVista 5View capture", "5views", "5vw", NULL,
1235 _5views_dump_can_write_encap, _5views_dump_open, NULL },
1237 /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_1_0 */
1238 { "AIX iptrace 1.0", "iptrace_1", NULL, NULL,
1242 /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_2_0 */
1243 { "AIX iptrace 2.0", "iptrace_2", NULL, NULL,
1247 /* WTAP_FILE_TYPE_SUBTYPE_BER */
1248 { "ASN.1 Basic Encoding Rules", "ber", NULL, NULL,
1252 /* WTAP_FILE_TYPE_SUBTYPE_HCIDUMP */
1253 { "Bluetooth HCI dump", "hcidump", NULL, NULL,
1257 /* WTAP_FILE_TYPE_SUBTYPE_CATAPULT_DCT2000 */
1258 { "Catapult DCT2000 trace (.out format)", "dct2000", "out", NULL,
1260 catapult_dct2000_dump_can_write_encap, catapult_dct2000_dump_open, NULL },
1262 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_OLD */
1263 { "Cinco Networks NetXRay 1.x", "netxray1", "cap", NULL,
1267 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_0 */
1268 { "Cinco Networks NetXRay 2.0 or later", "netxray2", "cap", NULL,
1272 /* WTAP_FILE_TYPE_SUBTYPE_COSINE */
1273 { "CoSine IPSX L2 capture", "cosine", "txt", NULL,
1277 /* WTAP_FILE_TYPE_SUBTYPE_CSIDS */
1278 { "CSIDS IPLog", "csids", NULL, NULL,
1282 /* WTAP_FILE_TYPE_SUBTYPE_DBS_ETHERWATCH */
1283 { "DBS Etherwatch (VMS)", "etherwatch", "txt", NULL,
1287 /* WTAP_FILE_TYPE_SUBTYPE_ERF */
1288 { "Endace ERF capture", "erf", "erf", NULL,
1290 erf_dump_can_write_encap, erf_dump_open, NULL },
1292 /* WTAP_FILE_TYPE_SUBTYPE_EYESDN */
1293 { "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "trc", NULL,
1295 eyesdn_dump_can_write_encap, eyesdn_dump_open, NULL },
1297 /* WTAP_FILE_TYPE_SUBTYPE_NETTL */
1298 { "HP-UX nettl trace", "nettl", "trc0", "trc1",
1300 nettl_dump_can_write_encap, nettl_dump_open, NULL },
1302 /* WTAP_FILE_TYPE_SUBTYPE_ISERIES */
1303 { "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "txt", NULL,
1307 /* WTAP_FILE_TYPE_SUBTYPE_ISERIES_UNICODE */
1308 { "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "txt", NULL,
1312 /* WTAP_FILE_TYPE_SUBTYPE_I4BTRACE */
1313 { "I4B ISDN trace", "i4btrace", NULL, NULL,
1317 /* WTAP_FILE_TYPE_SUBTYPE_ASCEND */
1318 { "Lucent/Ascend access server trace", "ascend", "txt", NULL,
1322 /* WTAP_FILE_TYPE_SUBTYPE_NETMON_1_x */
1323 { "Microsoft NetMon 1.x", "netmon1", "cap", NULL,
1325 netmon_dump_can_write_encap_1_x, netmon_dump_open, NULL },
1327 /* WTAP_FILE_TYPE_SUBTYPE_NETMON_2_x */
1328 { "Microsoft NetMon 2.x", "netmon2", "cap", NULL,
1330 netmon_dump_can_write_encap_2_x, netmon_dump_open, NULL },
1332 /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_UNCOMPRESSED */
1333 { "Sniffer (DOS)", "ngsniffer", "cap", "enc;trc;fdc;syc",
1335 ngsniffer_dump_can_write_encap, ngsniffer_dump_open, NULL },
1337 /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_COMPRESSED */
1338 { "Sniffer (DOS), compressed", "ngsniffer_comp", "cap", "enc;trc;fdc;syc",
1342 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_1 */
1343 { "NetXray, Sniffer (Windows) 1.1", "ngwsniffer_1_1", "cap", NULL,
1345 netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1, NULL },
1347 /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x */
1348 { "Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "cap", "caz",
1350 netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0, NULL },
1352 /* WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS */
1353 { "Network Instruments Observer", "niobserver", "bfr", NULL,
1355 network_instruments_dump_can_write_encap, network_instruments_dump_open, NULL },
1357 /* WTAP_FILE_TYPE_SUBTYPE_LANALYZER */
1358 { "Novell LANalyzer","lanalyzer", "tr1", NULL,
1360 lanalyzer_dump_can_write_encap, lanalyzer_dump_open, NULL },
1362 /* WTAP_FILE_TYPE_SUBTYPE_PPPDUMP */
1363 { "pppd log (pppdump format)", "pppd", NULL, NULL,
1367 /* WTAP_FILE_TYPE_SUBTYPE_RADCOM */
1368 { "RADCOM WAN/LAN analyzer", "radcom", NULL, NULL,
1372 /* WTAP_FILE_TYPE_SUBTYPE_SNOOP */
1373 { "Sun snoop", "snoop", "snoop", "cap",
1375 snoop_dump_can_write_encap, snoop_dump_open, NULL },
1377 /* WTAP_FILE_TYPE_SUBTYPE_SHOMITI */
1378 { "Shomiti/Finisar Surveyor", "shomiti", "cap", NULL,
1382 /* WTAP_FILE_TYPE_SUBTYPE_VMS */
1383 { "TCPIPtrace (VMS)", "tcpiptrace", "txt", NULL,
1387 /* WTAP_FILE_TYPE_SUBTYPE_K12 */
1388 { "Tektronix K12xx 32-bit .rf5 format", "rf5", "rf5", NULL,
1390 k12_dump_can_write_encap, k12_dump_open, NULL },
1392 /* WTAP_FILE_TYPE_SUBTYPE_TOSHIBA */
1393 { "Toshiba Compact ISDN Router snoop", "toshiba", "txt", NULL,
1397 /* WTAP_FILE_TYPE_SUBTYPE_VISUAL_NETWORKS */
1398 { "Visual Networks traffic capture", "visual", NULL, NULL,
1400 visual_dump_can_write_encap, visual_dump_open, NULL },
1402 /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V56 */
1403 { "Savvius classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
1407 /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V7 */
1408 { "Savvius classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
1412 /* WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED */
1413 { "Savvius tagged", "peektagged", "pkt", "tpc;apc;wpz",
1417 /* WTAP_FILE_TYPE_SUBTYPE_MPEG */
1418 { "MPEG", "mpeg", "mpeg", "mpg;mp3",
1422 /* WTAP_FILE_TYPE_SUBTYPE_K12TEXT */
1423 { "K12 text file", "k12text", "txt", NULL,
1425 k12text_dump_can_write_encap, k12text_dump_open, NULL },
1427 /* WTAP_FILE_TYPE_SUBTYPE_NETSCREEN */
1428 { "NetScreen snoop text file", "netscreen", "txt", NULL,
1432 /* WTAP_FILE_TYPE_SUBTYPE_COMMVIEW */
1433 { "TamoSoft CommView", "commview", "ncf", NULL,
1435 commview_dump_can_write_encap, commview_dump_open, NULL },
1437 /* WTAP_FILE_TYPE_SUBTYPE_BTSNOOP */
1438 { "Symbian OS btsnoop", "btsnoop", "log", NULL,
1440 btsnoop_dump_can_write_encap, btsnoop_dump_open_h4, NULL },
1442 /* WTAP_FILE_TYPE_SUBTYPE_TNEF */
1443 { "Transport-Neutral Encapsulation Format", "tnef", NULL, NULL,
1447 /* WTAP_FILE_TYPE_SUBTYPE_DCT3TRACE */
1448 { "Gammu DCT3 trace", "dct3trace", "xml", NULL,
1452 /* WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER */
1453 { "OS X PacketLogger", "pklg", "pklg", NULL,
1457 /* WTAP_FILE_TYPE_SUBTYPE_DAINTREE_SNA */
1458 { "Daintree SNA", "dsna", "dcf", NULL,
1462 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0 */
1463 { "NetScaler Trace (Version 1.0)", "nstrace10", NULL, NULL,
1465 nstrace_10_dump_can_write_encap, nstrace_dump_open, NULL },
1467 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0 */
1468 { "NetScaler Trace (Version 2.0)", "nstrace20", "cap", NULL,
1470 nstrace_20_dump_can_write_encap, nstrace_dump_open, NULL },
1472 /* WTAP_FILE_TYPE_SUBTYPE_JPEG_JFIF */
1473 { "JPEG/JFIF", "jpeg", "jpg", "jpeg;jfif",
1477 /* WTAP_FILE_TYPE_SUBTYPE_IPFIX */
1478 { "IPFIX File Format", "ipfix", "pfx", "ipfix",
1482 /* WTAP_ENCAP_MIME */
1483 { "MIME File Format", "mime", NULL, NULL,
1487 /* WTAP_FILE_TYPE_SUBTYPE_AETHRA */
1488 { "Aethra .aps file", "aethra", "aps", NULL,
1492 /* WTAP_FILE_TYPE_SUBTYPE_MPEG_2_TS */
1493 { "MPEG2 transport stream", "mp2t", "mp2t", "ts;mpg",
1497 /* WTAP_FILE_TYPE_SUBTYPE_VWR_80211 */
1498 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr80211", "vwr", NULL,
1502 /* WTAP_FILE_TYPE_SUBTYPE_VWR_ETH */
1503 { "Ixia IxVeriWave .vwr Raw Ethernet Capture", "vwreth", "vwr", NULL,
1507 /* WTAP_FILE_TYPE_SUBTYPE_CAMINS */
1508 { "CAM Inspector file", "camins", "camins", NULL,
1512 /* WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 */
1513 { "STANAG 4607 Format", "stanag4607", NULL, NULL,
1517 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 */
1518 { "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
1520 nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
1522 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT */
1523 { "Android Logcat Binary format", "logcat", "logcat", NULL,
1525 logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
1527 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF */
1528 { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
1530 logcat_text_brief_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
1532 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS */
1533 { "Android Logcat Process text format", "logcat-process", NULL, NULL,
1535 logcat_text_process_dump_can_write_encap, logcat_text_process_dump_open, NULL },
1537 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG */
1538 { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
1540 logcat_text_tag_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
1542 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD */
1543 { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
1545 logcat_text_thread_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
1547 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME */
1548 { "Android Logcat Time text format", "logcat-time", NULL, NULL,
1550 logcat_text_time_dump_can_write_encap, logcat_text_time_dump_open, NULL },
1552 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME */
1553 { "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
1555 logcat_text_threadtime_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
1557 /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG */
1558 { "Android Logcat Long text format", "logcat-long", NULL, NULL,
1560 logcat_text_long_dump_can_write_encap, logcat_text_long_dump_open, NULL },
1562 /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA */
1563 { "Colasoft Capsa format", "capsa", "cscpkt", NULL,
1567 /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER */
1568 { "Colasoft Packet Builder format", "colasoft-pb", "cscpkt", NULL,
1572 /* WTAP_FILE_TYPE_SUBTYPE_JSON */
1573 { "JavaScript Object Notation", "json", "json", "NULL",
1577 /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 */
1578 { "NetScaler Trace (Version 3.5)", "nstrace35", "cap", NULL,
1580 nstrace_35_dump_can_write_encap, nstrace_dump_open, NULL },
1582 /* WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423 */
1583 { "3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
1589 * Pointer to the table we're currently using. It's initialized to point
1590 * to the static table, but, if we have to allocate the GArray, it's
1591 * changed to point to the data in the GArray.
1593 static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
1596 * Number of elements in the table we're currently using. It's initialized
1597 * to the number of elements in the static table, but, if we have to
1598 * allocate the GArray, it's changed to have the size of the GArray.
1600 gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
1603 * Pointer to the GArray; NULL until it's needed.
1605 static GArray* dump_open_table_arr = NULL;
1608 * Create the GArray from the static table if it hasn't already been created.
1611 init_file_types_subtypes_garray(void)
1613 if (dump_open_table_arr) return;
1615 dump_open_table_arr = g_array_new(FALSE,TRUE,sizeof(struct file_type_subtype_info));
1617 g_array_append_vals(dump_open_table_arr,dump_open_table_base,wtap_num_file_types_subtypes);
1619 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1622 /* if subtype is WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, then create a new subtype as well as register it, else replace the
1623 existing entry in that spot */
1625 wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype)
1627 struct file_type_subtype_info* finfo;
1629 if (!fi || !fi->name || !fi->short_name || subtype > wtap_num_file_types_subtypes) {
1630 g_error("no file type info or invalid file type to register");
1634 /* do we want a new registration? */
1635 if (subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
1636 /* register a new one; first verify there isn't one named this already */
1637 if (wtap_short_string_to_file_type_subtype(fi->short_name) > -1 ) {
1638 g_error("file type short name already exists");
1643 * Create the GArray if it hasn't already been created.
1645 init_file_types_subtypes_garray();
1647 g_array_append_val(dump_open_table_arr,*fi);
1649 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1651 return wtap_num_file_types_subtypes++;
1654 /* re-register an existing one - verify the short names do match (sanity check really) */
1655 if (!dump_open_table[subtype].short_name || strcmp(dump_open_table[subtype].short_name,fi->short_name) != 0) {
1656 g_error("invalid file type name given to register");
1661 * Create the GArray if it hasn't already been created.
1663 init_file_types_subtypes_garray();
1666 * Get the pointer from the GArray, so that we get a non-const
1669 finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
1670 /*finfo->name = fi->name;*/
1671 /*finfo->short_name = fi->short_name;*/
1672 finfo->default_file_extension = fi->default_file_extension;
1673 finfo->additional_file_extensions = fi->additional_file_extensions;
1674 finfo->writing_must_seek = fi->writing_must_seek;
1675 finfo->has_name_resolution = fi->has_name_resolution;
1676 finfo->supported_comment_types = fi->supported_comment_types;
1677 finfo->can_write_encap = fi->can_write_encap;
1678 finfo->dump_open = fi->dump_open;
1679 finfo->wslua_info = fi->wslua_info;
1684 /* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
1687 wtap_deregister_file_type_subtype(const int subtype)
1689 struct file_type_subtype_info* finfo;
1691 if (subtype < 0 || subtype >= wtap_num_file_types_subtypes) {
1692 g_error("invalid file type to de-register");
1697 * Create the GArray if it hasn't already been created.
1699 init_file_types_subtypes_garray();
1702 * Get the pointer from the GArray, so that we get a non-const
1705 finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
1706 /* unfortunately, it's not safe to null-out the name or short_name; bunch of other code doesn't guard aainst that, afaict */
1707 /*finfo->name = NULL;*/
1708 /*finfo->short_name = NULL;*/
1709 finfo->default_file_extension = NULL;
1710 finfo->additional_file_extensions = NULL;
1711 finfo->writing_must_seek = FALSE;
1712 finfo->has_name_resolution = FALSE;
1713 finfo->supported_comment_types = 0;
1714 finfo->can_write_encap = NULL;
1715 finfo->dump_open = NULL;
1716 finfo->wslua_info = NULL;
1720 wtap_get_num_file_types_subtypes(void)
1722 return wtap_num_file_types_subtypes;
1726 * Given a GArray of WTAP_ENCAP_ types, return the per-file encapsulation
1727 * type that would be needed to write out a file with those types. If
1728 * there's only one type, it's that type, otherwise it's
1729 * WTAP_ENCAP_PER_PACKET.
1732 wtap_dump_file_encap_type(const GArray *file_encaps)
1736 encap = WTAP_ENCAP_PER_PACKET;
1737 if (file_encaps->len == 1) {
1738 /* OK, use the one-and-only encapsulation type. */
1739 encap = g_array_index(file_encaps, gint, 0);
1745 wtap_dump_can_write_encap(int filetype, int encap)
1749 if (filetype < 0 || filetype >= wtap_num_file_types_subtypes
1750 || dump_open_table[filetype].can_write_encap == NULL)
1753 result = (*dump_open_table[filetype].can_write_encap)(encap);
1756 /* if the err said to check wslua's can_write_encap, try that */
1757 if (result == WTAP_ERR_CHECK_WSLUA
1758 && dump_open_table[filetype].wslua_info != NULL
1759 && dump_open_table[filetype].wslua_info->wslua_can_write_encap != NULL) {
1761 result = (*dump_open_table[filetype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[filetype].wslua_info->wslua_data);
1773 * Return TRUE if a capture with a given GArray of encapsulation types
1774 * and a given bitset of comment types can be written in a specified
1775 * format, and FALSE if it can't.
1778 wtap_dump_can_write_format(int ft, const GArray *file_encaps,
1779 guint32 required_comment_types)
1784 * Can we write in this format?
1786 if (!wtap_dump_can_open(ft)) {
1792 * Yes. Can we write out all the required comments in this
1795 if (!wtap_dump_supports_comment_types(ft, required_comment_types)) {
1801 * Yes. Is the required per-file encapsulation type supported?
1802 * This might be WTAP_ENCAP_PER_PACKET.
1804 if (!wtap_dump_can_write_encap(ft, wtap_dump_file_encap_type(file_encaps))) {
1810 * Yes. Are all the individual encapsulation types supported?
1812 for (i = 0; i < file_encaps->len; i++) {
1813 if (!wtap_dump_can_write_encap(ft,
1814 g_array_index(file_encaps, int, i))) {
1815 /* No - one of them isn't. */
1820 /* Yes - we're OK. */
1825 * Return TRUE if we can write a file with the given GArray of
1826 * encapsulation types and the given bitmask of comment types.
1829 wtap_dump_can_write(const GArray *file_encaps, guint32 required_comment_types)
1833 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1834 /* To save a file with Wiretap, Wiretap has to handle that format,
1835 * and its code to handle that format must be able to write a file
1836 * with this file's encapsulation types.
1838 if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
1839 /* OK, we can write it out in this type. */
1844 /* No, we couldn't save it in any format. */
1849 * Get a GArray of WTAP_FILE_TYPE_SUBTYPE_ values for file types/subtypes
1850 * that can be used to save a file of a given type/subtype with a given
1851 * GArray of encapsulation types and the given bitmask of comment types.
1854 wtap_get_savable_file_types_subtypes(int file_type_subtype,
1855 const GArray *file_encaps, guint32 required_comment_types)
1857 GArray *savable_file_types_subtypes;
1859 int default_file_type_subtype = -1;
1860 int other_file_type_subtype = -1;
1862 /* Can we save this file in its own file type/subtype? */
1863 if (wtap_dump_can_write_format(file_type_subtype, file_encaps,
1864 required_comment_types)) {
1865 /* Yes - make that the default file type/subtype. */
1866 default_file_type_subtype = file_type_subtype;
1868 /* OK, find the first file type/subtype we *can* save it as. */
1869 default_file_type_subtype = -1;
1870 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1871 if (wtap_dump_can_write_format(ft, file_encaps,
1872 required_comment_types)) {
1874 default_file_type_subtype = ft;
1879 if (default_file_type_subtype == -1) {
1880 /* We don't support writing this file as any file type/subtype. */
1884 /* Allocate the array. */
1885 savable_file_types_subtypes = g_array_new(FALSE, FALSE, (guint)sizeof (int));
1887 /* Put the default file type/subtype first in the list. */
1888 g_array_append_val(savable_file_types_subtypes, default_file_type_subtype);
1890 /* If the default is pcap, put pcap-NG right after it if we can
1891 also write it in pcap-NG format; otherwise, if the default is
1892 pcap-NG, put pcap right after it if we can also write it in
1894 if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
1895 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, file_encaps,
1896 required_comment_types))
1897 other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
1898 } else if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
1899 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAP, file_encaps,
1900 required_comment_types))
1901 other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
1903 if (other_file_type_subtype != -1)
1904 g_array_append_val(savable_file_types_subtypes, other_file_type_subtype);
1906 /* Add all the other file types/subtypes that work. */
1907 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1908 if (ft == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1909 continue; /* not a real file type */
1910 if (ft == default_file_type_subtype || ft == other_file_type_subtype)
1911 continue; /* we've already done this one */
1912 if (wtap_dump_can_write_format(ft, file_encaps,
1913 required_comment_types)) {
1914 /* OK, we can write it out in this type. */
1915 g_array_append_val(savable_file_types_subtypes, ft);
1919 return savable_file_types_subtypes;
1922 /* Name that should be somewhat descriptive. */
1924 wtap_file_type_subtype_string(int file_type_subtype)
1926 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes) {
1927 g_error("Unknown capture file type %d", file_type_subtype);
1928 /** g_error() does an abort() and thus never returns **/
1931 return dump_open_table[file_type_subtype].name;
1934 /* Name to use in, say, a command-line flag specifying the type/subtype. */
1936 wtap_file_type_subtype_short_string(int file_type_subtype)
1938 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
1941 return dump_open_table[file_type_subtype].short_name;
1944 /* Translate a short name to a capture file type/subtype. */
1946 wtap_short_string_to_file_type_subtype(const char *short_name)
1948 int file_type_subtype;
1950 for (file_type_subtype = 0; file_type_subtype < wtap_num_file_types_subtypes; file_type_subtype++) {
1951 if (dump_open_table[file_type_subtype].short_name != NULL &&
1952 strcmp(short_name, dump_open_table[file_type_subtype].short_name) == 0)
1953 return file_type_subtype;
1957 * We now call the "libpcap" file format just "pcap", but we
1958 * allow it to be specified as "libpcap" as well, for
1959 * backwards compatibility.
1961 if (strcmp(short_name, "libpcap") == 0)
1962 return WTAP_FILE_TYPE_SUBTYPE_PCAP;
1964 return -1; /* no such file type, or we can't write it */
1968 add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
1969 const char **compressed_file_extensions)
1971 gchar **extensions_set, **extensionp;
1975 * Add the default extension, and all compressed variants of
1978 extensions = add_extensions(extensions,
1979 dump_open_table[file_type_subtype].default_file_extension,
1980 compressed_file_extensions);
1982 if (dump_open_table[file_type_subtype].additional_file_extensions != NULL) {
1984 * We have additional extensions; add them.
1986 * First, split the extension-list string into a set of
1989 extensions_set = g_strsplit(dump_open_table[file_type_subtype].additional_file_extensions,
1993 * Add each of those extensions to the list.
1995 for (extensionp = extensions_set; *extensionp != NULL;
1997 extension = *extensionp;
2000 * Add the extension, and all compressed variants
2003 extensions = add_extensions(extensions, extension,
2004 compressed_file_extensions);
2007 g_strfreev(extensions_set);
2012 /* Return a list of file extensions that are used by the specified file type.
2014 If include_compressed is TRUE, the list will include compressed
2015 extensions, e.g. not just "pcap" but also "pcap.gz" if we can read
2018 All strings in the list are allocated with g_malloc() and must be freed
2021 wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
2024 static const char *no_compressed_extensions[] = {
2028 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2029 return NULL; /* not a valid file type */
2031 if (dump_open_table[file_type_subtype].default_file_extension == NULL)
2032 return NULL; /* valid, but no extensions known */
2034 extensions = NULL; /* empty list, to start with */
2037 * Add all this file type's extensions, with compressed
2038 * variants if include_compressed is true.
2040 extensions = add_extensions_for_file_type_subtype(file_type_subtype, extensions,
2041 include_compressed ? compressed_file_extension_table : no_compressed_extensions);
2047 * Free a list returned by wtap_get_file_extension_type_extensions(),
2048 * wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
2051 wtap_free_extensions_list(GSList *extensions)
2055 for (extension = extensions; extension != NULL;
2056 extension = g_slist_next(extension)) {
2057 g_free(extension->data);
2059 g_slist_free(extensions);
2062 /* Return the default file extension to use with the specified file type;
2063 that's just the extension, without any ".". */
2065 wtap_default_file_extension(int file_type_subtype)
2067 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2070 return dump_open_table[file_type_subtype].default_file_extension;
2074 wtap_dump_can_open(int file_type_subtype)
2076 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2077 || dump_open_table[file_type_subtype].dump_open == NULL)
2085 wtap_dump_can_compress(int file_type_subtype)
2088 * If this is an unknown file type, or if we have to
2089 * seek when writing out a file with this file type,
2092 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2093 || dump_open_table[file_type_subtype].writing_must_seek)
2100 wtap_dump_can_compress(int file_type_subtype _U_)
2107 wtap_dump_has_name_resolution(int file_type_subtype)
2109 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2110 || dump_open_table[file_type_subtype].has_name_resolution == FALSE)
2117 wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
2119 guint32 supported_comment_types;
2121 if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2124 supported_comment_types = dump_open_table[file_type_subtype].supported_comment_types;
2126 if ((comment_types & supported_comment_types) == comment_types)
2131 static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean comressed, int *err);
2132 static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen,
2133 gboolean compressed, int *err);
2134 static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err);
2136 static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename);
2137 static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
2138 static int wtap_dump_file_close(wtap_dumper *wdh);
2140 static wtap_dumper *
2141 wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
2142 wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2143 wtap_optionblock_t nrb_hdr, int *err)
2146 wtap_optionblock_t descr, file_int_data;
2147 wtapng_if_descr_mandatory_t *descr_mand, *file_int_data_mand;
2149 /* Check whether we can open a capture file with that file type
2150 and that encapsulation. */
2151 if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
2154 /* Allocate a data structure for the output stream. */
2155 wdh = wtap_dump_alloc_wdh(file_type_subtype, encap, snaplen, compressed, err);
2157 return NULL; /* couldn't allocate it */
2159 /* Set Section Header Block data */
2160 wdh->shb_hdr = shb_hdr;
2161 /* Set Name Resolution Block data */
2162 wdh->nrb_hdr = nrb_hdr;
2163 /* Set Interface Description Block data */
2164 if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
2167 /* XXX: what free's this stuff? */
2168 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2169 for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
2170 file_int_data = g_array_index(idb_inf->interface_data, wtap_optionblock_t, itf_count);
2171 file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(file_int_data);
2172 descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2173 wtap_optionblock_copy_options(descr, file_int_data);
2174 if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data_mand->wtap_encap)) {
2175 descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
2176 descr_mand->wtap_encap = encap;
2177 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
2179 g_array_append_val(wdh->interface_data, descr);
2182 descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2183 descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
2184 descr_mand->wtap_encap = encap;
2185 descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
2186 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
2187 descr_mand->snap_len = snaplen;
2188 wtap_optionblock_set_option_string(descr, OPT_IDB_NAME, "Unknown/not available in original file format(libpcap)");
2190 descr_mand->num_stat_entries = 0; /* Number of ISB:s */
2191 descr_mand->interface_statistics = NULL;
2192 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2193 g_array_append_val(wdh->interface_data, descr);
2199 wtap_dump_open(const char *filename, int file_type_subtype, int encap,
2200 int snaplen, gboolean compressed, int *err)
2202 return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2206 wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
2207 int snaplen, gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2208 wtap_optionblock_t nrb_hdr, int *err)
2213 /* Allocate and initialize a data structure for the output stream. */
2214 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2215 shb_hdr, idb_inf, nrb_hdr, err);
2219 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2220 to a generic "the open failed" error. */
2221 errno = WTAP_ERR_CANT_OPEN;
2222 fh = wtap_dump_file_open(wdh, filename);
2226 return NULL; /* can't create file */
2230 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2231 /* Get rid of the file we created; we couldn't finish
2233 wtap_dump_file_close(wdh);
2234 ws_unlink(filename);
2242 wtap_dump_open_tempfile(char **filenamep, const char *pfx,
2243 int file_type_subtype, int encap,
2244 int snaplen, gboolean compressed, int *err)
2246 return wtap_dump_open_tempfile_ng(filenamep, pfx, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2250 wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
2251 int file_type_subtype, int encap,
2252 int snaplen, gboolean compressed,
2253 wtap_optionblock_t shb_hdr,
2254 wtapng_iface_descriptions_t *idb_inf,
2255 wtap_optionblock_t nrb_hdr, int *err)
2262 /* No path name for the temporary file yet. */
2265 /* Allocate and initialize a data structure for the output stream. */
2266 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2267 shb_hdr, idb_inf, nrb_hdr, err);
2271 /* Choose a random name for the file */
2272 fd = create_tempfile(&tmpname, pfx);
2276 return NULL; /* can't create file */
2278 *filenamep = tmpname;
2280 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2281 to a generic "the open failed" error. */
2282 errno = WTAP_ERR_CANT_OPEN;
2283 fh = wtap_dump_file_fdopen(wdh, fd);
2288 return NULL; /* can't create file */
2292 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2293 /* Get rid of the file we created; we couldn't finish
2295 wtap_dump_file_close(wdh);
2304 wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
2305 gboolean compressed, int *err)
2307 return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2311 wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
2312 gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2313 wtap_optionblock_t nrb_hdr, int *err)
2318 /* Allocate and initialize a data structure for the output stream. */
2319 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2320 shb_hdr, idb_inf, nrb_hdr, err);
2324 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2325 to a generic "the open failed" error. */
2326 errno = WTAP_ERR_CANT_OPEN;
2327 fh = wtap_dump_file_fdopen(wdh, fd);
2331 return NULL; /* can't create standard I/O stream */
2335 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2336 wtap_dump_file_close(wdh);
2344 wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
2345 gboolean compressed, int *err)
2347 return wtap_dump_open_stdout_ng(file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2351 wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
2352 gboolean compressed, wtap_optionblock_t shb_hdr,
2353 wtapng_iface_descriptions_t *idb_inf,
2354 wtap_optionblock_t nrb_hdr, int *err)
2359 /* Allocate and initialize a data structure for the output stream. */
2360 wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2361 shb_hdr, idb_inf, nrb_hdr, err);
2367 * Put the standard output into binary mode.
2369 * XXX - even if the file format we're writing is a text
2372 if (_setmode(1, O_BINARY) == -1) {
2373 /* "Should not happen" */
2376 return NULL; /* couldn't put standard output in binary mode */
2380 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2381 to a generic "the open failed" error. */
2382 errno = WTAP_ERR_CANT_OPEN;
2383 fh = wtap_dump_file_fdopen(wdh, 1);
2387 return NULL; /* can't create standard I/O stream */
2390 wdh->is_stdout = TRUE;
2392 if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2393 wtap_dump_file_close(wdh);
2401 wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
2403 if (!wtap_dump_can_open(file_type_subtype)) {
2404 /* Invalid type, or type we don't know how to write. */
2405 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2409 /* OK, we know how to write that type; can we write the specified
2410 encapsulation type? */
2411 *err = (*dump_open_table[file_type_subtype].can_write_encap)(encap);
2412 /* if the err said to check wslua's can_write_encap, try that */
2413 if (*err == WTAP_ERR_CHECK_WSLUA
2414 && dump_open_table[file_type_subtype].wslua_info != NULL
2415 && dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap != NULL) {
2417 *err = (*dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[file_type_subtype].wslua_info->wslua_data);
2424 /* if compression is wanted, do we support this for this file_type_subtype? */
2425 if(compressed && !wtap_dump_can_compress(file_type_subtype)) {
2426 *err = WTAP_ERR_COMPRESSION_NOT_SUPPORTED;
2430 /* All systems go! */
2434 static wtap_dumper *
2435 wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean compressed, int *err)
2439 wdh = (wtap_dumper *)g_malloc0(sizeof (wtap_dumper));
2445 wdh->file_type_subtype = file_type_subtype;
2446 wdh->snaplen = snaplen;
2448 wdh->compressed = compressed;
2449 wdh->wslua_data = NULL;
2454 wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
2459 /* Can we do a seek on the file descriptor?
2460 If not, note that fact. */
2464 fd = ws_fileno((FILE *)wdh->fh);
2465 if (ws_lseek64(fd, 1, SEEK_CUR) == (off_t) -1)
2468 /* Undo the seek. */
2469 ws_lseek64(fd, 0, SEEK_SET);
2474 /* If this file type requires seeking, and we can't seek, fail. */
2475 if (dump_open_table[file_type_subtype].writing_must_seek && cant_seek) {
2476 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
2480 /* Set wdh with wslua data if any - this is how we pass the data
2481 * to the file writer.
2483 if (dump_open_table[file_type_subtype].wslua_info)
2484 wdh->wslua_data = dump_open_table[file_type_subtype].wslua_info->wslua_data;
2486 /* Now try to open the file for writing. */
2487 if (!(*dump_open_table[file_type_subtype].dump_open)(wdh, err)) {
2491 return TRUE; /* success! */
2495 wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2496 const guint8 *pd, int *err, gchar **err_info)
2500 return (wdh->subtype_write)(wdh, phdr, pd, err, err_info);
2504 wtap_dump_flush(wtap_dumper *wdh)
2507 if(wdh->compressed) {
2508 gzwfile_flush((GZWFILE_T)wdh->fh);
2512 fflush((FILE *)wdh->fh);
2517 wtap_dump_close(wtap_dumper *wdh, int *err)
2519 gboolean ret = TRUE;
2521 if (wdh->subtype_finish != NULL) {
2522 /* There's a finish routine for this dump stream. */
2523 if (!(wdh->subtype_finish)(wdh, err))
2526 errno = WTAP_ERR_CANT_CLOSE;
2527 if (wtap_dump_file_close(wdh) == EOF) {
2529 /* The per-format finish function succeeded,
2530 but the stream close didn't. Save the
2531 reason why, if our caller asked for it. */
2537 if (wdh->priv != NULL)
2544 wtap_get_bytes_dumped(wtap_dumper *wdh)
2546 return wdh->bytes_dumped;
2550 wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
2552 wdh->bytes_dumped = bytes_dumped;
2556 wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
2558 if (!wdh || wdh->file_type_subtype < 0 || wdh->file_type_subtype >= wtap_num_file_types_subtypes
2559 || dump_open_table[wdh->file_type_subtype].has_name_resolution == FALSE)
2561 wdh->addrinfo_lists = addrinfo_lists;
2565 /* internally open a file for writing (compressed or not) */
2568 wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
2570 if(wdh->compressed) {
2571 return gzwfile_open(filename);
2573 return ws_fopen(filename, "wb");
2578 wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
2580 return ws_fopen(filename, "wb");
2584 /* internally open a file for writing (compressed or not) */
2587 wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
2589 if(wdh->compressed) {
2590 return gzwfile_fdopen(fd);
2592 return ws_fdopen(fd, "wb");
2597 wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
2599 return ws_fdopen(fd, "wb");
2603 /* internally writing raw bytes (compressed or not) */
2605 wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize, int *err)
2610 if (wdh->compressed) {
2611 nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned int) bufsize);
2613 * gzwfile_write() returns 0 on error.
2615 if (nwritten == 0) {
2616 *err = gzwfile_geterr((GZWFILE_T)wdh->fh);
2622 errno = WTAP_ERR_CANT_WRITE;
2623 nwritten = fwrite(buf, 1, bufsize, (FILE *)wdh->fh);
2625 * At least according to the Mac OS X man page,
2626 * this can return a short count on an error.
2628 if (nwritten != bufsize) {
2629 if (ferror((FILE *)wdh->fh))
2632 *err = WTAP_ERR_SHORT_WRITE;
2639 /* internally close a file for writing (compressed or not) */
2641 wtap_dump_file_close(wtap_dumper *wdh)
2644 if(wdh->compressed) {
2646 * Tell gzwfile_close() whether to close the descriptor
2649 return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout);
2654 * Don't close the standard output.
2656 * XXX - this really should do everything fclose() does,
2657 * including freeing all allocated data structures,
2658 * *except* for actually closing the file descriptor.
2660 return wdh->is_stdout ? fflush((FILE *)wdh->fh) : fclose((FILE *)wdh->fh);
2665 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
2668 if(wdh->compressed) {
2669 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2674 if (-1 == fseek((FILE *)wdh->fh, (long)offset, whence)) {
2685 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
2689 if(wdh->compressed) {
2690 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2695 if (-1 == (rval = ftell((FILE *)wdh->fh))) {
2706 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2711 * indent-tabs-mode: t
2714 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2715 * :indentSize=8:tabSize=8:noTabs=false: