Return the same error for too-large packets as we do for other files.
[metze/wireshark/wip.git] / wiretap / file_access.c
1 /* file_access.c
2  *
3  * Wiretap Library
4  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
5  *
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.
10  *
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.
15  *
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.
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include <errno.h>
27
28 #include <wsutil/file_util.h>
29 #include <wsutil/tempfile.h>
30
31 #include "wtap-int.h"
32 #include "file_wrappers.h"
33 #include <wsutil/buffer.h>
34 #include "lanalyzer.h"
35 #include "ngsniffer.h"
36 #include "radcom.h"
37 #include "ascendtext.h"
38 #include "nettl.h"
39 #include "libpcap.h"
40 #include "snoop.h"
41 #include "iptrace.h"
42 #include "iseries.h"
43 #include "netmon.h"
44 #include "netxray.h"
45 #include "toshiba.h"
46 #include "eyesdn.h"
47 #include "i4btrace.h"
48 #include "csids.h"
49 #include "pppdump.h"
50 #include "peekclassic.h"
51 #include "peektagged.h"
52 #include "vms.h"
53 #include "dbs-etherwatch.h"
54 #include "visual.h"
55 #include "cosine.h"
56 #include "5views.h"
57 #include "erf.h"
58 #include "hcidump.h"
59 #include "logcat.h"
60 #include "logcat_text.h"
61 #include "json.h"
62 #include "network_instruments.h"
63 #include "k12.h"
64 #include "ber.h"
65 #include "catapult_dct2000.h"
66 #include "mp2t.h"
67 #include "mpeg.h"
68 #include "netscreen.h"
69 #include "commview.h"
70 #include "pcapng.h"
71 #include "aethra.h"
72 #include "btsnoop.h"
73 #include "tnef.h"
74 #include "dct3trace.h"
75 #include "packetlogger.h"
76 #include "daintree-sna.h"
77 #include "netscaler.h"
78 #include "mime_file.h"
79 #include "ipfix.h"
80 #include "vwr.h"
81 #include "camins.h"
82 #include "stanag4607.h"
83 #include "capsa.h"
84 #include "pcap-encap.h"
85 #include "nettrace_3gpp_32_423.h"
86 #include "mplog.h"
87
88 /*
89  * Add an extension, and all compressed versions thereof, to a GSList
90  * of extensions.
91  */
92 static GSList *
93 add_extensions(GSList *extensions, const gchar *extension,
94     const char **compressed_file_extensions)
95 {
96         const char **compressed_file_extensionp;
97
98         /*
99          * Add the specified extension.
100          */
101         extensions = g_slist_append(extensions, g_strdup(extension));
102
103         /*
104          * Now add the extensions for compressed-file versions of
105          * that extension.
106          */
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));
113         }
114
115         return extensions;
116 }
117
118 /*
119  * File types that can be identified by file extensions.
120  *
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.
125  */
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" }
157 };
158
159 #define N_FILE_TYPE_EXTENSIONS  (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
160
161 static const struct file_extension_info* file_type_extensions = NULL;
162
163 static GArray* file_type_extensions_arr = NULL;
164
165 /* initialize the extensions array if it has not been initialized yet */
166 static void
167 init_file_type_extensions(void)
168 {
169
170         if (file_type_extensions_arr) return;
171
172         file_type_extensions_arr = g_array_new(FALSE,TRUE,sizeof(struct file_extension_info));
173
174         g_array_append_vals(file_type_extensions_arr,file_type_extensions_base,N_FILE_TYPE_EXTENSIONS);
175
176         file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
177 }
178
179 void
180 wtap_register_file_type_extension(const struct file_extension_info *ei)
181 {
182         init_file_type_extensions();
183
184         g_array_append_val(file_type_extensions_arr,*ei);
185
186         file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
187 }
188
189 int
190 wtap_get_num_file_type_extensions(void)
191 {
192         return file_type_extensions_arr->len;
193 }
194
195 const char *
196 wtap_get_file_extension_type_name(int extension_type)
197 {
198         return file_type_extensions[extension_type].name;
199 }
200
201 static GSList *
202 add_extensions_for_file_extensions_type(int extension_type,
203     GSList *extensions, const char **compressed_file_extensions)
204 {
205         gchar **extensions_set, **extensionp, *extension;
206
207         /*
208          * Split the extension-list string into a set of extensions.
209          */
210         extensions_set = g_strsplit(file_type_extensions[extension_type].extensions,
211             ";", 0);
212
213         /*
214          * Add each of those extensions to the list.
215          */
216         for (extensionp = extensions_set; *extensionp != NULL; extensionp++) {
217                 extension = *extensionp;
218
219                 /*
220                  * Add the extension, and all compressed variants
221                  * of it.
222                  */
223                 extensions = add_extensions(extensions, extension,
224                     compressed_file_extensions);
225         }
226
227         g_strfreev(extensions_set);
228         return extensions;
229 }
230
231 /* Return a list of file extensions that are used by the specified file
232    extension type.
233
234    All strings in the list are allocated with g_malloc() and must be freed
235    with g_free(). */
236 GSList *
237 wtap_get_file_extension_type_extensions(guint extension_type)
238 {
239         GSList *extensions;
240
241         if (extension_type >= file_type_extensions_arr->len)
242                 return NULL;    /* not a valid extension type */
243
244         extensions = NULL;      /* empty list, to start with */
245
246         /*
247          * Add all this file extension type's extensions, with compressed
248          * variants.
249          */
250         extensions = add_extensions_for_file_extensions_type(extension_type,
251             extensions, compressed_file_extension_table);
252
253         return extensions;
254 }
255
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.
259
260    All strings in the list are allocated with g_malloc() and must be freed
261    with g_free(). */
262 GSList *
263 wtap_get_all_file_extensions_list(void)
264 {
265         GSList *extensions;
266         unsigned int i;
267
268         init_file_type_extensions();
269
270         extensions = NULL;      /* empty list, to start with */
271
272         for (i = 0; i < file_type_extensions_arr->len; i++) {
273                 /*
274                  * Add all this file extension type's extensions, with
275                  * compressed variants.
276                  */
277                 extensions = add_extensions_for_file_extensions_type(i,
278                     extensions, compressed_file_extension_table);
279         }
280
281         return extensions;
282 }
283
284 /*
285  * The open_file_* routines should return:
286  *
287  *      -1 on an I/O error;
288  *
289  *      1 if the file they're reading is one of the types it handles;
290  *
291  *      0 if the file they're reading isn't the type they're checking for.
292  *
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.
295  *
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)
299  *
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.
303  *
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.
310  *
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 and packaging/nsis/common.nsh
317  *         (for Windows)
318  *
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).
321  */
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 },
351         /*
352          * PacketLogger must come before MPEG, because its files
353          * are sometimes grabbed by mpeg_open.
354          */
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 },
361         /*
362          * I put NetScreen *before* erf, because there were some
363          * false positives with my test-files (Sake Blok, July 2007)
364          *
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)
368          *
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)
373          */
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 }
398 };
399
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.
403  */
404 #define N_OPEN_INFO_ROUTINES  ((sizeof open_info_base / sizeof open_info_base[0]))
405
406 static GArray *open_info_arr = NULL;
407
408 /* this always points to the top of the created array */
409 struct open_info *open_routines = NULL;
410
411 /* this points to the first OPEN_INFO_HEURISTIC type in the array */
412 static guint heuristic_open_routine_idx = 0;
413
414 static void
415 set_heuristic_routine(void)
416 {
417         guint i;
418         g_assert(open_info_arr != NULL);
419
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;
423                         break;
424                 }
425                 /* sanity check */
426                 g_assert(open_routines[i].type == OPEN_INFO_MAGIC);
427         }
428
429         g_assert(heuristic_open_routine_idx > 0);
430 }
431
432 void
433 init_open_routines(void)
434 {
435         unsigned int i;
436         struct open_info *i_open;
437
438         if (open_info_arr)
439                 return;
440
441         open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
442
443         g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
444
445         open_routines = (struct open_info *)(void*) open_info_arr->data;
446
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);
451         }
452
453         set_heuristic_routine();
454 }
455
456 /*
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.
461  */
462 void
463 wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
464 {
465         init_open_routines();
466
467         if (!oi || !oi->name) {
468                 g_error("No open_info name given to register");
469                 return;
470         }
471
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");
475                 return;
476         }
477
478         if (oi->extensions != NULL)
479                 oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
480
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);
487         } else {
488                 g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
489         }
490
491         open_routines = (struct open_info *)(void*) open_info_arr->data;
492         set_heuristic_routine();
493 }
494
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.
499  */
500 void
501 wtap_deregister_open_info(const gchar *name)
502 {
503         guint i;
504         init_open_routines();
505
506         if (!name) {
507                 g_error("Missing open_info name to de-register");
508                 return;
509         }
510
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();
517                         return;
518                 }
519         }
520
521         g_error("deregister_open_info: name not found");
522 }
523
524 /* Determines if a open routine short name already exists
525  */
526 gboolean
527 wtap_has_open_info(const gchar *name)
528 {
529         guint i;
530         init_open_routines();
531
532         if (!name) {
533                 g_error("No name given to wtap_has_open_info!");
534                 return FALSE;
535         }
536
537
538         for (i = 0; i < open_info_arr->len; i++) {
539                 if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
540                         return TRUE;
541                 }
542         }
543
544         return FALSE;
545 }
546
547 /*
548  * Visual C++ on Win32 systems doesn't define these.  (Old UNIX systems don't
549  * define them either.)
550  *
551  * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
552  */
553 #ifndef S_ISREG
554 #define S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
555 #endif
556 #ifndef S_IFIFO
557 #define S_IFIFO _S_IFIFO
558 #endif
559 #ifndef S_ISFIFO
560 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
561 #endif
562 #ifndef S_ISDIR
563 #define S_ISDIR(mode)   (((mode) & S_IFMT) == S_IFDIR)
564 #endif
565
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. */
570 unsigned int
571 open_info_name_to_type(const char *name)
572 {
573         unsigned int i;
574         init_open_routines();
575
576         if (!name)
577                 return WTAP_TYPE_AUTO;
578
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)
582                         return i+1;
583         }
584
585         return WTAP_TYPE_AUTO; /* no such file type */
586 }
587
588 static char *
589 get_file_extension(const char *pathname)
590 {
591         gchar *filename;
592         gchar **components;
593         size_t ncomponents;
594         const char **compressed_file_extensionp;
595         gchar *extensionp;
596
597         /*
598          * Is the pathname empty?
599          */
600         if (strcmp(pathname, "") == 0)
601                 return NULL;    /* no extension */
602
603         /*
604          * Find the last component of the pathname.
605          */
606         filename = g_path_get_basename(pathname);
607
608         /*
609          * Does it have an extension?
610          */
611         if (strchr(filename, '.') == NULL) {
612                 g_free(filename);
613                 return NULL;    /* no extension whatsoever */
614         }
615
616         /*
617          * Yes.  Split it into components separated by ".".
618          */
619         components = g_strsplit(filename, ".", 0);
620         g_free(filename);
621
622         /*
623          * Count the components.
624          */
625         for (ncomponents = 0; components[ncomponents] != NULL; ncomponents++)
626                 ;
627
628         if (ncomponents == 0) {
629                 g_strfreev(components);
630                 return NULL;    /* no components */
631         }
632         if (ncomponents == 1) {
633                 g_strfreev(components);
634                 return NULL;    /* only one component, with no "." */
635         }
636
637         /*
638          * Is the last component one of the extensions used for compressed
639          * files?
640          */
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) {
646                         /*
647                          * Yes, it's one of the compressed-file extensions.
648                          * Is there an extension before that?
649                          */
650                         if (ncomponents == 2) {
651                                 g_strfreev(components);
652                                 return NULL;    /* no, only two components */
653                         }
654
655                         /*
656                          * Yes, return that extension.
657                          */
658                         extensionp = g_strdup(components[ncomponents - 2]);
659                         g_strfreev(components);
660                         return extensionp;
661                 }
662         }
663
664         /*
665          * The extension isn't one of the compressed-file extensions;
666          * return it.
667          */
668         extensionp = g_strdup(extensionp);
669         g_strfreev(components);
670         return extensionp;
671 }
672
673 /*
674  * Check if file extension is used in this heuristic
675  */
676 static gboolean
677 heuristic_uses_extension(unsigned int i, const char *extension)
678 {
679         gchar **extensionp;
680
681         /*
682          * Does this file type *have* any extensions?
683          */
684         if (open_routines[i].extensions == NULL)
685                 return FALSE;   /* no */
686
687         /*
688          * Check each of them against the specified extension.
689          */
690         for (extensionp = open_routines[i].extensions_set; *extensionp != NULL;
691             extensionp++) {
692                 if (strcmp(extension, *extensionp) == 0) {
693                         return TRUE;    /* it's one of them */
694                 }
695         }
696
697         return FALSE;   /* it's not one of them */
698 }
699
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. */
707 wtap *
708 wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
709                   gboolean do_random)
710 {
711         int     fd;
712         ws_statb64 statb;
713         wtap    *wth;
714         unsigned int    i;
715         gboolean use_stdin = FALSE;
716         gchar *extension;
717
718         *err = 0;
719         *err_info = NULL;
720
721         init_open_routines();
722
723         /* open standard input if filename is '-' */
724         if (strcmp(filename, "-") == 0)
725                 use_stdin = TRUE;
726
727         /* First, make sure the file is valid */
728         if (use_stdin) {
729                 if (ws_fstat64(0, &statb) < 0) {
730                         *err = errno;
731                         return NULL;
732                 }
733         } else {
734                 if (ws_stat64(filename, &statb) < 0) {
735                         *err = errno;
736                         return NULL;
737                 }
738         }
739         if (S_ISFIFO(statb.st_mode)) {
740                 /*
741                  * Opens of FIFOs are allowed only when not opening
742                  * for random access.
743                  *
744                  * Currently, we do seeking when trying to find out
745                  * the file type, but our I/O routines do some amount
746                  * of buffering, and do backward seeks within the buffer
747                  * if possible, so at least some file types can be
748                  * opened from pipes, so we don't completely disallow opens
749                  * of pipes.
750                  */
751                 if (do_random) {
752                         *err = WTAP_ERR_RANDOM_OPEN_PIPE;
753                         return NULL;
754                 }
755         } else if (S_ISDIR(statb.st_mode)) {
756                 /*
757                  * Return different errors for "this is a directory"
758                  * and "this is some random special file type", so
759                  * the user can get a potentially more helpful error.
760                  */
761                 *err = EISDIR;
762                 return NULL;
763         } else if (! S_ISREG(statb.st_mode)) {
764                 *err = WTAP_ERR_NOT_REGULAR_FILE;
765                 return NULL;
766         }
767
768         /*
769          * We need two independent descriptors for random access, so
770          * they have different file positions.  If we're opening the
771          * standard input, we can only dup it to get additional
772          * descriptors, so we can't have two independent descriptors,
773          * and thus can't do random access.
774          */
775         if (use_stdin && do_random) {
776                 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
777                 return NULL;
778         }
779
780         errno = ENOMEM;
781         wth = (wtap *)g_malloc0(sizeof(wtap));
782
783         /* Open the file */
784         errno = WTAP_ERR_CANT_OPEN;
785         if (use_stdin) {
786                 /*
787                  * We dup FD 0, so that we don't have to worry about
788                  * a file_close of wth->fh closing the standard
789                  * input of the process.
790                  */
791                 fd = ws_dup(0);
792                 if (fd < 0) {
793                         *err = errno;
794                         g_free(wth);
795                         return NULL;
796                 }
797 #ifdef _WIN32
798                 if (_setmode(fd, O_BINARY) == -1) {
799                         /* "Shouldn't happen" */
800                         *err = errno;
801                         g_free(wth);
802                         return NULL;
803                 }
804 #endif
805                 if (!(wth->fh = file_fdopen(fd))) {
806                         *err = errno;
807                         ws_close(fd);
808                         g_free(wth);
809                         return NULL;
810                 }
811         } else {
812                 if (!(wth->fh = file_open(filename))) {
813                         *err = errno;
814                         g_free(wth);
815                         return NULL;
816                 }
817         }
818
819         if (do_random) {
820                 if (!(wth->random_fh = file_open(filename))) {
821                         *err = errno;
822                         file_close(wth->fh);
823                         g_free(wth);
824                         return NULL;
825                 }
826         } else
827                 wth->random_fh = NULL;
828
829         /* initialization */
830         wth->file_encap = WTAP_ENCAP_UNKNOWN;
831         wth->subtype_sequential_close = NULL;
832         wth->subtype_close = NULL;
833         wth->file_tsprec = WTAP_TSPREC_USEC;
834         wth->priv = NULL;
835         wth->wslua_data = NULL;
836         wth->shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
837
838         /* Initialize the array containing a list of interfaces. pcapng_open and
839          * erf_open needs this (and libpcap_open for ERF encapsulation types).
840          * Always initing it here saves checking for a NULL ptr later. */
841         wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
842
843         if (wth->random_fh) {
844                 wth->fast_seek = g_ptr_array_new();
845
846                 file_set_random_access(wth->fh, FALSE, wth->fast_seek);
847                 file_set_random_access(wth->random_fh, TRUE, wth->fast_seek);
848         }
849
850         /* 'type' is 1 greater than the array index */
851         if (type != WTAP_TYPE_AUTO && type <= open_info_arr->len) {
852                 int result;
853
854                 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
855                         /* I/O error - give up */
856                         wtap_close(wth);
857                         return NULL;
858                 }
859
860                 /* Set wth with wslua data if any - this is how we pass the data
861                  * to the file reader, kinda like the priv member but not free'd later.
862                  * It's ok for this to copy a NULL.
863                  */
864                 wth->wslua_data = open_routines[type - 1].wslua_data;
865
866                 result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
867
868                 switch (result) {
869                         case WTAP_OPEN_ERROR:
870                                 /* Error - give up */
871                                 wtap_close(wth);
872                                 return NULL;
873
874                         case WTAP_OPEN_NOT_MINE:
875                                 /* No error, but not that type of file */
876                                 goto fail;
877
878                         case WTAP_OPEN_MINE:
879                                 /* We found the file type */
880                                 goto success;
881                 }
882         }
883
884         /* Try all file types that support magic numbers */
885         for (i = 0; i < heuristic_open_routine_idx; i++) {
886                 /* Seek back to the beginning of the file; the open routine
887                    for the previous file type may have left the file
888                    position somewhere other than the beginning, and the
889                    open routine for this file type will probably want
890                    to start reading at the beginning.
891
892                    Initialize the data offset while we're at it. */
893                 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
894                         /* Error - give up */
895                         wtap_close(wth);
896                         return NULL;
897                 }
898
899                 /* Set wth with wslua data if any - this is how we pass the data
900                  * to the file reader, kinda like the priv member but not free'd later.
901                  * It's ok for this to copy a NULL.
902                  */
903                 wth->wslua_data = open_routines[i].wslua_data;
904
905                 switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
906
907                 case WTAP_OPEN_ERROR:
908                         /* Error - give up */
909                         wtap_close(wth);
910                         return NULL;
911
912                 case WTAP_OPEN_NOT_MINE:
913                         /* No error, but not that type of file */
914                         break;
915
916                 case WTAP_OPEN_MINE:
917                         /* We found the file type */
918                         goto success;
919                 }
920         }
921
922
923         /* Does this file's name have an extension? */
924         extension = get_file_extension(filename);
925         if (extension != NULL) {
926                 /* Yes - try the heuristic types that use that extension first. */
927                 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
928                         /* Does this type use that extension? */
929                         if (heuristic_uses_extension(i, extension)) {
930                                 /* Yes. */
931                                 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
932                                         /* Error - give up */
933                                         g_free(extension);
934                                         wtap_close(wth);
935                                         return NULL;
936                                 }
937
938                                 /* Set wth with wslua data if any - this is how we pass the data
939                                  * to the file reader, kind of like priv but not free'd later.
940                                  */
941                                 wth->wslua_data = open_routines[i].wslua_data;
942
943                                 switch ((*open_routines[i].open_routine)(wth,
944                                     err, err_info)) {
945
946                                 case WTAP_OPEN_ERROR:
947                                         /* Error - give up */
948                                         g_free(extension);
949                                         wtap_close(wth);
950                                         return NULL;
951
952                                 case WTAP_OPEN_NOT_MINE:
953                                         /* No error, but not that type of file */
954                                         break;
955
956                                 case WTAP_OPEN_MINE:
957                                         /* We found the file type */
958                                         g_free(extension);
959                                         goto success;
960                                 }
961                         }
962                 }
963
964                 /*
965                  * Now try the heuristic types that have no extensions
966                  * to check; we try those before the ones that have
967                  * extensions that *don't* match this file's extension,
968                  * on the theory that files of those types generally
969                  * have one of the type's extensions, and, as this file
970                  * *doesn't* have one of those extensions, it's probably
971                  * *not* one of those files.
972                  */
973                 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
974                         /* Does this type have any extensions? */
975                         if (open_routines[i].extensions == NULL) {
976                                 /* No. */
977                                 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
978                                         /* Error - give up */
979                                         g_free(extension);
980                                         wtap_close(wth);
981                                         return NULL;
982                                 }
983
984                                 /* Set wth with wslua data if any - this is how we pass the data
985                                  * to the file reader, kind of like priv but not free'd later.
986                                  */
987                                 wth->wslua_data = open_routines[i].wslua_data;
988
989                                 switch ((*open_routines[i].open_routine)(wth,
990                                     err, err_info)) {
991
992                                 case WTAP_OPEN_ERROR:
993                                         /* Error - give up */
994                                         g_free(extension);
995                                         wtap_close(wth);
996                                         return NULL;
997
998                                 case WTAP_OPEN_NOT_MINE:
999                                         /* No error, but not that type of file */
1000                                         break;
1001
1002                                 case WTAP_OPEN_MINE:
1003                                         /* We found the file type */
1004                                         g_free(extension);
1005                                         goto success;
1006                                 }
1007                         }
1008                 }
1009
1010                 /*
1011                  * Now try the ones that have extensions where none of
1012                  * them matches this file's extensions.
1013                  */
1014                 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1015                         /*
1016                          * Does this type have extensions and is this file's
1017                          * extension one of them?
1018                          */
1019                         if (open_routines[i].extensions != NULL &&
1020                             !heuristic_uses_extension(i, extension)) {
1021                                 /* Yes and no. */
1022                                 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1023                                         /* Error - give up */
1024                                         g_free(extension);
1025                                         wtap_close(wth);
1026                                         return NULL;
1027                                 }
1028
1029                                 /* Set wth with wslua data if any - this is how we pass the data
1030                                  * to the file reader, kind of like priv but not free'd later.
1031                                  */
1032                                 wth->wslua_data = open_routines[i].wslua_data;
1033
1034                                 switch ((*open_routines[i].open_routine)(wth,
1035                                     err, err_info)) {
1036
1037                                 case WTAP_OPEN_ERROR:
1038                                         /* Error - give up */
1039                                         g_free(extension);
1040                                         wtap_close(wth);
1041                                         return NULL;
1042
1043                                 case WTAP_OPEN_NOT_MINE:
1044                                         /* No error, but not that type of file */
1045                                         break;
1046
1047                                 case WTAP_OPEN_MINE:
1048                                         /* We found the file type */
1049                                         g_free(extension);
1050                                         goto success;
1051                                 }
1052                         }
1053                 }
1054                 g_free(extension);
1055         } else {
1056                 /* No - try all the heuristics types in order. */
1057                 for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
1058
1059                         if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
1060                                 /* Error - give up */
1061                                 wtap_close(wth);
1062                                 return NULL;
1063                         }
1064
1065                         /* Set wth with wslua data if any - this is how we pass the data
1066                          * to the file reader, kind of like priv but not free'd later.
1067                          */
1068                         wth->wslua_data = open_routines[i].wslua_data;
1069
1070                         switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
1071
1072                         case WTAP_OPEN_ERROR:
1073                                 /* Error - give up */
1074                                 wtap_close(wth);
1075                                 return NULL;
1076
1077                         case WTAP_OPEN_NOT_MINE:
1078                                 /* No error, but not that type of file */
1079                                 break;
1080
1081                         case WTAP_OPEN_MINE:
1082                                 /* We found the file type */
1083                                 goto success;
1084                         }
1085                 }
1086         }
1087
1088 fail:
1089
1090         /* Well, it's not one of the types of file we know about. */
1091         wtap_close(wth);
1092         *err = WTAP_ERR_FILE_UNKNOWN_FORMAT;
1093         return NULL;
1094
1095 success:
1096         wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
1097         ws_buffer_init(wth->frame_buffer, 1500);
1098
1099         if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
1100                 (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
1101
1102                 wtap_optionblock_t descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
1103                 wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
1104
1105                 descr_mand->wtap_encap = wth->file_encap;
1106                 if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
1107                         descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */
1108                         wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9);
1109                         descr_mand->tsprecision = WTAP_TSPREC_NSEC;
1110                 } else {
1111                         descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
1112                         wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6);
1113                         descr_mand->tsprecision = WTAP_TSPREC_USEC;
1114                 }
1115                 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
1116                 descr_mand->snap_len = wth->snapshot_length;
1117
1118                 descr_mand->num_stat_entries = 0;          /* Number of ISB:s */
1119                 descr_mand->interface_statistics = NULL;
1120                 g_array_append_val(wth->interface_data, descr);
1121
1122         }
1123         return wth;
1124 }
1125
1126 /*
1127  * Given the pathname of the file we just closed with wtap_fdclose(), attempt
1128  * to reopen that file and assign the new file descriptor(s) to the sequential
1129  * stream and, if do_random is TRUE, to the random stream.  Used on Windows
1130  * after the rename of a file we had open was done or if the rename of a
1131  * file on top of a file we had open failed.
1132  *
1133  * This is only required by Wireshark, not TShark, and, at the point that
1134  * Wireshark is doing this, the sequential stream is closed, and the
1135  * random stream is open, so this refuses to open pipes, and only
1136  * reopens the random stream.
1137  */
1138 gboolean
1139 wtap_fdreopen(wtap *wth, const char *filename, int *err)
1140 {
1141         ws_statb64 statb;
1142
1143         /*
1144          * We need two independent descriptors for random access, so
1145          * they have different file positions.  If we're opening the
1146          * standard input, we can only dup it to get additional
1147          * descriptors, so we can't have two independent descriptors,
1148          * and thus can't do random access.
1149          */
1150         if (strcmp(filename, "-") == 0) {
1151                 *err = WTAP_ERR_RANDOM_OPEN_STDIN;
1152                 return FALSE;
1153         }
1154
1155         /* First, make sure the file is valid */
1156         if (ws_stat64(filename, &statb) < 0) {
1157                 *err = errno;
1158                 return FALSE;
1159         }
1160         if (S_ISFIFO(statb.st_mode)) {
1161                 /*
1162                  * Opens of FIFOs are not allowed; see above.
1163                  */
1164                 *err = WTAP_ERR_RANDOM_OPEN_PIPE;
1165                 return FALSE;
1166         } else if (S_ISDIR(statb.st_mode)) {
1167                 /*
1168                  * Return different errors for "this is a directory"
1169                  * and "this is some random special file type", so
1170                  * the user can get a potentially more helpful error.
1171                  */
1172                 *err = EISDIR;
1173                 return FALSE;
1174         } else if (! S_ISREG(statb.st_mode)) {
1175                 *err = WTAP_ERR_NOT_REGULAR_FILE;
1176                 return FALSE;
1177         }
1178
1179         /* Open the file */
1180         errno = WTAP_ERR_CANT_OPEN;
1181         if (!file_fdreopen(wth->random_fh, filename)) {
1182                 *err = errno;
1183                 return FALSE;
1184         }
1185         return TRUE;
1186 }
1187
1188 /* Table of the file types and subtypes for which we have built-in support.
1189    Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending
1190    order.
1191
1192    These are used to report what type and subtype a given file is and
1193    to let the user select a format when writing out packets.
1194
1195    This table is what we start with, but it can be modified.
1196    If we need to modify it, we allocate a GArray, copy the entries
1197    in the above table to that GArray, use the copy as the table, and
1198    make all changes to the copy. */
1199 static const struct file_type_subtype_info dump_open_table_base[] = {
1200         /* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN (only used internally for initialization) */
1201         { NULL, NULL, NULL, NULL,
1202           FALSE, FALSE, 0,
1203           NULL, NULL, NULL },
1204
1205         /* WTAP_FILE_TYPE_SUBTYPE_PCAP */
1206         /* Gianluca Varenni suggests that we add "deprecated" to the description. */
1207         { "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp",
1208           FALSE, FALSE, 0,
1209           libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1210
1211         /* WTAP_FILE_TYPE_SUBTYPE_PCAPNG */
1212         { "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
1213           FALSE, TRUE, WTAP_COMMENT_PER_SECTION|WTAP_COMMENT_PER_INTERFACE|WTAP_COMMENT_PER_PACKET,
1214           pcapng_dump_can_write_encap, pcapng_dump_open, NULL },
1215
1216         /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC */
1217         { "Wireshark - nanosecond libpcap", "nseclibpcap", "pcap", "cap;dmp",
1218           FALSE, FALSE, 0,
1219           libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1220
1221         /* WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX */
1222         { "AIX tcpdump - libpcap", "aixlibpcap", "pcap", "cap;dmp",
1223           FALSE, FALSE, 0,
1224           NULL, NULL, NULL },
1225
1226         /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029 */
1227         { "Modified tcpdump - libpcap", "modlibpcap", "pcap", "cap;dmp",
1228           FALSE, FALSE, 0,
1229           libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1230
1231         /* WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA */
1232         { "Nokia tcpdump - libpcap ", "nokialibpcap", "pcap", "cap;dmp",
1233           FALSE, FALSE, 0,
1234           libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1235
1236         /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417 */
1237         { "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "pcap", "cap;dmp",
1238           FALSE, FALSE, 0,
1239           libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1240
1241         /* WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915 */
1242         { "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "pcap", "cap;dmp",
1243           FALSE, FALSE, 0,
1244           libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
1245
1246         /* WTAP_FILE_TYPE_SUBTYPE_5VIEWS */
1247         { "InfoVista 5View capture", "5views", "5vw", NULL,
1248            TRUE, FALSE, 0,
1249           _5views_dump_can_write_encap, _5views_dump_open, NULL },
1250
1251         /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_1_0 */
1252         { "AIX iptrace 1.0", "iptrace_1", NULL, NULL,
1253           FALSE, FALSE, 0,
1254           NULL, NULL, NULL },
1255
1256         /* WTAP_FILE_TYPE_SUBTYPE_IPTRACE_2_0 */
1257         { "AIX iptrace 2.0", "iptrace_2", NULL, NULL,
1258           FALSE, FALSE, 0,
1259           NULL, NULL, NULL },
1260
1261         /* WTAP_FILE_TYPE_SUBTYPE_BER */
1262         { "ASN.1 Basic Encoding Rules", "ber", NULL, NULL,
1263           FALSE, FALSE, 0,
1264           NULL, NULL, NULL },
1265
1266         /* WTAP_FILE_TYPE_SUBTYPE_HCIDUMP */
1267         { "Bluetooth HCI dump", "hcidump", NULL, NULL,
1268           FALSE, FALSE, 0,
1269           NULL, NULL, NULL },
1270
1271         /* WTAP_FILE_TYPE_SUBTYPE_CATAPULT_DCT2000 */
1272         { "Catapult DCT2000 trace (.out format)", "dct2000", "out", NULL,
1273           FALSE, FALSE, 0,
1274           catapult_dct2000_dump_can_write_encap, catapult_dct2000_dump_open, NULL },
1275
1276         /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_OLD */
1277         { "Cinco Networks NetXRay 1.x", "netxray1", "cap", NULL,
1278           TRUE, FALSE, 0,
1279           NULL, NULL, NULL },
1280
1281         /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_0 */
1282         { "Cinco Networks NetXRay 2.0 or later", "netxray2", "cap", NULL,
1283           TRUE, FALSE, 0,
1284           NULL, NULL, NULL },
1285
1286         /* WTAP_FILE_TYPE_SUBTYPE_COSINE */
1287         { "CoSine IPSX L2 capture", "cosine", "txt", NULL,
1288           FALSE, FALSE, 0,
1289           NULL, NULL, NULL },
1290
1291         /* WTAP_FILE_TYPE_SUBTYPE_CSIDS */
1292         { "CSIDS IPLog", "csids", NULL, NULL,
1293           FALSE, FALSE, 0,
1294           NULL, NULL, NULL },
1295
1296         /* WTAP_FILE_TYPE_SUBTYPE_DBS_ETHERWATCH */
1297         { "DBS Etherwatch (VMS)", "etherwatch", "txt", NULL,
1298           FALSE, FALSE, 0,
1299           NULL, NULL, NULL },
1300
1301         /* WTAP_FILE_TYPE_SUBTYPE_ERF */
1302         { "Endace ERF capture", "erf", "erf", NULL,
1303           FALSE, FALSE, 0,
1304           erf_dump_can_write_encap, erf_dump_open, NULL },
1305
1306         /* WTAP_FILE_TYPE_SUBTYPE_EYESDN */
1307         { "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "trc", NULL,
1308            FALSE, FALSE, 0,
1309            eyesdn_dump_can_write_encap, eyesdn_dump_open, NULL },
1310
1311         /* WTAP_FILE_TYPE_SUBTYPE_NETTL */
1312         { "HP-UX nettl trace", "nettl", "trc0", "trc1",
1313           FALSE, FALSE, 0,
1314           nettl_dump_can_write_encap, nettl_dump_open, NULL },
1315
1316         /* WTAP_FILE_TYPE_SUBTYPE_ISERIES */
1317         { "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "txt", NULL,
1318           FALSE, FALSE, 0,
1319           NULL, NULL, NULL },
1320
1321         /* WTAP_FILE_TYPE_SUBTYPE_ISERIES_UNICODE */
1322         { "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "txt", NULL,
1323           FALSE, FALSE, 0,
1324           NULL, NULL, NULL },
1325
1326         /* WTAP_FILE_TYPE_SUBTYPE_I4BTRACE */
1327         { "I4B ISDN trace", "i4btrace", NULL, NULL,
1328           FALSE, FALSE, 0,
1329           NULL, NULL, NULL },
1330
1331         /* WTAP_FILE_TYPE_SUBTYPE_ASCEND */
1332         { "Lucent/Ascend access server trace", "ascend", "txt", NULL,
1333           FALSE, FALSE, 0,
1334           NULL, NULL, NULL },
1335
1336         /* WTAP_FILE_TYPE_SUBTYPE_NETMON_1_x */
1337         { "Microsoft NetMon 1.x", "netmon1", "cap", NULL,
1338           TRUE, FALSE, 0,
1339           netmon_dump_can_write_encap_1_x, netmon_dump_open, NULL },
1340
1341         /* WTAP_FILE_TYPE_SUBTYPE_NETMON_2_x */
1342         { "Microsoft NetMon 2.x", "netmon2", "cap", NULL,
1343           TRUE, FALSE, 0,
1344           netmon_dump_can_write_encap_2_x, netmon_dump_open, NULL },
1345
1346         /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_UNCOMPRESSED */
1347         { "Sniffer (DOS)", "ngsniffer", "cap", "enc;trc;fdc;syc",
1348           FALSE, FALSE, 0,
1349           ngsniffer_dump_can_write_encap, ngsniffer_dump_open, NULL },
1350
1351         /* WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_COMPRESSED */
1352         { "Sniffer (DOS), compressed", "ngsniffer_comp", "cap", "enc;trc;fdc;syc",
1353           FALSE, FALSE, 0,
1354           NULL, NULL, NULL },
1355
1356         /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_1 */
1357         { "NetXray, Sniffer (Windows) 1.1", "ngwsniffer_1_1", "cap", NULL,
1358           TRUE, FALSE, 0,
1359           netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1, NULL },
1360
1361         /* WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x */
1362         { "Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "cap", "caz",
1363           TRUE, FALSE, 0,
1364           netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0, NULL },
1365
1366         /* WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS */
1367         { "Network Instruments Observer", "niobserver", "bfr", NULL,
1368           FALSE, FALSE, 0,
1369           network_instruments_dump_can_write_encap, network_instruments_dump_open, NULL },
1370
1371         /* WTAP_FILE_TYPE_SUBTYPE_LANALYZER */
1372         { "Novell LANalyzer","lanalyzer", "tr1", NULL,
1373           TRUE, FALSE, 0,
1374           lanalyzer_dump_can_write_encap, lanalyzer_dump_open, NULL },
1375
1376         /* WTAP_FILE_TYPE_SUBTYPE_PPPDUMP */
1377         { "pppd log (pppdump format)", "pppd", NULL, NULL,
1378           FALSE, FALSE, 0,
1379           NULL, NULL, NULL },
1380
1381         /* WTAP_FILE_TYPE_SUBTYPE_RADCOM */
1382         { "RADCOM WAN/LAN analyzer", "radcom", NULL, NULL,
1383           FALSE, FALSE, 0,
1384           NULL, NULL, NULL },
1385
1386         /* WTAP_FILE_TYPE_SUBTYPE_SNOOP */
1387         { "Sun snoop", "snoop", "snoop", "cap",
1388           FALSE, FALSE, 0,
1389           snoop_dump_can_write_encap, snoop_dump_open, NULL },
1390
1391         /* WTAP_FILE_TYPE_SUBTYPE_SHOMITI */
1392         { "Shomiti/Finisar Surveyor", "shomiti", "cap", NULL,
1393           FALSE, FALSE, 0,
1394           NULL, NULL, NULL },
1395
1396         /* WTAP_FILE_TYPE_SUBTYPE_VMS */
1397         { "TCPIPtrace (VMS)", "tcpiptrace", "txt", NULL,
1398           FALSE, FALSE, 0,
1399           NULL, NULL, NULL },
1400
1401         /* WTAP_FILE_TYPE_SUBTYPE_K12 */
1402         { "Tektronix K12xx 32-bit .rf5 format", "rf5", "rf5", NULL,
1403            TRUE, FALSE, 0,
1404            k12_dump_can_write_encap, k12_dump_open, NULL },
1405
1406         /* WTAP_FILE_TYPE_SUBTYPE_TOSHIBA */
1407         { "Toshiba Compact ISDN Router snoop", "toshiba", "txt", NULL,
1408           FALSE, FALSE, 0,
1409           NULL, NULL, NULL },
1410
1411         /* WTAP_FILE_TYPE_SUBTYPE_VISUAL_NETWORKS */
1412         { "Visual Networks traffic capture", "visual", NULL, NULL,
1413           TRUE, FALSE, 0,
1414           visual_dump_can_write_encap, visual_dump_open, NULL },
1415
1416         /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V56 */
1417         { "Savvius classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
1418           FALSE, FALSE, 0,
1419           NULL, NULL, NULL },
1420
1421         /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V7 */
1422         { "Savvius classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
1423           FALSE, FALSE, 0,
1424           NULL, NULL, NULL },
1425
1426         /* WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED */
1427         { "Savvius tagged", "peektagged", "pkt", "tpc;apc;wpz",
1428           FALSE, FALSE, 0,
1429           NULL, NULL, NULL },
1430
1431         /* WTAP_FILE_TYPE_SUBTYPE_MPEG */
1432         { "MPEG", "mpeg", "mpeg", "mpg;mp3",
1433           FALSE, FALSE, 0,
1434           NULL, NULL, NULL },
1435
1436         /* WTAP_FILE_TYPE_SUBTYPE_K12TEXT  */
1437         { "K12 text file", "k12text", "txt", NULL,
1438           FALSE, FALSE, 0,
1439           k12text_dump_can_write_encap, k12text_dump_open, NULL },
1440
1441         /* WTAP_FILE_TYPE_SUBTYPE_NETSCREEN */
1442         { "NetScreen snoop text file", "netscreen", "txt", NULL,
1443           FALSE, FALSE, 0,
1444           NULL, NULL, NULL },
1445
1446         /* WTAP_FILE_TYPE_SUBTYPE_COMMVIEW */
1447         { "TamoSoft CommView", "commview", "ncf", NULL,
1448           FALSE, FALSE, 0,
1449           commview_dump_can_write_encap, commview_dump_open, NULL },
1450
1451         /* WTAP_FILE_TYPE_SUBTYPE_BTSNOOP */
1452         { "Symbian OS btsnoop", "btsnoop", "log", NULL,
1453           FALSE, FALSE, 0,
1454           btsnoop_dump_can_write_encap, btsnoop_dump_open_h4, NULL },
1455
1456         /* WTAP_FILE_TYPE_SUBTYPE_TNEF */
1457         { "Transport-Neutral Encapsulation Format", "tnef", NULL, NULL,
1458           FALSE, FALSE, 0,
1459           NULL, NULL, NULL },
1460
1461         /* WTAP_FILE_TYPE_SUBTYPE_DCT3TRACE */
1462         { "Gammu DCT3 trace", "dct3trace", "xml", NULL,
1463           FALSE, FALSE, 0,
1464           NULL, NULL, NULL },
1465
1466         /* WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER */
1467         { "OS X PacketLogger", "pklg", "pklg", NULL,
1468           FALSE, FALSE, 0,
1469           NULL, NULL, NULL },
1470
1471         /* WTAP_FILE_TYPE_SUBTYPE_DAINTREE_SNA */
1472         { "Daintree SNA", "dsna", "dcf", NULL,
1473           FALSE, FALSE, 0,
1474           NULL, NULL, NULL },
1475
1476         /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0 */
1477         { "NetScaler Trace (Version 1.0)", "nstrace10", NULL, NULL,
1478           TRUE, FALSE, 0,
1479           nstrace_10_dump_can_write_encap, nstrace_dump_open, NULL },
1480
1481         /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0 */
1482         { "NetScaler Trace (Version 2.0)", "nstrace20", "cap", NULL,
1483           TRUE, FALSE, 0,
1484           nstrace_20_dump_can_write_encap, nstrace_dump_open, NULL },
1485
1486         /* WTAP_FILE_TYPE_SUBTYPE_JPEG_JFIF */
1487         { "JPEG/JFIF", "jpeg", "jpg", "jpeg;jfif",
1488           FALSE, FALSE, 0,
1489           NULL, NULL, NULL },
1490
1491         /* WTAP_FILE_TYPE_SUBTYPE_IPFIX */
1492         { "IPFIX File Format", "ipfix", "pfx", "ipfix",
1493           FALSE, FALSE, 0,
1494           NULL, NULL, NULL },
1495
1496         /* WTAP_ENCAP_MIME */
1497         { "MIME File Format", "mime", NULL, NULL,
1498            FALSE, FALSE, 0,
1499            NULL, NULL, NULL },
1500
1501         /* WTAP_FILE_TYPE_SUBTYPE_AETHRA */
1502         { "Aethra .aps file", "aethra", "aps", NULL,
1503           FALSE, FALSE, 0,
1504           NULL, NULL, NULL },
1505
1506         /* WTAP_FILE_TYPE_SUBTYPE_MPEG_2_TS */
1507         { "MPEG2 transport stream", "mp2t", "mp2t", "ts;mpg",
1508           FALSE, FALSE, 0,
1509           NULL, NULL, NULL },
1510
1511         /* WTAP_FILE_TYPE_SUBTYPE_VWR_80211 */
1512         { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr80211", "vwr", NULL,
1513           FALSE, FALSE, 0,
1514           NULL, NULL, NULL },
1515
1516         /* WTAP_FILE_TYPE_SUBTYPE_VWR_ETH */
1517         { "Ixia IxVeriWave .vwr Raw Ethernet Capture", "vwreth", "vwr", NULL,
1518           FALSE, FALSE, 0,
1519           NULL, NULL, NULL },
1520
1521         /* WTAP_FILE_TYPE_SUBTYPE_CAMINS */
1522         { "CAM Inspector file", "camins", "camins", NULL,
1523           FALSE, FALSE, 0,
1524           NULL, NULL, NULL },
1525
1526         /* WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 */
1527         { "STANAG 4607 Format", "stanag4607", NULL, NULL,
1528           FALSE, FALSE, 0,
1529           NULL, NULL, NULL },
1530
1531         /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 */
1532         { "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
1533           TRUE, FALSE, 0,
1534           nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
1535
1536         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT */
1537         { "Android Logcat Binary format", "logcat", "logcat", NULL,
1538           FALSE, FALSE, 0,
1539           logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
1540
1541         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF */
1542         { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
1543           FALSE, FALSE, 0,
1544           logcat_text_brief_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
1545
1546         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS */
1547         { "Android Logcat Process text format", "logcat-process", NULL, NULL,
1548           FALSE, FALSE, 0,
1549           logcat_text_process_dump_can_write_encap, logcat_text_process_dump_open, NULL },
1550
1551         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG */
1552         { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
1553           FALSE, FALSE, 0,
1554           logcat_text_tag_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
1555
1556         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD */
1557         { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
1558            FALSE, FALSE, 0,
1559            logcat_text_thread_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
1560
1561         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME */
1562         { "Android Logcat Time text format", "logcat-time", NULL, NULL,
1563           FALSE, FALSE, 0,
1564           logcat_text_time_dump_can_write_encap, logcat_text_time_dump_open, NULL },
1565
1566         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME */
1567         { "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
1568           FALSE, FALSE, 0,
1569           logcat_text_threadtime_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
1570
1571         /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG */
1572         { "Android Logcat Long text format", "logcat-long", NULL, NULL,
1573           FALSE, FALSE, 0,
1574           logcat_text_long_dump_can_write_encap, logcat_text_long_dump_open, NULL },
1575
1576         /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA */
1577         { "Colasoft Capsa format", "capsa", "cscpkt", NULL,
1578           FALSE, FALSE, 0,
1579           NULL, NULL, NULL },
1580
1581         /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER */
1582         { "Colasoft Packet Builder format", "colasoft-pb", "cscpkt", NULL,
1583           FALSE, FALSE, 0,
1584           NULL, NULL, NULL },
1585
1586         /* WTAP_FILE_TYPE_SUBTYPE_JSON */
1587         { "JavaScript Object Notation", "json", "json", "NULL",
1588           FALSE, FALSE, 0,
1589           NULL, NULL, NULL },
1590
1591         /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 */
1592         { "NetScaler Trace (Version 3.5)", "nstrace35", "cap", NULL,
1593           TRUE, FALSE, 0,
1594           nstrace_35_dump_can_write_encap, nstrace_dump_open, NULL },
1595
1596         /* WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423 */
1597         { "3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
1598           FALSE, FALSE, 0,
1599           NULL, NULL, NULL },
1600
1601         /* WTAP_FILE_TYPE_MPLOG */
1602         { "Micropross mplog file", "mplog", "mplog", NULL,
1603           FALSE, FALSE, 0,
1604           NULL, NULL, NULL }
1605 };
1606
1607 /*
1608  * Pointer to the table we're currently using.  It's initialized to point
1609  * to the static table, but, if we have to allocate the GArray, it's
1610  * changed to point to the data in the GArray.
1611  */
1612 static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
1613
1614 /*
1615  * Number of elements in the table we're currently using.  It's initialized
1616  * to the number of elements in the static table, but, if we have to
1617  * allocate the GArray, it's changed to have the size of the GArray.
1618  */
1619 gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
1620
1621 /*
1622  * Pointer to the GArray; NULL until it's needed.
1623  */
1624 static GArray*  dump_open_table_arr = NULL;
1625
1626 /*
1627  * Create the GArray from the static table if it hasn't already been created.
1628  */
1629 static void
1630 init_file_types_subtypes_garray(void)
1631 {
1632         if (dump_open_table_arr) return;
1633
1634         dump_open_table_arr = g_array_new(FALSE,TRUE,sizeof(struct file_type_subtype_info));
1635
1636         g_array_append_vals(dump_open_table_arr,dump_open_table_base,wtap_num_file_types_subtypes);
1637
1638         dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1639 }
1640
1641 /* if subtype is WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, then create a new subtype as well as register it, else replace the
1642    existing entry in that spot */
1643 int
1644 wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype)
1645 {
1646         struct file_type_subtype_info* finfo;
1647
1648         if (!fi || !fi->name || !fi->short_name || subtype > wtap_num_file_types_subtypes) {
1649                 g_error("no file type info or invalid file type to register");
1650                 return subtype;
1651         }
1652
1653         /* do we want a new registration? */
1654         if (subtype == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
1655                 /* register a new one; first verify there isn't one named this already */
1656                 if (wtap_short_string_to_file_type_subtype(fi->short_name) > -1 ) {
1657                         g_error("file type short name already exists");
1658                         return subtype;
1659                 }
1660
1661                 /*
1662                  * Create the GArray if it hasn't already been created.
1663                  */
1664                 init_file_types_subtypes_garray();
1665
1666                 g_array_append_val(dump_open_table_arr,*fi);
1667
1668                 dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
1669
1670                 return wtap_num_file_types_subtypes++;
1671         }
1672
1673         /* re-register an existing one - verify the short names do match (sanity check really) */
1674         if (!dump_open_table[subtype].short_name || strcmp(dump_open_table[subtype].short_name,fi->short_name) != 0) {
1675                 g_error("invalid file type name given to register");
1676                 return subtype;
1677         }
1678
1679         /*
1680          * Create the GArray if it hasn't already been created.
1681          */
1682         init_file_types_subtypes_garray();
1683
1684         /*
1685          * Get the pointer from the GArray, so that we get a non-const
1686          * pointer.
1687          */
1688         finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
1689         /*finfo->name = fi->name;*/
1690         /*finfo->short_name = fi->short_name;*/
1691         finfo->default_file_extension     = fi->default_file_extension;
1692         finfo->additional_file_extensions = fi->additional_file_extensions;
1693         finfo->writing_must_seek          = fi->writing_must_seek;
1694         finfo->has_name_resolution        = fi->has_name_resolution;
1695         finfo->supported_comment_types    = fi->supported_comment_types;
1696         finfo->can_write_encap            = fi->can_write_encap;
1697         finfo->dump_open                  = fi->dump_open;
1698         finfo->wslua_info                 = fi->wslua_info;
1699
1700         return subtype;
1701 }
1702
1703 /* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
1704  */
1705 void
1706 wtap_deregister_file_type_subtype(const int subtype)
1707 {
1708         struct file_type_subtype_info* finfo;
1709
1710         if (subtype < 0 || subtype >= wtap_num_file_types_subtypes) {
1711                 g_error("invalid file type to de-register");
1712                 return;
1713         }
1714
1715         /*
1716          * Create the GArray if it hasn't already been created.
1717          */
1718         init_file_types_subtypes_garray();
1719
1720         /*
1721          * Get the pointer from the GArray, so that we get a non-const
1722          * pointer.
1723          */
1724         finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
1725         /* unfortunately, it's not safe to null-out the name or short_name; bunch of other code doesn't guard aainst that, afaict */
1726         /*finfo->name = NULL;*/
1727         /*finfo->short_name = NULL;*/
1728         finfo->default_file_extension = NULL;
1729         finfo->additional_file_extensions = NULL;
1730         finfo->writing_must_seek = FALSE;
1731         finfo->has_name_resolution = FALSE;
1732         finfo->supported_comment_types = 0;
1733         finfo->can_write_encap = NULL;
1734         finfo->dump_open = NULL;
1735         finfo->wslua_info = NULL;
1736 }
1737
1738 int
1739 wtap_get_num_file_types_subtypes(void)
1740 {
1741         return wtap_num_file_types_subtypes;
1742 }
1743
1744 /*
1745  * Given a GArray of WTAP_ENCAP_ types, return the per-file encapsulation
1746  * type that would be needed to write out a file with those types.  If
1747  * there's only one type, it's that type, otherwise it's
1748  * WTAP_ENCAP_PER_PACKET.
1749  */
1750 int
1751 wtap_dump_file_encap_type(const GArray *file_encaps)
1752 {
1753         int encap;
1754
1755         encap = WTAP_ENCAP_PER_PACKET;
1756         if (file_encaps->len == 1) {
1757                 /* OK, use the one-and-only encapsulation type. */
1758                 encap = g_array_index(file_encaps, gint, 0);
1759         }
1760         return encap;
1761 }
1762
1763 static gboolean
1764 wtap_dump_can_write_encap(int filetype, int encap)
1765 {
1766         int result = 0;
1767
1768         if (filetype < 0 || filetype >= wtap_num_file_types_subtypes
1769             || dump_open_table[filetype].can_write_encap == NULL)
1770                 return FALSE;
1771
1772         result = (*dump_open_table[filetype].can_write_encap)(encap);
1773
1774         if (result != 0) {
1775                 /* if the err said to check wslua's can_write_encap, try that */
1776                 if (result == WTAP_ERR_CHECK_WSLUA
1777                         && dump_open_table[filetype].wslua_info != NULL
1778                         && dump_open_table[filetype].wslua_info->wslua_can_write_encap != NULL) {
1779
1780                         result = (*dump_open_table[filetype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[filetype].wslua_info->wslua_data);
1781
1782                 }
1783
1784                 if (result != 0)
1785                         return FALSE;
1786         }
1787
1788         return TRUE;
1789 }
1790
1791 /*
1792  * Return TRUE if a capture with a given GArray of encapsulation types
1793  * and a given bitset of comment types can be written in a specified
1794  * format, and FALSE if it can't.
1795  */
1796 static gboolean
1797 wtap_dump_can_write_format(int ft, const GArray *file_encaps,
1798     guint32 required_comment_types)
1799 {
1800         guint i;
1801
1802         /*
1803          * Can we write in this format?
1804          */
1805         if (!wtap_dump_can_open(ft)) {
1806                 /* No. */
1807                 return FALSE;
1808         }
1809
1810         /*
1811          * Yes.  Can we write out all the required comments in this
1812          * format?
1813          */
1814         if (!wtap_dump_supports_comment_types(ft, required_comment_types)) {
1815                 /* No. */
1816                 return FALSE;
1817         }
1818
1819         /*
1820          * Yes.  Is the required per-file encapsulation type supported?
1821          * This might be WTAP_ENCAP_PER_PACKET.
1822          */
1823         if (!wtap_dump_can_write_encap(ft, wtap_dump_file_encap_type(file_encaps))) {
1824                 /* No. */
1825                 return FALSE;
1826         }
1827
1828         /*
1829          * Yes.  Are all the individual encapsulation types supported?
1830          */
1831         for (i = 0; i < file_encaps->len; i++) {
1832                 if (!wtap_dump_can_write_encap(ft,
1833                     g_array_index(file_encaps, int, i))) {
1834                         /* No - one of them isn't. */
1835                         return FALSE;
1836                 }
1837         }
1838
1839         /* Yes - we're OK. */
1840         return TRUE;
1841 }
1842
1843 /**
1844  * Return TRUE if we can write a file with the given GArray of
1845  * encapsulation types and the given bitmask of comment types.
1846  */
1847 gboolean
1848 wtap_dump_can_write(const GArray *file_encaps, guint32 required_comment_types)
1849 {
1850         int ft;
1851
1852         for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1853                 /* To save a file with Wiretap, Wiretap has to handle that format,
1854                  * and its code to handle that format must be able to write a file
1855                  * with this file's encapsulation types.
1856                  */
1857                 if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
1858                         /* OK, we can write it out in this type. */
1859                         return TRUE;
1860                 }
1861         }
1862
1863         /* No, we couldn't save it in any format. */
1864         return FALSE;
1865 }
1866
1867 /**
1868  * Get a GArray of WTAP_FILE_TYPE_SUBTYPE_ values for file types/subtypes
1869  * that can be used to save a file of a given type/subtype with a given
1870  * GArray of encapsulation types and the given bitmask of comment types.
1871  */
1872 GArray *
1873 wtap_get_savable_file_types_subtypes(int file_type_subtype,
1874     const GArray *file_encaps, guint32 required_comment_types)
1875 {
1876         GArray *savable_file_types_subtypes;
1877         int ft;
1878         int default_file_type_subtype = -1;
1879         int other_file_type_subtype = -1;
1880
1881         /* Can we save this file in its own file type/subtype? */
1882         if (wtap_dump_can_write_format(file_type_subtype, file_encaps,
1883                                        required_comment_types)) {
1884                 /* Yes - make that the default file type/subtype. */
1885                 default_file_type_subtype = file_type_subtype;
1886         } else {
1887                 /* OK, find the first file type/subtype we *can* save it as. */
1888                 default_file_type_subtype = -1;
1889                 for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1890                         if (wtap_dump_can_write_format(ft, file_encaps,
1891                                                        required_comment_types)) {
1892                                 /* OK, got it. */
1893                                 default_file_type_subtype = ft;
1894                         }
1895                 }
1896         }
1897
1898         if (default_file_type_subtype == -1) {
1899                 /* We don't support writing this file as any file type/subtype. */
1900                 return NULL;
1901         }
1902
1903         /* Allocate the array. */
1904         savable_file_types_subtypes = g_array_new(FALSE, FALSE, (guint)sizeof (int));
1905
1906         /* Put the default file type/subtype first in the list. */
1907         g_array_append_val(savable_file_types_subtypes, default_file_type_subtype);
1908
1909         /* If the default is pcap, put pcap-NG right after it if we can
1910            also write it in pcap-NG format; otherwise, if the default is
1911            pcap-NG, put pcap right after it if we can also write it in
1912            pcap format. */
1913         if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
1914                 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, file_encaps,
1915                                                required_comment_types))
1916                         other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
1917         } else if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
1918                 if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAP, file_encaps,
1919                                                required_comment_types))
1920                         other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
1921         }
1922         if (other_file_type_subtype != -1)
1923                 g_array_append_val(savable_file_types_subtypes, other_file_type_subtype);
1924
1925         /* Add all the other file types/subtypes that work. */
1926         for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
1927                 if (ft == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1928                         continue;       /* not a real file type */
1929                 if (ft == default_file_type_subtype || ft == other_file_type_subtype)
1930                         continue;       /* we've already done this one */
1931                 if (wtap_dump_can_write_format(ft, file_encaps,
1932                                                required_comment_types)) {
1933                         /* OK, we can write it out in this type. */
1934                         g_array_append_val(savable_file_types_subtypes, ft);
1935                 }
1936         }
1937
1938         return savable_file_types_subtypes;
1939 }
1940
1941 /* Name that should be somewhat descriptive. */
1942 const char *
1943 wtap_file_type_subtype_string(int file_type_subtype)
1944 {
1945         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes) {
1946                 g_error("Unknown capture file type %d", file_type_subtype);
1947                 /** g_error() does an abort() and thus never returns **/
1948                 return "";
1949         } else
1950                 return dump_open_table[file_type_subtype].name;
1951 }
1952
1953 /* Name to use in, say, a command-line flag specifying the type/subtype. */
1954 const char *
1955 wtap_file_type_subtype_short_string(int file_type_subtype)
1956 {
1957         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
1958                 return NULL;
1959         else
1960                 return dump_open_table[file_type_subtype].short_name;
1961 }
1962
1963 /* Translate a short name to a capture file type/subtype. */
1964 int
1965 wtap_short_string_to_file_type_subtype(const char *short_name)
1966 {
1967         int file_type_subtype;
1968
1969         for (file_type_subtype = 0; file_type_subtype < wtap_num_file_types_subtypes; file_type_subtype++) {
1970                 if (dump_open_table[file_type_subtype].short_name != NULL &&
1971                     strcmp(short_name, dump_open_table[file_type_subtype].short_name) == 0)
1972                         return file_type_subtype;
1973         }
1974
1975         /*
1976          * We now call the "libpcap" file format just "pcap", but we
1977          * allow it to be specified as "libpcap" as well, for
1978          * backwards compatibility.
1979          */
1980         if (strcmp(short_name, "libpcap") == 0)
1981                 return WTAP_FILE_TYPE_SUBTYPE_PCAP;
1982
1983         return -1;      /* no such file type, or we can't write it */
1984 }
1985
1986 static GSList *
1987 add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
1988     const char **compressed_file_extensions)
1989 {
1990         gchar **extensions_set, **extensionp;
1991         gchar *extension;
1992
1993         /*
1994          * Add the default extension, and all compressed variants of
1995          * it.
1996          */
1997         extensions = add_extensions(extensions,
1998             dump_open_table[file_type_subtype].default_file_extension,
1999             compressed_file_extensions);
2000
2001         if (dump_open_table[file_type_subtype].additional_file_extensions != NULL) {
2002                 /*
2003                  * We have additional extensions; add them.
2004                  *
2005                  * First, split the extension-list string into a set of
2006                  * extensions.
2007                  */
2008                 extensions_set = g_strsplit(dump_open_table[file_type_subtype].additional_file_extensions,
2009                     ";", 0);
2010
2011                 /*
2012                  * Add each of those extensions to the list.
2013                  */
2014                 for (extensionp = extensions_set; *extensionp != NULL;
2015                     extensionp++) {
2016                         extension = *extensionp;
2017
2018                         /*
2019                          * Add the extension, and all compressed variants
2020                          * of it.
2021                          */
2022                         extensions = add_extensions(extensions, extension,
2023                             compressed_file_extensions);
2024                 }
2025
2026                 g_strfreev(extensions_set);
2027         }
2028         return extensions;
2029 }
2030
2031 /* Return a list of file extensions that are used by the specified file type.
2032
2033    If include_compressed is TRUE, the list will include compressed
2034    extensions, e.g. not just "pcap" but also "pcap.gz" if we can read
2035    gzipped files.
2036
2037    All strings in the list are allocated with g_malloc() and must be freed
2038    with g_free(). */
2039 GSList *
2040 wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
2041 {
2042         GSList *extensions;
2043         static const char *no_compressed_extensions[] = {
2044                 NULL
2045         };
2046
2047         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2048                 return NULL;    /* not a valid file type */
2049
2050         if (dump_open_table[file_type_subtype].default_file_extension == NULL)
2051                 return NULL;    /* valid, but no extensions known */
2052
2053         extensions = NULL;      /* empty list, to start with */
2054
2055         /*
2056          * Add all this file type's extensions, with compressed
2057          * variants if include_compressed is true.
2058          */
2059         extensions = add_extensions_for_file_type_subtype(file_type_subtype, extensions,
2060             include_compressed ? compressed_file_extension_table : no_compressed_extensions);
2061
2062         return extensions;
2063 }
2064
2065 /*
2066  * Free a list returned by wtap_get_file_extension_type_extensions(),
2067  * wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
2068  */
2069 void
2070 wtap_free_extensions_list(GSList *extensions)
2071 {
2072         GSList *extension;
2073
2074         for (extension = extensions; extension != NULL;
2075             extension = g_slist_next(extension)) {
2076                 g_free(extension->data);
2077         }
2078         g_slist_free(extensions);
2079 }
2080
2081 /* Return the default file extension to use with the specified file type;
2082    that's just the extension, without any ".". */
2083 const char *
2084 wtap_default_file_extension(int file_type_subtype)
2085 {
2086         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2087                 return NULL;
2088         else
2089                 return dump_open_table[file_type_subtype].default_file_extension;
2090 }
2091
2092 gboolean
2093 wtap_dump_can_open(int file_type_subtype)
2094 {
2095         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2096             || dump_open_table[file_type_subtype].dump_open == NULL)
2097                 return FALSE;
2098
2099         return TRUE;
2100 }
2101
2102 #ifdef HAVE_ZLIB
2103 gboolean
2104 wtap_dump_can_compress(int file_type_subtype)
2105 {
2106         /*
2107          * If this is an unknown file type, or if we have to
2108          * seek when writing out a file with this file type,
2109          * return FALSE.
2110          */
2111         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2112             || dump_open_table[file_type_subtype].writing_must_seek)
2113                 return FALSE;
2114
2115         return TRUE;
2116 }
2117 #else
2118 gboolean
2119 wtap_dump_can_compress(int file_type_subtype _U_)
2120 {
2121         return FALSE;
2122 }
2123 #endif
2124
2125 gboolean
2126 wtap_dump_has_name_resolution(int file_type_subtype)
2127 {
2128         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
2129             || dump_open_table[file_type_subtype].has_name_resolution == FALSE)
2130                 return FALSE;
2131
2132         return TRUE;
2133 }
2134
2135 gboolean
2136 wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
2137 {
2138         guint32 supported_comment_types;
2139
2140         if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
2141                 return FALSE;
2142
2143         supported_comment_types = dump_open_table[file_type_subtype].supported_comment_types;
2144
2145         if ((comment_types & supported_comment_types) == comment_types)
2146                 return TRUE;
2147         return FALSE;
2148 }
2149
2150 static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean comressed, int *err);
2151 static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen,
2152                                         gboolean compressed, int *err);
2153 static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err);
2154
2155 static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename);
2156 static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
2157 static int wtap_dump_file_close(wtap_dumper *wdh);
2158
2159 static wtap_dumper *
2160 wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
2161                       wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2162                       wtap_optionblock_t nrb_hdr, int *err)
2163 {
2164         wtap_dumper *wdh;
2165         wtap_optionblock_t descr, file_int_data;
2166         wtapng_if_descr_mandatory_t *descr_mand, *file_int_data_mand;
2167
2168         /* Check whether we can open a capture file with that file type
2169            and that encapsulation. */
2170         if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
2171                 return NULL;
2172
2173         /* Allocate a data structure for the output stream. */
2174         wdh = wtap_dump_alloc_wdh(file_type_subtype, encap, snaplen, compressed, err);
2175         if (wdh == NULL)
2176                 return NULL;    /* couldn't allocate it */
2177
2178         /* Set Section Header Block data */
2179         wdh->shb_hdr = shb_hdr;
2180         /* Set Name Resolution Block data */
2181         wdh->nrb_hdr = nrb_hdr;
2182         /* Set Interface Description Block data */
2183         if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
2184                 guint itf_count;
2185
2186                 /* XXX: what free's this stuff? */
2187                 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2188                 for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
2189                         file_int_data = g_array_index(idb_inf->interface_data, wtap_optionblock_t, itf_count);
2190                         file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(file_int_data);
2191                         descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2192                         wtap_optionblock_copy_options(descr, file_int_data);
2193                         if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data_mand->wtap_encap)) {
2194                                 descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
2195                                 descr_mand->wtap_encap = encap;
2196                                 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
2197                         }
2198                         g_array_append_val(wdh->interface_data, descr);
2199                 }
2200         } else {
2201                 descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2202                 descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
2203                 descr_mand->wtap_encap = encap;
2204                 descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
2205                 descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
2206                 descr_mand->snap_len = snaplen;
2207                 wtap_optionblock_set_option_string(descr, OPT_IDB_NAME, "Unknown/not available in original file format(libpcap)");
2208
2209                 descr_mand->num_stat_entries = 0;          /* Number of ISB:s */
2210                 descr_mand->interface_statistics = NULL;
2211                 wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2212                 g_array_append_val(wdh->interface_data, descr);
2213         }
2214         return wdh;
2215 }
2216
2217 wtap_dumper *
2218 wtap_dump_open(const char *filename, int file_type_subtype, int encap,
2219                int snaplen, gboolean compressed, int *err)
2220 {
2221         return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2222 }
2223
2224 wtap_dumper *
2225 wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
2226                   int snaplen, gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2227                   wtap_optionblock_t nrb_hdr, int *err)
2228 {
2229         wtap_dumper *wdh;
2230         WFILE_T fh;
2231
2232         /* Allocate and initialize a data structure for the output stream. */
2233         wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2234             shb_hdr, idb_inf, nrb_hdr, err);
2235         if (wdh == NULL)
2236                 return NULL;
2237
2238         /* In case "fopen()" fails but doesn't set "errno", set "errno"
2239            to a generic "the open failed" error. */
2240         errno = WTAP_ERR_CANT_OPEN;
2241         fh = wtap_dump_file_open(wdh, filename);
2242         if (fh == NULL) {
2243                 *err = errno;
2244                 g_free(wdh);
2245                 return NULL;    /* can't create file */
2246         }
2247         wdh->fh = fh;
2248
2249         if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2250                 /* Get rid of the file we created; we couldn't finish
2251                    opening it. */
2252                 wtap_dump_file_close(wdh);
2253                 ws_unlink(filename);
2254                 g_free(wdh);
2255                 return NULL;
2256         }
2257         return wdh;
2258 }
2259
2260 wtap_dumper *
2261 wtap_dump_open_tempfile(char **filenamep, const char *pfx,
2262                         int file_type_subtype, int encap,
2263                         int snaplen, gboolean compressed, int *err)
2264 {
2265         return wtap_dump_open_tempfile_ng(filenamep, pfx, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
2266 }
2267
2268 wtap_dumper *
2269 wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
2270                            int file_type_subtype, int encap,
2271                            int snaplen, gboolean compressed,
2272                            wtap_optionblock_t shb_hdr,
2273                            wtapng_iface_descriptions_t *idb_inf,
2274                            wtap_optionblock_t nrb_hdr, int *err)
2275 {
2276         int fd;
2277         char *tmpname;
2278         wtap_dumper *wdh;
2279         WFILE_T fh;
2280
2281         /* No path name for the temporary file yet. */
2282         *filenamep = NULL;
2283
2284         /* Allocate and initialize a data structure for the output stream. */
2285         wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2286             shb_hdr, idb_inf, nrb_hdr, err);
2287         if (wdh == NULL)
2288                 return NULL;
2289
2290         /* Choose a random name for the file */
2291         fd = create_tempfile(&tmpname, pfx);
2292         if (fd == -1) {
2293                 *err = errno;
2294                 g_free(wdh);
2295                 return NULL;    /* can't create file */
2296         }
2297         *filenamep = tmpname;
2298
2299         /* In case "fopen()" fails but doesn't set "errno", set "errno"
2300            to a generic "the open failed" error. */
2301         errno = WTAP_ERR_CANT_OPEN;
2302         fh = wtap_dump_file_fdopen(wdh, fd);
2303         if (fh == NULL) {
2304                 *err = errno;
2305                 ws_close(fd);
2306                 g_free(wdh);
2307                 return NULL;    /* can't create file */
2308         }
2309         wdh->fh = fh;
2310
2311         if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2312                 /* Get rid of the file we created; we couldn't finish
2313                    opening it. */
2314                 wtap_dump_file_close(wdh);
2315                 ws_unlink(tmpname);
2316                 g_free(wdh);
2317                 return NULL;
2318         }
2319         return wdh;
2320 }
2321
2322 wtap_dumper *
2323 wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
2324                  gboolean compressed, int *err)
2325 {
2326         return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2327 }
2328
2329 wtap_dumper *
2330 wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
2331                     gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
2332                     wtap_optionblock_t nrb_hdr, int *err)
2333 {
2334         wtap_dumper *wdh;
2335         WFILE_T fh;
2336
2337         /* Allocate and initialize a data structure for the output stream. */
2338         wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2339             shb_hdr, idb_inf, nrb_hdr, err);
2340         if (wdh == NULL)
2341                 return NULL;
2342
2343         /* In case "fopen()" fails but doesn't set "errno", set "errno"
2344            to a generic "the open failed" error. */
2345         errno = WTAP_ERR_CANT_OPEN;
2346         fh = wtap_dump_file_fdopen(wdh, fd);
2347         if (fh == NULL) {
2348                 *err = errno;
2349                 g_free(wdh);
2350                 return NULL;    /* can't create standard I/O stream */
2351         }
2352         wdh->fh = fh;
2353
2354         if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2355                 wtap_dump_file_close(wdh);
2356                 g_free(wdh);
2357                 return NULL;
2358         }
2359         return wdh;
2360 }
2361
2362 wtap_dumper *
2363 wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
2364                       gboolean compressed, int *err)
2365 {
2366         return wtap_dump_open_stdout_ng(file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
2367 }
2368
2369 wtap_dumper *
2370 wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
2371                          gboolean compressed, wtap_optionblock_t shb_hdr,
2372                          wtapng_iface_descriptions_t *idb_inf,
2373                          wtap_optionblock_t nrb_hdr, int *err)
2374 {
2375         wtap_dumper *wdh;
2376         WFILE_T fh;
2377
2378         /* Allocate and initialize a data structure for the output stream. */
2379         wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
2380             shb_hdr, idb_inf, nrb_hdr, err);
2381         if (wdh == NULL)
2382                 return NULL;
2383
2384 #ifdef _WIN32
2385         /*
2386          * Put the standard output into binary mode.
2387          *
2388          * XXX - even if the file format we're writing is a text
2389          * format?
2390          */
2391         if (_setmode(1, O_BINARY) == -1) {
2392                 /* "Should not happen" */
2393                 *err = errno;
2394                 g_free(wdh);
2395                 return NULL;    /* couldn't put standard output in binary mode */
2396         }
2397 #endif
2398
2399         /* In case "fopen()" fails but doesn't set "errno", set "errno"
2400            to a generic "the open failed" error. */
2401         errno = WTAP_ERR_CANT_OPEN;
2402         fh = wtap_dump_file_fdopen(wdh, 1);
2403         if (fh == NULL) {
2404                 *err = errno;
2405                 g_free(wdh);
2406                 return NULL;    /* can't create standard I/O stream */
2407         }
2408         wdh->fh = fh;
2409         wdh->is_stdout = TRUE;
2410
2411         if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
2412                 wtap_dump_file_close(wdh);
2413                 g_free(wdh);
2414                 return NULL;
2415         }
2416         return wdh;
2417 }
2418
2419 static gboolean
2420 wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
2421 {
2422         if (!wtap_dump_can_open(file_type_subtype)) {
2423                 /* Invalid type, or type we don't know how to write. */
2424                 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2425                 return FALSE;
2426         }
2427
2428         /* OK, we know how to write that type; can we write the specified
2429            encapsulation type? */
2430         *err = (*dump_open_table[file_type_subtype].can_write_encap)(encap);
2431         /* if the err said to check wslua's can_write_encap, try that */
2432         if (*err == WTAP_ERR_CHECK_WSLUA
2433                 && dump_open_table[file_type_subtype].wslua_info != NULL
2434                 && dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap != NULL) {
2435
2436                 *err = (*dump_open_table[file_type_subtype].wslua_info->wslua_can_write_encap)(encap, dump_open_table[file_type_subtype].wslua_info->wslua_data);
2437
2438         }
2439
2440         if (*err != 0)
2441                 return FALSE;
2442
2443         /* if compression is wanted, do we support this for this file_type_subtype? */
2444         if(compressed && !wtap_dump_can_compress(file_type_subtype)) {
2445                 *err = WTAP_ERR_COMPRESSION_NOT_SUPPORTED;
2446                 return FALSE;
2447         }
2448
2449         /* All systems go! */
2450         return TRUE;
2451 }
2452
2453 static wtap_dumper *
2454 wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean compressed, int *err)
2455 {
2456         wtap_dumper *wdh;
2457
2458         wdh = (wtap_dumper *)g_malloc0(sizeof (wtap_dumper));
2459         if (wdh == NULL) {
2460                 *err = errno;
2461                 return NULL;
2462         }
2463
2464         wdh->file_type_subtype = file_type_subtype;
2465         wdh->snaplen = snaplen;
2466         wdh->encap = encap;
2467         wdh->compressed = compressed;
2468         wdh->wslua_data = NULL;
2469         return wdh;
2470 }
2471
2472 static gboolean
2473 wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
2474 {
2475         int fd;
2476         gboolean cant_seek;
2477
2478         /* Can we do a seek on the file descriptor?
2479            If not, note that fact. */
2480         if(compressed) {
2481                 cant_seek = TRUE;
2482         } else {
2483                 fd = ws_fileno((FILE *)wdh->fh);
2484                 if (ws_lseek64(fd, 1, SEEK_CUR) == (off_t) -1)
2485                         cant_seek = TRUE;
2486                 else {
2487                         /* Undo the seek. */
2488                         ws_lseek64(fd, 0, SEEK_SET);
2489                         cant_seek = FALSE;
2490                 }
2491         }
2492
2493         /* If this file type requires seeking, and we can't seek, fail. */
2494         if (dump_open_table[file_type_subtype].writing_must_seek && cant_seek) {
2495                 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
2496                 return FALSE;
2497         }
2498
2499         /* Set wdh with wslua data if any - this is how we pass the data
2500          * to the file writer.
2501          */
2502         if (dump_open_table[file_type_subtype].wslua_info)
2503                 wdh->wslua_data = dump_open_table[file_type_subtype].wslua_info->wslua_data;
2504
2505         /* Now try to open the file for writing. */
2506         if (!(*dump_open_table[file_type_subtype].dump_open)(wdh, err)) {
2507                 return FALSE;
2508         }
2509
2510         return TRUE;    /* success! */
2511 }
2512
2513 gboolean
2514 wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2515           const guint8 *pd, int *err, gchar **err_info)
2516 {
2517         *err = 0;
2518         *err_info = NULL;
2519         return (wdh->subtype_write)(wdh, phdr, pd, err, err_info);
2520 }
2521
2522 void
2523 wtap_dump_flush(wtap_dumper *wdh)
2524 {
2525 #ifdef HAVE_ZLIB
2526         if(wdh->compressed) {
2527                 gzwfile_flush((GZWFILE_T)wdh->fh);
2528         } else
2529 #endif
2530         {
2531                 fflush((FILE *)wdh->fh);
2532         }
2533 }
2534
2535 gboolean
2536 wtap_dump_close(wtap_dumper *wdh, int *err)
2537 {
2538         gboolean ret = TRUE;
2539
2540         if (wdh->subtype_finish != NULL) {
2541                 /* There's a finish routine for this dump stream. */
2542                 if (!(wdh->subtype_finish)(wdh, err))
2543                         ret = FALSE;
2544         }
2545         errno = WTAP_ERR_CANT_CLOSE;
2546         if (wtap_dump_file_close(wdh) == EOF) {
2547                 if (ret) {
2548                         /* The per-format finish function succeeded,
2549                            but the stream close didn't.  Save the
2550                            reason why, if our caller asked for it. */
2551                         if (err != NULL)
2552                                 *err = errno;
2553                 }
2554                 ret = FALSE;
2555         }
2556         if (wdh->priv != NULL)
2557                 g_free(wdh->priv);
2558         g_free(wdh);
2559         return ret;
2560 }
2561
2562 gint64
2563 wtap_get_bytes_dumped(wtap_dumper *wdh)
2564 {
2565         return wdh->bytes_dumped;
2566 }
2567
2568 void
2569 wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
2570 {
2571         wdh->bytes_dumped = bytes_dumped;
2572 }
2573
2574 gboolean
2575 wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
2576 {
2577         if (!wdh || wdh->file_type_subtype < 0 || wdh->file_type_subtype >= wtap_num_file_types_subtypes
2578                 || dump_open_table[wdh->file_type_subtype].has_name_resolution == FALSE)
2579                         return FALSE;
2580         wdh->addrinfo_lists = addrinfo_lists;
2581         return TRUE;
2582 }
2583
2584 /* internally open a file for writing (compressed or not) */
2585 #ifdef HAVE_ZLIB
2586 static WFILE_T
2587 wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
2588 {
2589         if(wdh->compressed) {
2590                 return gzwfile_open(filename);
2591         } else {
2592                 return ws_fopen(filename, "wb");
2593         }
2594 }
2595 #else
2596 static WFILE_T
2597 wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
2598 {
2599         return ws_fopen(filename, "wb");
2600 }
2601 #endif
2602
2603 /* internally open a file for writing (compressed or not) */
2604 #ifdef HAVE_ZLIB
2605 static WFILE_T
2606 wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
2607 {
2608         if(wdh->compressed) {
2609                 return gzwfile_fdopen(fd);
2610         } else {
2611                 return ws_fdopen(fd, "wb");
2612         }
2613 }
2614 #else
2615 static WFILE_T
2616 wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
2617 {
2618         return ws_fdopen(fd, "wb");
2619 }
2620 #endif
2621
2622 /* internally writing raw bytes (compressed or not) */
2623 gboolean
2624 wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize, int *err)
2625 {
2626         size_t nwritten;
2627
2628 #ifdef HAVE_ZLIB
2629         if (wdh->compressed) {
2630                 nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned int) bufsize);
2631                 /*
2632                  * gzwfile_write() returns 0 on error.
2633                  */
2634                 if (nwritten == 0) {
2635                         *err = gzwfile_geterr((GZWFILE_T)wdh->fh);
2636                         return FALSE;
2637                 }
2638         } else
2639 #endif
2640         {
2641                 errno = WTAP_ERR_CANT_WRITE;
2642                 nwritten = fwrite(buf, 1, bufsize, (FILE *)wdh->fh);
2643                 /*
2644                  * At least according to the Mac OS X man page,
2645                  * this can return a short count on an error.
2646                  */
2647                 if (nwritten != bufsize) {
2648                         if (ferror((FILE *)wdh->fh))
2649                                 *err = errno;
2650                         else
2651                                 *err = WTAP_ERR_SHORT_WRITE;
2652                         return FALSE;
2653                 }
2654         }
2655         return TRUE;
2656 }
2657
2658 /* internally close a file for writing (compressed or not) */
2659 static int
2660 wtap_dump_file_close(wtap_dumper *wdh)
2661 {
2662 #ifdef HAVE_ZLIB
2663         if(wdh->compressed) {
2664                 /*
2665                  * Tell gzwfile_close() whether to close the descriptor
2666                  * or not.
2667                  */
2668                 return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout);
2669         } else
2670 #endif
2671         {
2672                 /*
2673                  * Don't close the standard output.
2674                  *
2675                  * XXX - this really should do everything fclose() does,
2676                  * including freeing all allocated data structures,
2677                  * *except* for actually closing the file descriptor.
2678                  */
2679                 return wdh->is_stdout ? fflush((FILE *)wdh->fh) : fclose((FILE *)wdh->fh);
2680         }
2681 }
2682
2683 gint64
2684 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
2685 {
2686 #ifdef HAVE_ZLIB
2687         if(wdh->compressed) {
2688                 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2689                 return -1;
2690         } else
2691 #endif
2692         {
2693                 if (-1 == fseek((FILE *)wdh->fh, (long)offset, whence)) {
2694                         *err = errno;
2695                         return -1;
2696                 } else
2697                 {
2698                         return 0;
2699                 }
2700         }
2701 }
2702
2703 gint64
2704 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
2705 {
2706         gint64 rval;
2707 #ifdef HAVE_ZLIB
2708         if(wdh->compressed) {
2709                 *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
2710                 return -1;
2711         } else
2712 #endif
2713         {
2714                 if (-1 == (rval = ftell((FILE *)wdh->fh))) {
2715                         *err = errno;
2716                         return -1;
2717                 } else
2718                 {
2719                         return rval;
2720                 }
2721         }
2722 }
2723
2724 /*
2725  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2726  *
2727  * Local variables:
2728  * c-basic-offset: 8
2729  * tab-width: 8
2730  * indent-tabs-mode: t
2731  * End:
2732  *
2733  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2734  * :indentSize=8:tabSize=8:noTabs=false:
2735  */