4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * SPDX-License-Identifier: GPL-2.0-or-later
10 #define WS_LOG_DOMAIN LOG_DOMAIN_WIRETAP
17 #include <wsutil/file_util.h>
18 #include <wsutil/tempfile.h>
20 #include <wsutil/plugins.h>
22 #include <wsutil/ws_assert.h>
25 #include "wtap_modules.h"
26 #include "file_wrappers.h"
27 #include "required_file_handlers.h"
28 #include <wsutil/buffer.h>
29 #include <wsutil/str_util.h>
31 #include "lanalyzer.h"
32 #include "ngsniffer.h"
34 #include "ascendtext.h"
47 #include "peekclassic.h"
48 #include "peektagged.h"
50 #include "dbs-etherwatch.h"
57 #include "logcat_text.h"
62 #include "catapult_dct2000.h"
66 #include "netscreen.h"
72 #include "dct3trace.h"
73 #include "packetlogger.h"
74 #include "daintree-sna.h"
75 #include "netscaler.h"
76 #include "mime_file.h"
80 #include "stanag4607.h"
82 #include "nettrace_3gpp_32_423.h"
86 #include "ruby_marshal.h"
87 #include "systemd_journal.h"
90 #include "busmaster.h"
93 #include "eri_enb_log.h"
94 #include "autosar_dlt.h"
100 * Add an extension, and all compressed versions thereof if requested,
101 * to a GSList of extensions.
104 add_extensions(GSList
*extensions
, const char *extension
,
105 GSList
*compression_type_extensions
)
108 * Add the specified extension.
110 extensions
= g_slist_prepend(extensions
, g_strdup(extension
));
113 * Add whatever compressed versions we were supplied.
115 for (GSList
*compression_type_extension
= compression_type_extensions
;
116 compression_type_extension
!= NULL
;
117 compression_type_extension
= g_slist_next(compression_type_extension
)) {
118 extensions
= g_slist_prepend(extensions
,
119 ws_strdup_printf("%s.%s", extension
,
120 (const char *)compression_type_extension
->data
));
127 * File types that can be identified by file extensions.
129 * These are used in file open dialogs to offer choices of extensions
130 * for which to filter. Note that the first field can list more than
131 * one type of file, because, for example, ".cap" is a popular
132 * extension used by a number of capture file types.
134 * File types that *don't* have a file extension used for them should
135 * *not* be placed here; if there's nothing to put in the last field
136 * of the structure, don't put an entry here, not even one with an
137 * empty string for the extensions list.
139 * All added file types, regardless of extension or lack thereof,
140 * must also be added open_info_base[] below.
142 static const struct file_extension_info file_type_extensions_base
[] = {
143 { "Wireshark/tcpdump/... - pcap", true, "pcap;cap;dmp" },
144 { "Wireshark/... - pcapng", true, "pcapng;ntar;scap" },
145 { "Network Monitor, Surveyor, NetScaler", true, "cap" },
146 { "Sun snoop", true, "snoop" },
147 { "InfoVista 5View capture", true, "5vw" },
148 { "Sniffer (DOS)", true, "cap;enc;trc;fdc;syc" },
149 { "Cinco NetXRay, Sniffer (Windows)", true, "cap;caz" },
150 { "Endace ERF capture", true, "erf" },
151 { "EyeSDN USB S0/E1 ISDN trace format", true, "trc" },
152 { "HP-UX nettl trace", true, "trc0;trc1" },
153 { "Viavi Observer", true, "bfr" },
154 { "Colasoft Capsa", true, "cscpkt" },
155 { "Novell LANalyzer", true, "tr1" },
156 { "Tektronix K12xx 32-bit .rf5 format", true, "rf5" },
157 { "Savvius *Peek", true, "pkt;tpc;apc;wpz" },
158 { "Catapult DCT2000 trace (.out format)", true, "out" },
159 { "Micropross mplog", true, "mplog" },
160 { "TamoSoft CommView NCF", true, "ncf" },
161 { "TamoSoft CommView NCFX", true, "ncfx" },
162 { "Symbian OS btsnoop", true, "log" },
163 { "XML files (including Gammu DCT3 traces)", true, "xml" },
164 { "macOS PacketLogger", true, "pklg" },
165 { "Daintree SNA", true, "dcf" },
166 { "IPFIX File Format", true, "pfx;ipfix" },
167 { "Aethra .aps file", true, "aps" },
168 { "MPEG2 transport stream", true, "mp2t;ts;mpg" },
169 { "Ixia IxVeriWave .vwr Raw 802.11 Capture", true, "vwr" },
170 { "CAM Inspector file", true, "camins" },
171 { "BLF file", true, "blf" },
172 { "AUTOSAR DLT file", true, "dlt" },
173 { "MPEG files", false, "mpeg;mpg;mp3" },
174 { "Transport-Neutral Encapsulation Format", false, "tnef" },
175 { "JPEG/JFIF files", false, "jpg;jpeg;jfif" },
176 { "JavaScript Object Notation file", false, "json" },
177 { "MP4 file", false, "mp4" },
178 { "RTPDump file", false, "rtp;rtpdump" },
179 { "EMS file", false, "ems" },
182 #define N_FILE_TYPE_EXTENSIONS (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
184 static const struct file_extension_info
* file_type_extensions
;
186 static GArray
* file_type_extensions_arr
;
188 /* initialize the extensions array if it has not been initialized yet */
190 init_file_type_extensions(void)
193 if (file_type_extensions_arr
) return;
195 file_type_extensions_arr
= g_array_new(false,true,sizeof(struct file_extension_info
));
197 g_array_append_vals(file_type_extensions_arr
,file_type_extensions_base
,N_FILE_TYPE_EXTENSIONS
);
199 file_type_extensions
= (struct file_extension_info
*)(void *)file_type_extensions_arr
->data
;
203 wtap_register_file_type_extension(const struct file_extension_info
*ei
)
205 init_file_type_extensions();
207 g_array_append_val(file_type_extensions_arr
,*ei
);
209 file_type_extensions
= (const struct file_extension_info
*)(void *)file_type_extensions_arr
->data
;
213 wtap_get_num_file_type_extensions(void)
215 return file_type_extensions_arr
->len
;
219 wtap_get_file_extension_type_name(int extension_type
)
221 return file_type_extensions
[extension_type
].name
;
225 add_extensions_for_file_extensions_type(int extension_type
, GSList
*extensions
,
226 GSList
*compression_type_extensions
)
228 char **extensions_set
, **extensionp
, *extension
;
231 * Split the extension-list string into a set of extensions.
233 extensions_set
= g_strsplit(file_type_extensions
[extension_type
].extensions
,
237 * Add each of those extensions to the list.
239 for (extensionp
= extensions_set
; *extensionp
!= NULL
; extensionp
++) {
240 extension
= *extensionp
;
243 * Add the extension, and all compressed variants
246 extensions
= add_extensions(extensions
, extension
,
247 compression_type_extensions
);
250 g_strfreev(extensions_set
);
254 /* Return a list of file extensions that are used by the specified file
257 * All strings in the list are allocated with g_malloc() and must be freed
261 wtap_get_file_extension_type_extensions(unsigned extension_type
)
263 GSList
*extensions
, *compression_type_extensions
;
265 if (extension_type
>= file_type_extensions_arr
->len
)
266 return NULL
; /* not a valid extension type */
268 extensions
= NULL
; /* empty list, to start with */
271 * Get compression-type extensions, if any.
273 compression_type_extensions
= wtap_get_all_compression_type_extensions_list();
276 * Add all this file extension type's extensions, with compressed
279 extensions
= add_extensions_for_file_extensions_type(extension_type
,
280 extensions
, compression_type_extensions
);
282 g_slist_free(compression_type_extensions
);
288 * The open_file_* routines must return:
290 * WTAP_OPEN_ERROR on an I/O error;
292 * WTAP_OPEN_MINE if the file they're reading is one of the types
295 * WTAP_OPEN_NOT_MINE if the file they're reading isn't the type
296 * they're checking for.
298 * If the routine handles this type of file, it must set the "file_type"
299 * field in the "struct wtap" to the type of the file.
301 * Note that the routine does *not* have to free the private data pointer on
302 * error. The caller takes care of that by calling wtap_close on error.
303 * (See https://gitlab.com/wireshark/wireshark/-/issues/8518)
305 * However, the caller *does* have to free the private data pointer when
306 * returning WTAP_OPEN_NOT_MINE, since the next file type will be called
307 * and will likely just overwrite the pointer.
309 * The names are used in file open dialogs to select, for files that
310 * don't have magic numbers and that could potentially be files of
311 * more than one type based on the heuristics, a particular file
312 * type to interpret it as, if the file name has no extension, the
313 * extension isn't sufficient to determine the appropriate file type,
314 * or the extension is wrong.
316 * NOTE: when adding file formats to this list you may also want to add them
317 * to the following files so that the various desktop environments will
318 * know that Wireshark can open the file:
319 * 1) resources/freedesktop/org.wireshark.Wireshark-mime.xml (for freedesktop.org environments)
320 * 2) packaging/macosx/WiresharkInfo.plist.in (for macOS)
322 * If your file format has a commonly-used extension (e.g., ".pcap") then you
323 * should probably also add it to file_type_extensions_base[] (in this file),
324 * to the list of "<glob pattern=...>" entries for this file format in
325 * resources/freedesktop/org.wireshark.Wireshark-mime.xml, to the
326 * CFBundleTypeExtensions array for this file format in
327 * packaging/macosx/WiresharkInfo.plist, and to the PushFileExtensions macro
328 * in packaging/nsis/wireshark-common.nsh and the File Associations in
329 * packaging/wix/ComponentGroups.wxi (for Windows).
331 static const struct open_info open_info_base
[] = {
332 /* Open routines that look for magic numbers */
333 { "Wireshark/tcpdump/... - pcap", OPEN_INFO_MAGIC
, libpcap_open
, NULL
, NULL
, NULL
},
334 { "Wireshark/... - pcapng", OPEN_INFO_MAGIC
, pcapng_open
, NULL
, NULL
, NULL
},
335 { "Sniffer (DOS)", OPEN_INFO_MAGIC
, ngsniffer_open
, NULL
, NULL
, NULL
},
336 { "Snoop, Shomiti/Finisar Surveyor", OPEN_INFO_MAGIC
, snoop_open
, NULL
, NULL
, NULL
},
337 { "AIX iptrace", OPEN_INFO_MAGIC
, iptrace_open
, NULL
, NULL
, NULL
},
338 { "Microsoft Network Monitor", OPEN_INFO_MAGIC
, netmon_open
, NULL
, NULL
, NULL
},
339 { "Cinco NetXray/Sniffer (Windows)", OPEN_INFO_MAGIC
, netxray_open
, NULL
, NULL
, NULL
},
340 { "RADCOM WAN/LAN analyzer", OPEN_INFO_MAGIC
, radcom_open
, NULL
, NULL
, NULL
},
341 { "HP-UX nettl trace", OPEN_INFO_MAGIC
, nettl_open
, NULL
, NULL
, NULL
},
342 { "Visual Networks traffic capture", OPEN_INFO_MAGIC
, visual_open
, NULL
, NULL
, NULL
},
343 { "InfoVista 5View capture", OPEN_INFO_MAGIC
, _5views_open
, NULL
, NULL
, NULL
},
344 { "Viavi Observer", OPEN_INFO_MAGIC
, observer_open
, NULL
, NULL
, NULL
},
345 { "Savvius tagged", OPEN_INFO_MAGIC
, peektagged_open
, NULL
, NULL
, NULL
},
346 { "Colasoft Capsa", OPEN_INFO_MAGIC
, capsa_open
, NULL
, NULL
, NULL
},
347 { "DBS Etherwatch (VMS)", OPEN_INFO_MAGIC
, dbs_etherwatch_open
, NULL
, NULL
, NULL
},
348 { "Tektronix K12xx 32-bit .rf5 format", OPEN_INFO_MAGIC
, k12_open
, NULL
, NULL
, NULL
},
349 { "Catapult DCT2000 trace (.out format)", OPEN_INFO_MAGIC
, catapult_dct2000_open
, NULL
, NULL
, NULL
},
350 { "Aethra .aps file", OPEN_INFO_MAGIC
, aethra_open
, NULL
, NULL
, NULL
},
351 { "Symbian OS btsnoop", OPEN_INFO_MAGIC
, btsnoop_open
, "log", NULL
, NULL
},
352 { "EyeSDN USB S0/E1 ISDN trace format", OPEN_INFO_MAGIC
, eyesdn_open
, NULL
, NULL
, NULL
},
353 { "Transport-Neutral Encapsulation Format", OPEN_INFO_MAGIC
, tnef_open
, NULL
, NULL
, NULL
},
354 /* 3GPP TS 32.423 Trace must come before MIME Files as it's XML based*/
355 { "3GPP TS 32.423 Trace format", OPEN_INFO_MAGIC
, nettrace_3gpp_32_423_file_open
, NULL
, NULL
, NULL
},
356 /* Gammu DCT3 trace must come before MIME files as it's XML based*/
357 { "Gammu DCT3 trace", OPEN_INFO_MAGIC
, dct3trace_open
, NULL
, NULL
, NULL
},
358 { "BLF Logfile", OPEN_INFO_MAGIC
, blf_open
, NULL
, NULL
, NULL
},
359 { "AUTOSAR DLT Logfile", OPEN_INFO_MAGIC
, autosar_dlt_open
, NULL
, NULL
, NULL
},
360 { "RTPDump files", OPEN_INFO_MAGIC
, rtpdump_open
, NULL
, NULL
, NULL
},
361 { "MIME Files Format", OPEN_INFO_MAGIC
, mime_file_open
, NULL
, NULL
, NULL
},
362 { "Micropross mplog", OPEN_INFO_MAGIC
, mplog_open
, NULL
, NULL
, NULL
},
363 { "Unigraf DPA-400 capture", OPEN_INFO_MAGIC
, dpa400_open
, NULL
, NULL
, NULL
},
364 { "RFC 7468 files", OPEN_INFO_MAGIC
, rfc7468_open
, NULL
, NULL
, NULL
},
366 /* Open routines that have no magic numbers and require heuristics. */
367 { "Novell LANalyzer", OPEN_INFO_HEURISTIC
, lanalyzer_open
, "tr1", NULL
, NULL
},
369 * PacketLogger must come before MPEG, because its files
370 * are sometimes grabbed by mpeg_open.
372 { "macOS PacketLogger", OPEN_INFO_HEURISTIC
, packetlogger_open
, "pklg", NULL
, NULL
},
373 /* Some MPEG files have magic numbers, others just have heuristics. */
374 { "MPEG", OPEN_INFO_HEURISTIC
, mpeg_open
, "mpeg;mpg;mp3", NULL
, NULL
},
375 { "Daintree SNA", OPEN_INFO_HEURISTIC
, daintree_sna_open
, "dcf", NULL
, NULL
},
376 { "STANAG 4607 Format", OPEN_INFO_HEURISTIC
, stanag4607_open
, NULL
, NULL
, NULL
},
377 { "ASN.1 Basic Encoding Rules", OPEN_INFO_HEURISTIC
, ber_open
, NULL
, NULL
, NULL
},
379 * I put NetScreen *before* erf, because there were some
380 * false positives with my test-files (Sake Blok, July 2007)
382 * I put VWR *after* ERF, because there were some cases where
383 * ERF files were misidentified as vwr files (Stephen
384 * Donnelly, August 2013; see bug 9054)
386 * I put VWR *after* Peek Classic, CommView, iSeries text,
387 * Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
388 * because there were some cases where files of those types were
389 * misidentified as vwr files (Guy Harris, December 2013)
391 { "NetScreen snoop text file", OPEN_INFO_HEURISTIC
, netscreen_open
, "txt", NULL
, NULL
},
392 { "Endace ERF capture", OPEN_INFO_HEURISTIC
, erf_open
, "erf", NULL
, NULL
},
393 { "IPFIX File Format", OPEN_INFO_HEURISTIC
, ipfix_open
, "pfx;ipfix",NULL
, NULL
},
394 { "K12 text file", OPEN_INFO_HEURISTIC
, k12text_open
, "txt", NULL
, NULL
},
395 { "Savvius classic", OPEN_INFO_HEURISTIC
, peekclassic_open
, "pkt;tpc;apc;wpz", NULL
, NULL
},
396 { "pppd log (pppdump format)", OPEN_INFO_HEURISTIC
, pppdump_open
, NULL
, NULL
, NULL
},
397 { "IBM iSeries comm. trace", OPEN_INFO_HEURISTIC
, iseries_open
, "txt", NULL
, NULL
},
398 { "I4B ISDN trace", OPEN_INFO_HEURISTIC
, i4btrace_open
, NULL
, NULL
, NULL
},
399 { "MPEG2 transport stream", OPEN_INFO_HEURISTIC
, mp2t_open
, "mp2t;ts;mpg", NULL
, NULL
},
400 { "CSIDS IPLog", OPEN_INFO_HEURISTIC
, csids_open
, NULL
, NULL
, NULL
},
401 { "TCPIPtrace (VMS)", OPEN_INFO_HEURISTIC
, vms_open
, "txt", NULL
, NULL
},
402 { "CoSine IPSX L2 capture", OPEN_INFO_HEURISTIC
, cosine_open
, "txt", NULL
, NULL
},
403 { "Bluetooth HCI dump", OPEN_INFO_HEURISTIC
, hcidump_open
, NULL
, NULL
, NULL
},
404 { "TamoSoft CommView NCF", OPEN_INFO_HEURISTIC
, commview_ncf_open
, "ncf", NULL
, NULL
},
405 { "TamoSoft CommView NCFX", OPEN_INFO_HEURISTIC
, commview_ncfx_open
, "ncfx", NULL
, NULL
},
406 { "NetScaler", OPEN_INFO_HEURISTIC
, nstrace_open
, "cap", NULL
, NULL
},
407 { "Android Logcat Binary format", OPEN_INFO_HEURISTIC
, logcat_open
, "logcat", NULL
, NULL
},
408 { "Android Logcat Text formats", OPEN_INFO_HEURISTIC
, logcat_text_open
, "txt", NULL
, NULL
},
409 { "Candump log", OPEN_INFO_HEURISTIC
, candump_open
, NULL
, NULL
, NULL
},
410 { "Busmaster log", OPEN_INFO_HEURISTIC
, busmaster_open
, NULL
, NULL
, NULL
},
411 { "CSS Electronics CLX000 CAN log", OPEN_INFO_MAGIC
, cllog_open
, "txt", NULL
, NULL
},
412 { "Ericsson eNode-B raw log", OPEN_INFO_MAGIC
, eri_enb_log_open
, NULL
, NULL
, NULL
},
413 { "Systemd Journal", OPEN_INFO_HEURISTIC
, systemd_journal_open
, "log;jnl;journal", NULL
, NULL
},
415 /* ASCII trace files from Telnet sessions. */
416 { "Lucent/Ascend access server trace", OPEN_INFO_HEURISTIC
, ascend_open
, "txt", NULL
, NULL
},
417 { "Toshiba Compact ISDN Router snoop", OPEN_INFO_HEURISTIC
, toshiba_open
, "txt", NULL
, NULL
},
419 { "EGNOS Message Server (EMS) file", OPEN_INFO_HEURISTIC
, ems_open
, "ems", NULL
, NULL
},
421 /* Extremely weak heuristics - put them at the end. */
422 { "Ixia IxVeriWave .vwr Raw Capture", OPEN_INFO_HEURISTIC
, vwr_open
, "vwr", NULL
, NULL
},
423 { "CAM Inspector file", OPEN_INFO_HEURISTIC
, camins_open
, "camins", NULL
, NULL
},
424 { "JavaScript Object Notation", OPEN_INFO_HEURISTIC
, json_open
, "json", NULL
, NULL
},
425 { "Ruby Marshal Object", OPEN_INFO_HEURISTIC
, ruby_marshal_open
, "", NULL
, NULL
},
426 { "3gpp phone log", OPEN_INFO_MAGIC
, log3gpp_open
, "log", NULL
, NULL
},
427 { "MP4 media file", OPEN_INFO_MAGIC
, mp4_open
, "mp4", NULL
, NULL
},
431 /* this is only used to build the dynamic array on load, do NOT use this
432 * for anything else, because the size of the actual array will change if
433 * Lua scripts register a new file reader.
435 #define N_OPEN_INFO_ROUTINES ((sizeof open_info_base / sizeof open_info_base[0]))
437 static GArray
*open_info_arr
;
439 /* this always points to the top of the created array */
440 struct open_info
*open_routines
;
442 /* this points to the first OPEN_INFO_HEURISTIC type in the array */
443 static unsigned heuristic_open_routine_idx
;
446 set_heuristic_routine(void)
449 ws_assert(open_info_arr
!= NULL
);
451 for (i
= 0; i
< open_info_arr
->len
; i
++) {
452 if (open_routines
[i
].type
== OPEN_INFO_HEURISTIC
) {
453 heuristic_open_routine_idx
= i
;
457 ws_assert(open_routines
[i
].type
== OPEN_INFO_MAGIC
);
460 ws_assert(heuristic_open_routine_idx
> 0);
464 init_open_routines(void)
467 struct open_info
*i_open
;
472 open_info_arr
= g_array_new(true,true,sizeof(struct open_info
));
474 g_array_append_vals(open_info_arr
, open_info_base
, N_OPEN_INFO_ROUTINES
);
476 open_routines
= (struct open_info
*)(void*) open_info_arr
->data
;
478 /* Populate the extensions_set list now */
479 for (i
= 0, i_open
= open_routines
; i
< open_info_arr
->len
; i
++, i_open
++) {
480 if (i_open
->extensions
!= NULL
)
481 i_open
->extensions_set
= g_strsplit(i_open
->extensions
, ";", 0);
484 set_heuristic_routine();
488 * Registers a new file reader - currently only called by wslua code for
489 * Lua readers and by compiled file reader plugins.
491 * If first_routine is true, the reader added before other readers of its
492 * type (magic or heuristic). This should be done only in cases where
493 * this reader's open test must be performed early, to avoid false
494 * positives for other readers' tests treating files for this reader
495 * as being for another reader.
497 * XXX - given that there is no guarantee that registration routines will
498 * be called in a given order, all this really does is divide readers for
499 * a given type (magic or heuristic) into two categories, with open routines
500 * for readers in the first category (first_routine true) all being called
501 * before readers in the second category; it does not guarantee a particular
502 * total order for open routines.
504 * Checks for an existing reader of the same name and errors if it finds one;
505 * if you want to handle that condition more gracefully, call
506 * wtap_has_open_info() first.
509 wtap_register_open_info(struct open_info
*oi
, const bool first_routine
)
511 if (!oi
|| !oi
->name
) {
512 ws_error("No open_info name given to register");
516 /* verify name doesn't already exist */
517 if (wtap_has_open_info(oi
->name
)) {
518 ws_error("Name given to register_open_info already exists");
522 if (oi
->extensions
!= NULL
)
523 oi
->extensions_set
= g_strsplit(oi
->extensions
, ";", 0);
525 /* if it's magic and first, prepend it; if it's heuristic and not first,
526 append it; if it's anything else, stick it in the middle */
527 if (first_routine
&& oi
->type
== OPEN_INFO_MAGIC
) {
528 g_array_prepend_val(open_info_arr
, *oi
);
529 } else if (!first_routine
&& oi
->type
== OPEN_INFO_HEURISTIC
) {
530 g_array_append_val(open_info_arr
, *oi
);
532 g_array_insert_val(open_info_arr
, heuristic_open_routine_idx
, *oi
);
535 open_routines
= (struct open_info
*)(void*) open_info_arr
->data
;
536 set_heuristic_routine();
539 /* De-registers a file reader by removing it from the GArray based on its name.
540 * This function must NOT be called during wtap_open_offline(), since it changes the array.
541 * Note: this function will error if it doesn't find the given name; if you want to handle
542 * that condition more gracefully, call wtap_has_open_info() first.
545 wtap_deregister_open_info(const char *name
)
550 ws_error("Missing open_info name to de-register");
554 for (i
= 0; i
< open_info_arr
->len
; i
++) {
555 if (open_routines
[i
].name
&& strcmp(open_routines
[i
].name
, name
) == 0) {
556 g_strfreev(open_routines
[i
].extensions_set
);
557 open_info_arr
= g_array_remove_index(open_info_arr
, i
);
558 set_heuristic_routine();
563 ws_error("deregister_open_info: name not found");
566 /* Determines if a open routine short name already exists
569 wtap_has_open_info(const char *name
)
574 ws_error("No name given to wtap_has_open_info!");
579 for (i
= 0; i
< open_info_arr
->len
; i
++) {
580 if (open_routines
[i
].name
&& strcmp(open_routines
[i
].name
, name
) == 0) {
589 wtap_uses_lua_filehandler(const wtap
* wth
)
591 if (wth
&& wth
->wslua_data
!= NULL
) {
593 * Currently, wslua_data is set if and only if using a Lua
603 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
604 * define them either.)
606 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
609 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
612 #define S_IFIFO _S_IFIFO
615 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
618 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
621 /* returns the 'type' number to use for wtap_open_offline based on the
622 * passed-in name (the name in the open_info struct). It returns WTAP_TYPE_AUTO
623 * on failure, which is the number 0. The 'type' number is the entry's index+1,
624 * because that's what wtap_open_offline() expects it to be.
627 open_info_name_to_type(const char *name
)
632 return WTAP_TYPE_AUTO
;
634 for (i
= 0; i
< open_info_arr
->len
; i
++) {
635 if (open_routines
[i
].name
!= NULL
&&
636 strcmp(name
, open_routines
[i
].name
) == 0)
640 return WTAP_TYPE_AUTO
; /* no such file type */
644 get_file_extension(const char *pathname
)
652 * Is the pathname empty?
654 if (strcmp(pathname
, "") == 0)
655 return NULL
; /* no extension */
658 * Find the last component of the pathname.
660 filename
= g_path_get_basename(pathname
);
663 * Does it have an extension?
665 if (strchr(filename
, '.') == NULL
) {
667 return NULL
; /* no extension whatsoever */
671 * Yes. Fold it to lowercase, since open_routines[] has
672 * its extensions in lowercase.
674 ascii_strdown_inplace(filename
);
677 * Split it into components separated by ".".
679 components
= g_strsplit(filename
, ".", 0);
683 * Count the components.
685 for (ncomponents
= 0; components
[ncomponents
] != NULL
; ncomponents
++)
688 if (ncomponents
== 0) {
689 g_strfreev(components
);
690 return NULL
; /* no components */
692 if (ncomponents
== 1) {
693 g_strfreev(components
);
694 return NULL
; /* only one component, with no "." */
698 * Get compression-type extensions, if any.
700 GSList
*compression_type_extensions
= wtap_get_all_compression_type_extensions_list();
703 * Is the last component one of the extensions used for compressed
706 extensionp
= components
[ncomponents
- 1];
707 for (GSList
*compression_type_extension
= compression_type_extensions
;
708 compression_type_extension
!= NULL
;
709 compression_type_extension
= g_slist_next(compression_type_extension
)) {
710 if (strcmp(extensionp
, (const char *)compression_type_extension
->data
) == 0) {
712 * Yes, so it's one of the compressed-file extensions.
713 * Is there an extension before that?
715 if (ncomponents
== 2) {
716 g_slist_free(compression_type_extensions
);
717 g_strfreev(components
);
718 return NULL
; /* no, only two components */
722 * Yes, return that extension.
724 g_slist_free(compression_type_extensions
);
725 extensionp
= g_strdup(components
[ncomponents
- 2]);
726 g_strfreev(components
);
731 g_slist_free(compression_type_extensions
);
734 * The extension isn't one of the compressed-file extensions;
737 extensionp
= g_strdup(extensionp
);
738 g_strfreev(components
);
743 * Check if file extension is used in this heuristic
746 heuristic_uses_extension(unsigned int i
, const char *extension
)
751 * Does this file type *have* any extensions?
753 if (open_routines
[i
].extensions
== NULL
)
754 return false; /* no */
757 * Check each of them against the specified extension.
759 for (extensionp
= open_routines
[i
].extensions_set
; *extensionp
!= NULL
;
761 if (strcmp(extension
, *extensionp
) == 0) {
762 return true; /* it's one of them */
766 return false; /* it's not one of them */
769 /* Opens a file and prepares a wtap struct.
770 * If "do_random" is true, it opens the file twice; the second open
771 * allows the application to do random-access I/O without moving
772 * the seek offset for sequential I/O, which is used by Wireshark
773 * so that it can do sequential I/O to a capture file that's being
774 * written to as new packets arrive independently of random I/O done
775 * to display protocol trees for packets when they're selected.
778 wtap_open_offline(const char *filename
, unsigned int type
, int *err
, char **err_info
,
786 bool use_stdin
= false;
793 /* open standard input if filename is '-' */
794 if (strcmp(filename
, "-") == 0)
797 /* First, make sure the file is valid */
799 if (ws_fstat64(0, &statb
) < 0) {
804 if (ws_stat64(filename
, &statb
) < 0) {
809 if (S_ISFIFO(statb
.st_mode
)) {
811 * Opens of FIFOs are allowed only when not opening
814 * Currently, we do seeking when trying to find out
815 * the file type, but our I/O routines do some amount
816 * of buffering, and do backward seeks within the buffer
817 * if possible, so at least some file types can be
818 * opened from pipes, so we don't completely disallow opens
822 *err
= WTAP_ERR_RANDOM_OPEN_PIPE
;
826 } else if (S_ISDIR(statb
.st_mode
)) {
828 * Return different errors for "this is a directory"
829 * and "this is some random special file type", so
830 * the user can get a potentially more helpful error.
834 } else if (! S_ISREG(statb
.st_mode
)) {
835 *err
= WTAP_ERR_NOT_REGULAR_FILE
;
840 * We need two independent descriptors for random access, so
841 * they have different file positions. If we're opening the
842 * standard input, we can only dup it to get additional
843 * descriptors, so we can't have two independent descriptors,
844 * and thus can't do random access.
846 if (use_stdin
&& do_random
) {
847 *err
= WTAP_ERR_RANDOM_OPEN_STDIN
;
852 wth
= g_new0(wtap
, 1);
855 errno
= WTAP_ERR_CANT_OPEN
;
858 * We dup FD 0, so that we don't have to worry about
859 * a file_close of wth->fh closing the standard
860 * input of the process.
869 if (_setmode(fd
, O_BINARY
) == -1) {
870 /* "Shouldn't happen" */
876 if (!(wth
->fh
= file_fdopen(fd
))) {
883 if (!(wth
->fh
= file_open(filename
))) {
891 if (!(wth
->random_fh
= file_open(filename
))) {
898 wth
->random_fh
= NULL
;
901 wth
->ispipe
= ispipe
;
902 wth
->file_encap
= WTAP_ENCAP_UNKNOWN
;
903 wth
->subtype_sequential_close
= NULL
;
904 wth
->subtype_close
= NULL
;
905 wth
->file_tsprec
= WTAP_TSPREC_USEC
;
906 wth
->pathname
= g_strdup(filename
);
908 wth
->wslua_data
= NULL
;
909 wth
->shb_hdrs
= g_array_new(false, false, sizeof(wtap_block_t
));
910 shb
= wtap_block_create(WTAP_BLOCK_SECTION
);
912 g_array_append_val(wth
->shb_hdrs
, shb
);
914 /* Initialize the array containing a list of interfaces. pcapng_open and
915 * erf_open needs this (and libpcap_open for ERF encapsulation types).
916 * Always initing it here saves checking for a NULL ptr later. */
917 wth
->interface_data
= g_array_new(false, false, sizeof(wtap_block_t
));
919 * Next interface data that wtap_get_next_interface_description()
922 wth
->next_interface_data
= 0;
924 wth
->shb_iface_to_global
= g_array_new(false, false, sizeof(unsigned));
925 g_array_append_val(wth
->shb_iface_to_global
, wth
->interface_data
->len
);
927 if (wth
->random_fh
) {
928 wth
->fast_seek
= g_ptr_array_new();
930 file_set_random_access(wth
->fh
, false, wth
->fast_seek
);
931 file_set_random_access(wth
->random_fh
, true, wth
->fast_seek
);
934 /* 'type' is 1 greater than the array index */
935 if (type
!= WTAP_TYPE_AUTO
&& type
<= open_info_arr
->len
) {
938 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
939 /* I/O error - give up */
944 /* Set wth with wslua data if any - this is how we pass the data
945 * to the file reader, kinda like the priv member but not free'd later.
946 * It's ok for this to copy a NULL.
948 wth
->wslua_data
= open_routines
[type
- 1].wslua_data
;
950 result
= (*open_routines
[type
- 1].open_routine
)(wth
, err
, err_info
);
953 case WTAP_OPEN_ERROR
:
954 /* Error - give up */
958 case WTAP_OPEN_NOT_MINE
:
959 /* No error, but not that type of file */
963 /* We found the file type */
968 /* Try all file types that support magic numbers */
969 for (i
= 0; i
< heuristic_open_routine_idx
; i
++) {
970 /* Seek back to the beginning of the file; the open routine
971 * for the previous file type may have left the file
972 * position somewhere other than the beginning, and the
973 * open routine for this file type will probably want
974 * to start reading at the beginning.
976 * Initialize the data offset while we're at it.
978 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
979 /* Error - give up */
984 /* Set wth with wslua data if any - this is how we pass the data
985 * to the file reader, kinda like the priv member but not free'd later.
986 * It's ok for this to copy a NULL.
988 wth
->wslua_data
= open_routines
[i
].wslua_data
;
990 switch ((*open_routines
[i
].open_routine
)(wth
, err
, err_info
)) {
992 case WTAP_OPEN_ERROR
:
993 /* Error - give up */
997 case WTAP_OPEN_NOT_MINE
:
998 /* No error, but not that type of file */
1001 case WTAP_OPEN_MINE
:
1002 /* We found the file type */
1008 /* Does this file's name have an extension? */
1009 extension
= get_file_extension(filename
);
1010 if (extension
!= NULL
) {
1011 /* Yes - try the heuristic types that use that extension first. */
1012 for (i
= heuristic_open_routine_idx
; i
< open_info_arr
->len
; i
++) {
1013 /* Does this type use that extension? */
1014 if (heuristic_uses_extension(i
, extension
)) {
1016 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
1017 /* Error - give up */
1023 /* Set wth with wslua data if any - this is how we pass the data
1024 * to the file reader, kind of like priv but not free'd later.
1026 wth
->wslua_data
= open_routines
[i
].wslua_data
;
1028 switch ((*open_routines
[i
].open_routine
)(wth
,
1031 case WTAP_OPEN_ERROR
:
1032 /* Error - give up */
1037 case WTAP_OPEN_NOT_MINE
:
1038 /* No error, but not that type of file */
1041 case WTAP_OPEN_MINE
:
1042 /* We found the file type */
1050 * Now try the heuristic types that have no extensions
1051 * to check; we try those before the ones that have
1052 * extensions that *don't* match this file's extension,
1053 * on the theory that files of those types generally
1054 * have one of the type's extensions, and, as this file
1055 * *doesn't* have one of those extensions, it's probably
1056 * *not* one of those files.
1058 for (i
= heuristic_open_routine_idx
; i
< open_info_arr
->len
; i
++) {
1059 /* Does this type have any extensions? */
1060 if (open_routines
[i
].extensions
== NULL
) {
1062 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
1063 /* Error - give up */
1069 /* Set wth with wslua data if any - this is how we pass the data
1070 * to the file reader, kind of like priv but not free'd later.
1072 wth
->wslua_data
= open_routines
[i
].wslua_data
;
1074 switch ((*open_routines
[i
].open_routine
)(wth
,
1077 case WTAP_OPEN_ERROR
:
1078 /* Error - give up */
1083 case WTAP_OPEN_NOT_MINE
:
1084 /* No error, but not that type of file */
1087 case WTAP_OPEN_MINE
:
1088 /* We found the file type */
1096 * Now try the ones that have extensions where none of
1097 * them matches this file's extensions.
1099 for (i
= heuristic_open_routine_idx
; i
< open_info_arr
->len
; i
++) {
1101 * Does this type have extensions and is this file's
1102 * extension one of them?
1104 if (open_routines
[i
].extensions
!= NULL
&&
1105 !heuristic_uses_extension(i
, extension
)) {
1107 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
1108 /* Error - give up */
1114 /* Set wth with wslua data if any - this is how we pass the data
1115 * to the file reader, kind of like priv but not free'd later.
1117 wth
->wslua_data
= open_routines
[i
].wslua_data
;
1119 switch ((*open_routines
[i
].open_routine
)(wth
,
1122 case WTAP_OPEN_ERROR
:
1123 /* Error - give up */
1128 case WTAP_OPEN_NOT_MINE
:
1129 /* No error, but not that type of file */
1132 case WTAP_OPEN_MINE
:
1133 /* We found the file type */
1141 /* No - try all the heuristics types in order. */
1142 for (i
= heuristic_open_routine_idx
; i
< open_info_arr
->len
; i
++) {
1144 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
1145 /* Error - give up */
1150 /* Set wth with wslua data if any - this is how we pass the data
1151 * to the file reader, kind of like priv but not free'd later.
1153 wth
->wslua_data
= open_routines
[i
].wslua_data
;
1155 switch ((*open_routines
[i
].open_routine
)(wth
, err
, err_info
)) {
1157 case WTAP_OPEN_ERROR
:
1158 /* Error - give up */
1162 case WTAP_OPEN_NOT_MINE
:
1163 /* No error, but not that type of file */
1166 case WTAP_OPEN_MINE
:
1167 /* We found the file type */
1175 /* Well, it's not one of the types of file we know about. */
1177 *err
= WTAP_ERR_FILE_UNKNOWN_FORMAT
;
1185 * Given the pathname of the file we just closed with wtap_fdclose(), attempt
1186 * to reopen that file and assign the new file descriptor(s) to the sequential
1187 * stream and, if do_random is true, to the random stream. Used on Windows
1188 * after the rename of a file we had open was done or if the rename of a
1189 * file on top of a file we had open failed.
1191 * This is only required by Wireshark, not TShark, and, at the point that
1192 * Wireshark is doing this, the sequential stream is closed, and the
1193 * random stream is open, so this refuses to open pipes, and only
1194 * reopens the random stream.
1197 wtap_fdreopen(wtap
*wth
, const char *filename
, int *err
)
1202 * We need two independent descriptors for random access, so
1203 * they have different file positions. If we're opening the
1204 * standard input, we can only dup it to get additional
1205 * descriptors, so we can't have two independent descriptors,
1206 * and thus can't do random access.
1208 if (strcmp(filename
, "-") == 0) {
1209 *err
= WTAP_ERR_RANDOM_OPEN_STDIN
;
1213 /* First, make sure the file is valid */
1214 if (ws_stat64(filename
, &statb
) < 0) {
1218 if (S_ISFIFO(statb
.st_mode
)) {
1220 * Opens of FIFOs are not allowed; see above.
1222 *err
= WTAP_ERR_RANDOM_OPEN_PIPE
;
1224 } else if (S_ISDIR(statb
.st_mode
)) {
1226 * Return different errors for "this is a directory"
1227 * and "this is some random special file type", so
1228 * the user can get a potentially more helpful error.
1232 } else if (! S_ISREG(statb
.st_mode
)) {
1233 *err
= WTAP_ERR_NOT_REGULAR_FILE
;
1238 errno
= WTAP_ERR_CANT_OPEN
;
1239 if (!file_fdreopen(wth
->random_fh
, filename
)) {
1243 if (strcmp(filename
, wth
->pathname
) != 0) {
1244 g_free(wth
->pathname
);
1245 wth
->pathname
= g_strdup(filename
);
1250 /* Table of the file types and subtypes for which we have support. */
1253 * Pointer to the GArray holding the registered file types.
1255 static GArray
* file_type_subtype_table_arr
;
1258 * Pointer to the table of registered file types in that GArray.
1260 static const struct file_type_subtype_info
* file_type_subtype_table
;
1263 * Number of elements in the table for builtin file types/subtypes.
1265 static unsigned wtap_num_builtin_file_types_subtypes
;
1268 * Required builtin types.
1270 int pcap_file_type_subtype
= -1;
1271 int pcap_nsec_file_type_subtype
= -1;
1272 int pcapng_file_type_subtype
= -1;
1275 * Table for mapping old file type/subtype names to new ones for
1276 * backwards compatibility.
1278 static GHashTable
*type_subtype_name_map
;
1281 * Initialize the table of file types/subtypes with all the builtin
1285 wtap_init_file_type_subtypes(void)
1287 /* Don't do this twice. */
1288 ws_assert(file_type_subtype_table_arr
== NULL
);
1291 * Estimate the number of file types/subtypes as twice the
1292 * number of modules; that's probably an overestimate, as
1293 * the average number of file types/subtypes registered by
1294 * a module is > 1 but probably < 2, but that shouldn't
1295 * waste too much memory.
1297 * Add on 7 more for pcapng, pcap, nanosecond pcap, and the
1298 * extra modified flavors of pcap.
1300 file_type_subtype_table_arr
= g_array_sized_new(false, true,
1301 sizeof(struct file_type_subtype_info
), wtap_module_count
*2 + 7);
1302 file_type_subtype_table
= (const struct file_type_subtype_info
*)(void *)file_type_subtype_table_arr
->data
;
1305 * Initialize the hash table for mapping old file type/subtype
1306 * names to the corresponding new names.
1308 type_subtype_name_map
= g_hash_table_new_full(g_str_hash
,
1309 g_str_equal
, g_free
, g_free
);
1311 /* No entries yet, so no builtin entries yet. */
1312 wtap_num_builtin_file_types_subtypes
= 0;
1315 * Register the builtin entries that aren't in the table.
1316 * First, do the required ones; register pcapng first, then
1317 * pcap, so, at the beginning of the table, we have pcapng,
1318 * pcap, nanosecond pcap, and the weird modified pcaps, so
1319 * searches for file types that can write a file format
1320 * start with pcapng, pcap, and nanosecond pcap.
1325 /* Now register the ones found by the build process */
1326 for (unsigned i
= 0; i
< wtap_module_count
; i
++)
1327 wtap_module_reg
[i
].cb_func();
1329 /* Update the number of builtin entries. */
1330 wtap_num_builtin_file_types_subtypes
= file_type_subtype_table_arr
->len
;
1334 * Attempt to register a new file type/subtype; fails if a type/subtype
1335 * with that name is already registered.
1338 wtap_register_file_type_subtype(const struct file_type_subtype_info
* fi
)
1340 struct file_type_subtype_info
* finfo
;
1341 unsigned file_type_subtype
;
1344 * Check for required fields (description and name).
1346 if (!fi
|| !fi
->description
|| !fi
->name
) {
1347 ws_warning("no file type info");
1352 * There must be at least one block type that this file
1353 * type/subtype supports.
1355 if (fi
->num_supported_blocks
== 0 || fi
->supported_blocks
== NULL
) {
1356 ws_warning("no blocks supported by file type \"%s\"", fi
->name
);
1361 * Is this type already registered?
1363 if (wtap_name_to_file_type_subtype(fi
->name
) != -1) {
1365 * Yes. You don't get to replace an existing handler.
1367 ws_warning("file type \"%s\" is already registered", fi
->name
);
1372 * Is there a freed entry in the array, due to a file type
1373 * being de-registered?
1375 * Skip the built-in entries, as they're never deregistered.
1377 for (file_type_subtype
= wtap_num_builtin_file_types_subtypes
;
1378 file_type_subtype
< file_type_subtype_table_arr
->len
;
1379 file_type_subtype
++) {
1380 if (file_type_subtype_table
[file_type_subtype
].name
== NULL
) {
1382 * We found such an entry.
1384 * Get the pointer from the GArray, so that we get a
1385 * non-const pointer.
1387 finfo
= &g_array_index(file_type_subtype_table_arr
, struct file_type_subtype_info
, file_type_subtype
);
1390 * Fill in the entry with the new values.
1394 return (int)file_type_subtype
;
1399 * There aren't any free slots, so add a new entry.
1400 * Get the number of current number of entries, which will
1401 * be the index of the new entry, then append this entry
1402 * to the end of the array, change file_type_subtype_table
1403 * in case the array had to get reallocated, and return
1404 * the index of the new entry.
1406 file_type_subtype
= file_type_subtype_table_arr
->len
;
1407 g_array_append_val(file_type_subtype_table_arr
, *fi
);
1408 file_type_subtype_table
= (const struct file_type_subtype_info
*)(void *)file_type_subtype_table_arr
->data
;
1409 return file_type_subtype
;
1412 /* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
1415 wtap_deregister_file_type_subtype(const int subtype
)
1417 struct file_type_subtype_info
* finfo
;
1419 if (subtype
< 0 || subtype
>= (int)file_type_subtype_table_arr
->len
) {
1420 ws_error("invalid file type to de-register");
1423 if ((unsigned)subtype
< wtap_num_builtin_file_types_subtypes
) {
1424 ws_error("built-in file types cannot be de-registered");
1429 * Get the pointer from the GArray, so that we get a non-const
1432 finfo
= &g_array_index(file_type_subtype_table_arr
, struct file_type_subtype_info
, subtype
);
1434 * Clear out this entry.
1436 finfo
->description
= NULL
;
1438 finfo
->default_file_extension
= NULL
;
1439 finfo
->additional_file_extensions
= NULL
;
1440 finfo
->writing_must_seek
= false;
1441 finfo
->num_supported_blocks
= 0;
1442 finfo
->supported_blocks
= NULL
;
1443 finfo
->can_write_encap
= NULL
;
1444 finfo
->dump_open
= NULL
;
1445 finfo
->wslua_info
= NULL
;
1449 * Given a GArray of WTAP_ENCAP_ types, return the per-file encapsulation
1450 * type that would be needed to write out a file with those types. If
1451 * there's only one type, it's that type, otherwise it's
1452 * WTAP_ENCAP_PER_PACKET.
1455 wtap_dump_required_file_encap_type(const GArray
*file_encaps
)
1459 encap
= WTAP_ENCAP_PER_PACKET
;
1460 if (file_encaps
->len
== 1) {
1461 /* OK, use the one-and-only encapsulation type. */
1462 encap
= g_array_index(file_encaps
, int, 0);
1468 wtap_dump_can_write_encap(int file_type_subtype
, int encap
)
1472 if (file_type_subtype
< 0 ||
1473 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
||
1474 file_type_subtype_table
[file_type_subtype
].can_write_encap
== NULL
)
1477 result
= (*file_type_subtype_table
[file_type_subtype
].can_write_encap
)(encap
);
1480 /* if the err said to check wslua's can_write_encap, try that */
1481 if (result
== WTAP_ERR_CHECK_WSLUA
1482 && file_type_subtype_table
[file_type_subtype
].wslua_info
!= NULL
1483 && file_type_subtype_table
[file_type_subtype
].wslua_info
->wslua_can_write_encap
!= NULL
) {
1485 result
= (*file_type_subtype_table
[file_type_subtype
].wslua_info
->wslua_can_write_encap
)(encap
, file_type_subtype_table
[file_type_subtype
].wslua_info
->wslua_data
);
1497 * Return true if a capture with a given GArray of encapsulation types
1498 * and a given bitset of comment types can be written in a specified
1499 * format, and false if it can't.
1502 wtap_dump_can_write_format(int ft
, const GArray
*file_encaps
,
1503 uint32_t required_comment_types
)
1508 * Can we write in this format?
1510 if (!wtap_dump_can_open(ft
)) {
1516 * Yes. Can we write out all the required comments in this
1519 if (required_comment_types
& WTAP_COMMENT_PER_SECTION
) {
1520 if (wtap_file_type_subtype_supports_option(ft
,
1521 WTAP_BLOCK_SECTION
, OPT_COMMENT
) == OPTION_NOT_SUPPORTED
) {
1522 /* Not section comments. */
1526 if (required_comment_types
& WTAP_COMMENT_PER_INTERFACE
) {
1527 if (wtap_file_type_subtype_supports_option(ft
,
1528 WTAP_BLOCK_IF_ID_AND_INFO
, OPT_COMMENT
) == OPTION_NOT_SUPPORTED
) {
1529 /* Not interface comments. */
1533 if (required_comment_types
& WTAP_COMMENT_PER_PACKET
) {
1534 if (wtap_file_type_subtype_supports_option(ft
,
1535 WTAP_BLOCK_PACKET
, OPT_COMMENT
) == OPTION_NOT_SUPPORTED
) {
1536 /* Not packet comments. */
1542 * Yes. Is the required per-file encapsulation type supported?
1543 * This might be WTAP_ENCAP_PER_PACKET.
1545 if (!wtap_dump_can_write_encap(ft
, wtap_dump_required_file_encap_type(file_encaps
))) {
1551 * Yes. Are all the individual encapsulation types supported?
1553 for (i
= 0; i
< file_encaps
->len
; i
++) {
1554 if (!wtap_dump_can_write_encap(ft
,
1555 g_array_index(file_encaps
, int, i
))) {
1556 /* No - one of them isn't. */
1561 /* Yes - we're OK. */
1566 * Return true if we can write a file with the given GArray of
1567 * encapsulation types and the given bitmask of comment types.
1570 wtap_dump_can_write(const GArray
*file_encaps
, uint32_t required_comment_types
)
1574 for (ft
= 0; ft
< (int)file_type_subtype_table_arr
->len
; ft
++) {
1575 /* To save a file with Wiretap, Wiretap has to handle that format,
1576 * and its code to handle that format must be able to write a file
1577 * with this file's encapsulation types.
1579 if (wtap_dump_can_write_format(ft
, file_encaps
, required_comment_types
)) {
1580 /* OK, we can write it out in this type. */
1585 /* No, we couldn't save it in any format. */
1590 * Sort by file type/subtype name.
1593 compare_file_type_subtypes_by_name(gconstpointer a
, gconstpointer b
)
1595 int file_type_subtype_a
= *(const int *)a
;
1596 int file_type_subtype_b
= *(const int *)b
;
1598 return strcmp(wtap_file_type_subtype_name(file_type_subtype_a
),
1599 wtap_file_type_subtype_name(file_type_subtype_b
));
1603 * Sort by file type/subtype description.
1606 compare_file_type_subtypes_by_description(gconstpointer a
, gconstpointer b
)
1608 int file_type_subtype_a
= *(const int *)a
;
1609 int file_type_subtype_b
= *(const int *)b
;
1611 return strcmp(wtap_file_type_subtype_description(file_type_subtype_a
),
1612 wtap_file_type_subtype_description(file_type_subtype_b
));
1616 * Get a GArray of file type/subtype values for file types/subtypes
1617 * that can be used to save a file of a given type/subtype with a given
1618 * GArray of encapsulation types and the given bitmask of comment types.
1621 wtap_get_savable_file_types_subtypes_for_file(int file_type_subtype
,
1622 const GArray
*file_encaps
, uint32_t required_comment_types
,
1623 ft_sort_order sort_order
)
1625 GArray
*savable_file_types_subtypes
;
1627 int default_file_type_subtype
= -1;
1628 int other_file_type_subtype
= -1;
1630 /* Can we save this file in its own file type/subtype? */
1631 if (wtap_dump_can_write_format(file_type_subtype
, file_encaps
,
1632 required_comment_types
)) {
1633 /* Yes - make that the default file type/subtype. */
1634 default_file_type_subtype
= file_type_subtype
;
1635 } else if (wtap_dump_can_write_format(pcap_file_type_subtype
,
1637 required_comment_types
)) {
1639 * No, but we can write it as a pcap file; make that
1640 * the default file type/subtype.
1642 default_file_type_subtype
= pcap_file_type_subtype
;
1643 } else if (wtap_dump_can_write_format(pcapng_file_type_subtype
,
1645 required_comment_types
)) {
1647 * No, but we can write it as a pcapng file; make that
1648 * the default file type/subtype.
1650 default_file_type_subtype
= pcapng_file_type_subtype
;
1652 /* OK, find the first file type/subtype we *can* save it as. */
1653 default_file_type_subtype
= -1;
1654 for (ft
= 0; ft
< (int)file_type_subtype_table_arr
->len
; ft
++) {
1655 if (wtap_dump_can_write_format(ft
, file_encaps
,
1656 required_comment_types
)) {
1658 default_file_type_subtype
= ft
;
1664 if (default_file_type_subtype
== -1) {
1665 /* We don't support writing this file as any file type/subtype. */
1670 * If the default is pcap, put pcapng right after it if we can
1671 * also write it in pcapng format; otherwise, if the default is
1672 * pcapng, put pcap right after it if we can also write it in
1675 if (default_file_type_subtype
== pcap_file_type_subtype
) {
1676 if (wtap_dump_can_write_format(pcapng_file_type_subtype
,
1678 required_comment_types
))
1679 other_file_type_subtype
= pcapng_file_type_subtype
;
1680 } else if (default_file_type_subtype
== pcapng_file_type_subtype
) {
1681 if (wtap_dump_can_write_format(pcap_file_type_subtype
,
1683 required_comment_types
))
1684 other_file_type_subtype
= pcap_file_type_subtype
;
1687 /* Allocate the array. */
1688 savable_file_types_subtypes
= g_array_new(false, false,
1692 * First, add the types we don't want to force to the
1693 * beginning of the list.
1695 for (ft
= 0; ft
< (int)file_type_subtype_table_arr
->len
; ft
++) {
1696 if (ft
== default_file_type_subtype
||
1697 ft
== other_file_type_subtype
)
1698 continue; /* we will done this one later */
1699 if (wtap_dump_can_write_format(ft
, file_encaps
,
1700 required_comment_types
)) {
1701 /* OK, we can write it out in this type. */
1702 g_array_append_val(savable_file_types_subtypes
, ft
);
1706 /* Now, sort the list. */
1707 g_array_sort(savable_file_types_subtypes
,
1708 (sort_order
== FT_SORT_BY_NAME
) ? compare_file_type_subtypes_by_name
:
1709 compare_file_type_subtypes_by_description
);
1712 * If we have a type/subtype to put above the default one,
1715 * We put this type at the beginning before putting the
1716 * default there, so the default is at the top.
1718 if (other_file_type_subtype
!= -1)
1719 g_array_prepend_val(savable_file_types_subtypes
,
1720 other_file_type_subtype
);
1722 /* Put the default file type/subtype first in the list. */
1723 g_array_prepend_val(savable_file_types_subtypes
,
1724 default_file_type_subtype
);
1726 return savable_file_types_subtypes
;
1730 * Get a GArray of all writable file type/subtype values.
1733 wtap_get_writable_file_types_subtypes(ft_sort_order sort_order
)
1735 GArray
*writable_file_types_subtypes
;
1739 * Allocate the array.
1740 * Pre-allocate room enough for all types.
1741 * XXX - that's overkill; just scan the table to find all the
1742 * writable types and count them.
1744 writable_file_types_subtypes
= g_array_sized_new(false, false,
1745 sizeof (int), file_type_subtype_table_arr
->len
);
1748 * First, add the types we don't want to force to the
1749 * beginning of the list.
1751 for (ft
= 0; ft
< (int)file_type_subtype_table_arr
->len
; ft
++) {
1752 if (ft
== pcap_file_type_subtype
||
1753 ft
== pcapng_file_type_subtype
)
1754 continue; /* we've already done these two */
1755 if (wtap_dump_can_open(ft
)) {
1756 /* OK, we can write this type. */
1757 g_array_append_val(writable_file_types_subtypes
, ft
);
1761 /* Now, sort the list. */
1762 g_array_sort(writable_file_types_subtypes
,
1763 (sort_order
== FT_SORT_BY_NAME
) ? compare_file_type_subtypes_by_name
:
1764 compare_file_type_subtypes_by_description
);
1767 * Now, put pcap and pcapng at the beginning, as they're
1768 * our "native" formats. Put pcapng there first, and
1771 if (pcapng_file_type_subtype
!= -1 &&
1772 wtap_dump_can_open(pcapng_file_type_subtype
)) {
1774 * We can write pcapng. (If we can't, that's a huge
1777 g_array_prepend_val(writable_file_types_subtypes
,
1778 pcapng_file_type_subtype
);
1780 if (pcap_file_type_subtype
!= -1 &&
1781 wtap_dump_can_open(pcap_file_type_subtype
)) {
1783 * We can write pcap. (If we can't, that's a huge
1786 g_array_prepend_val(writable_file_types_subtypes
,
1787 pcap_file_type_subtype
);
1790 return writable_file_types_subtypes
;
1794 * String describing the file type/subtype.
1797 wtap_file_type_subtype_description(int file_type_subtype
)
1799 if (file_type_subtype
< 0 ||
1800 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
)
1803 return file_type_subtype_table
[file_type_subtype
].description
;
1807 * Name to use in, say, a command-line flag specifying the type/subtype.
1810 wtap_file_type_subtype_name(int file_type_subtype
)
1812 if (file_type_subtype
< 0 ||
1813 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
)
1816 return file_type_subtype_table
[file_type_subtype
].name
;
1820 * Register a backwards-compatibility name.
1823 wtap_register_compatibility_file_subtype_name(const char *old_name
,
1824 const char *new_name
)
1826 g_hash_table_insert(type_subtype_name_map
, g_strdup(old_name
),
1827 g_strdup(new_name
));
1831 * Translate a name to a capture file type/subtype.
1834 wtap_name_to_file_type_subtype(const char *name
)
1837 int file_type_subtype
;
1840 * Is this name a backwards-compatibility name?
1842 new_name
= (char *)g_hash_table_lookup(type_subtype_name_map
,
1844 if (new_name
!= NULL
) {
1846 * Yes, and new_name is the name to which it should
1851 for (file_type_subtype
= 0;
1852 file_type_subtype
< (int)file_type_subtype_table_arr
->len
;
1853 file_type_subtype
++) {
1854 if (file_type_subtype_table
[file_type_subtype
].name
!= NULL
&&
1855 strcmp(name
, file_type_subtype_table
[file_type_subtype
].name
) == 0)
1856 return file_type_subtype
;
1859 return -1; /* no such file type, or we can't write it */
1863 * Provide the file type/subtype for pcap.
1866 wtap_pcap_file_type_subtype(void)
1869 * Make sure pcap was registered as a file type/subtype;
1870 * it's one of our "native" formats.
1872 ws_assert(pcap_file_type_subtype
!= -1);
1873 return pcap_file_type_subtype
;
1877 * Provide the file type/subtype for nanosecond-resolution pcap.
1880 wtap_pcap_nsec_file_type_subtype(void)
1883 * Make sure nanosecond-resolution pcap was registered
1884 * as a file type/subtype; it's one of our "native" formats.
1886 ws_assert(pcap_nsec_file_type_subtype
!= -1);
1887 return pcap_nsec_file_type_subtype
;
1891 * Provide the file type/subtype for pcapng.
1894 wtap_pcapng_file_type_subtype(void)
1897 * Make sure pcapng was registered as a file type/subtype;
1898 * it's one of our "native" formats.
1900 ws_assert(pcapng_file_type_subtype
!= -1);
1901 return pcapng_file_type_subtype
;
1905 * Determine if a file type/subtype can write a block of the given type.
1908 wtap_file_type_subtype_supports_block(int file_type_subtype
,
1909 wtap_block_type_t type
)
1911 size_t num_supported_blocks
;
1912 const struct supported_block_type
*supported_blocks
;
1914 if (file_type_subtype
< 0 ||
1915 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
) {
1917 * There's no such file type, so it can't support any
1920 return BLOCK_NOT_SUPPORTED
;
1923 num_supported_blocks
= file_type_subtype_table
[file_type_subtype
].num_supported_blocks
;
1924 supported_blocks
= file_type_subtype_table
[file_type_subtype
].supported_blocks
;
1926 for (size_t block_idx
= 0; block_idx
< num_supported_blocks
;
1928 if (supported_blocks
[block_idx
].type
== type
)
1929 return supported_blocks
[block_idx
].support
;
1933 * Not found, which means not supported.
1935 return BLOCK_NOT_SUPPORTED
;
1939 * Determine if a file type/subtype, when writing a block of the given type,
1940 * can support adding the given option to the block.
1943 wtap_file_type_subtype_supports_option(int file_type_subtype
,
1944 wtap_block_type_t type
, unsigned option
)
1946 size_t num_supported_blocks
;
1947 const struct supported_block_type
*supported_blocks
;
1949 if (file_type_subtype
< 0 ||
1950 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
) {
1952 * There's no such file type, so it can't support any
1953 * blocks, and thus can't support any options.
1955 return OPTION_NOT_SUPPORTED
;
1958 num_supported_blocks
= file_type_subtype_table
[file_type_subtype
].num_supported_blocks
;
1959 supported_blocks
= file_type_subtype_table
[file_type_subtype
].supported_blocks
;
1961 for (size_t block_idx
= 0; block_idx
< num_supported_blocks
;
1963 if (supported_blocks
[block_idx
].type
== type
) {
1965 * OK, that block is known.
1968 if (supported_blocks
[block_idx
].support
== BLOCK_NOT_SUPPORTED
) {
1970 * No, so clearly the option isn't
1971 * supported in that block.
1973 return OPTION_NOT_SUPPORTED
;
1977 * Yes, so check the options.
1979 size_t num_supported_options
;
1980 const struct supported_option_type
*supported_options
;
1982 num_supported_options
= supported_blocks
[block_idx
].num_supported_options
;
1983 supported_options
= supported_blocks
[block_idx
].supported_options
;
1984 for (size_t opt_idx
= 0; opt_idx
< num_supported_options
;
1986 if (supported_options
[opt_idx
].opt
== option
)
1987 return supported_options
[opt_idx
].support
;
1991 * Not found, which means not supported.
1993 return OPTION_NOT_SUPPORTED
;
1998 * The block type wasn't found, which means it's not supported,
1999 * which means the option isn't supported in that block.
2001 return OPTION_NOT_SUPPORTED
;
2005 add_extensions_for_file_type_subtype(int file_type_subtype
, GSList
*extensions
,
2006 GSList
*compression_type_extensions
)
2008 char **extensions_set
, **extensionp
;
2011 if (file_type_subtype
< 0 ||
2012 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
) {
2014 * There's no such file type, so it has no extensions
2021 * Add the default extension, and all of the compressed variants
2022 * from the list of compressed-file extensions, if there is a
2023 * default extension.
2025 if (file_type_subtype_table
[file_type_subtype
].default_file_extension
!= NULL
) {
2026 extensions
= add_extensions(extensions
,
2027 file_type_subtype_table
[file_type_subtype
].default_file_extension
,
2028 compression_type_extensions
);
2031 if (file_type_subtype_table
[file_type_subtype
].additional_file_extensions
!= NULL
) {
2033 * We have additional extensions; add them.
2035 * First, split the extension-list string into a set of
2038 extensions_set
= g_strsplit(file_type_subtype_table
[file_type_subtype
].additional_file_extensions
,
2042 * Add each of those extensions to the list.
2044 for (extensionp
= extensions_set
; *extensionp
!= NULL
;
2046 extension
= *extensionp
;
2049 * Add the extension, and all compressed variants
2050 * of it if requested.
2052 extensions
= add_extensions(extensions
, extension
,
2053 compression_type_extensions
);
2056 g_strfreev(extensions_set
);
2061 /* Return a list of file extensions that are used by the specified file
2064 * If include_compressed is true, the list will include compressed
2065 * extensions, e.g. not just "pcap" but also "pcap.gz" if we can read
2068 * All strings in the list are allocated with g_malloc() and must be freed
2072 wtap_get_file_extensions_list(int file_type_subtype
, bool include_compressed
)
2074 GSList
*extensions
, *compression_type_extensions
;
2076 if (file_type_subtype
< 0 ||
2077 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
)
2078 return NULL
; /* not a valid file type */
2080 if (file_type_subtype_table
[file_type_subtype
].default_file_extension
== NULL
)
2081 return NULL
; /* valid, but no extensions known */
2083 extensions
= NULL
; /* empty list, to start with */
2086 * Add all this file type's extensions, with compressed
2087 * variants if include_compressed is true.
2089 if (include_compressed
) {
2091 * Get compression-type extensions, if any.
2093 compression_type_extensions
= wtap_get_all_compression_type_extensions_list();
2096 * We don't want the compressed file extensions.
2098 compression_type_extensions
= NULL
;
2100 extensions
= add_extensions_for_file_type_subtype(file_type_subtype
, extensions
,
2101 compression_type_extensions
);
2103 g_slist_free(compression_type_extensions
);
2108 /* Return a list of all extensions that are used by all capture file
2109 * types, including compressed extensions, e.g. not just "pcap" but
2110 * also "pcap.gz" if we can read gzipped files.
2112 * "Capture files" means "include file types that correspond to
2113 * collections of network packets, but not file types that
2114 * store data that just happens to be transported over protocols
2115 * such as HTTP but that aren't collections of network packets",
2116 * so that it could be used for "All Capture Files" without picking
2117 * up JPEG files or files such as that - those aren't capture files,
2118 * and we *do* have them listed in the long list of individual file
2119 * types, so omitting them from "All Capture Files" is the right
2122 * All strings in the list are allocated with g_malloc() and must be freed
2125 * This is used to generate a list of extensions to look for if the user
2126 * chooses "All Capture Files" in a file open dialog.
2129 wtap_get_all_capture_file_extensions_list(void)
2131 GSList
*extensions
, *compression_type_extensions
;
2134 init_file_type_extensions();
2136 extensions
= NULL
; /* empty list, to start with */
2139 * Get compression-type extensions, if any.
2141 compression_type_extensions
= wtap_get_all_compression_type_extensions_list();
2143 for (i
= 0; i
< file_type_extensions_arr
->len
; i
++) {
2145 * Is this a capture file, rather than one of the
2146 * other random file types we can read?
2148 if (file_type_extensions
[i
].is_capture_file
) {
2150 * Yes. Add all this file extension type's
2151 * extensions, with compressed variants.
2153 extensions
= add_extensions_for_file_extensions_type(i
,
2154 extensions
, compression_type_extensions
);
2158 g_slist_free(compression_type_extensions
);
2163 /* Return a list of all extensions that are used by all file types that
2164 * we can read, including compressed extensions, e.g. not just "pcap" but
2165 * also "pcap.gz" if we can read gzipped files.
2167 * "File type" means "include file types that correspond to collections
2168 * of network packets, as well as file types that store data that just
2169 * happens to be transported over protocols such as HTTP but that aren't
2170 * collections of network packets, and plain text files".
2172 * All strings in the list are allocated with g_malloc() and must be freed
2175 * This is used to get the "base name" for a file, by stripping off
2176 * compressed-file extensions and extensions that correspond to file
2177 * types that we know about.
2180 wtap_get_all_file_extensions_list(void)
2182 GSList
*extensions
, *compression_type_extensions
;
2184 extensions
= NULL
; /* empty list, to start with */
2187 * Get compression-type extensions, if any.
2189 compression_type_extensions
= wtap_get_all_compression_type_extensions_list();
2191 for (int ft
= 0; ft
< (int)file_type_subtype_table_arr
->len
; ft
++) {
2192 extensions
= add_extensions_for_file_type_subtype(ft
, extensions
,
2193 compression_type_extensions
);
2196 g_slist_free(compression_type_extensions
);
2202 * Free a list returned by wtap_get_file_extension_type_extensions(),
2203 * wtap_get_all_capture_file_extensions_list, wtap_get_file_extensions_list(),
2204 * or wtap_get_all_file_extensions_list().
2207 wtap_free_extensions_list(GSList
*extensions
)
2211 for (extension
= extensions
; extension
!= NULL
;
2212 extension
= g_slist_next(extension
)) {
2213 g_free(extension
->data
);
2215 g_slist_free(extensions
);
2219 * Return the default file extension to use with the specified file type
2220 * and subtype; that's just the extension, without any ".".
2223 wtap_default_file_extension(int file_type_subtype
)
2225 if (file_type_subtype
< 0 ||
2226 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
)
2229 return file_type_subtype_table
[file_type_subtype
].default_file_extension
;
2233 * Return whether we know how to write the specified file type.
2236 wtap_dump_can_open(int file_type_subtype
)
2238 if (file_type_subtype
< 0 ||
2239 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
||
2240 file_type_subtype_table
[file_type_subtype
].dump_open
== NULL
)
2247 * Return whether we know how to write a compressed file of the specified
2252 wtap_dump_can_compress(int file_type_subtype
)
2255 * If this is an unknown file type, or if we have to
2256 * seek when writing out a file with this file type,
2259 if (file_type_subtype
< 0 ||
2260 file_type_subtype
>= (int)file_type_subtype_table_arr
->len
||
2261 file_type_subtype_table
[file_type_subtype
].writing_must_seek
)
2268 wtap_dump_can_compress(int file_type_subtype _U_
)
2274 static bool wtap_dump_open_finish(wtap_dumper
*wdh
, int *err
,
2277 static WFILE_T
wtap_dump_file_open(wtap_dumper
*wdh
, const char *filename
);
2278 static WFILE_T
wtap_dump_file_fdopen(wtap_dumper
*wdh
, int fd
);
2279 static int wtap_dump_file_close(wtap_dumper
*wdh
);
2281 static wtap_dumper
*
2282 wtap_dump_init_dumper(int file_type_subtype
, wtap_compression_type compression_type
,
2283 const wtap_dump_params
*params
, int *err
)
2286 wtap_block_t descr
, file_int_data
;
2287 wtapng_if_descr_mandatory_t
*descr_mand
, *file_int_data_mand
;
2288 GArray
*interfaces
= params
->idb_inf
? params
->idb_inf
->interface_data
: NULL
;
2290 /* Can we write files of this file type/subtype?
2292 * This will fail if file_type_subtype isn't a valid
2293 * file type/subtype value, so, if it doesn't fail,
2294 * we know file_type_subtype is within the bounds of
2295 * the table of file types/subtypes.
2297 if (!wtap_dump_can_open(file_type_subtype
)) {
2298 /* Invalid type, or type we don't know how to write. */
2299 *err
= WTAP_ERR_UNWRITABLE_FILE_TYPE
;
2303 /* OK, we know how to write that file type/subtype; can we write
2304 * the specified encapsulation type in that file type/subtype?
2306 *err
= (*file_type_subtype_table
[file_type_subtype
].can_write_encap
)(params
->encap
);
2307 /* if the err said to check wslua's can_write_encap, try that */
2308 if (*err
== WTAP_ERR_CHECK_WSLUA
2309 && file_type_subtype_table
[file_type_subtype
].wslua_info
!= NULL
2310 && file_type_subtype_table
[file_type_subtype
].wslua_info
->wslua_can_write_encap
!= NULL
) {
2312 *err
= (*file_type_subtype_table
[file_type_subtype
].wslua_info
->wslua_can_write_encap
)(params
->encap
, file_type_subtype_table
[file_type_subtype
].wslua_info
->wslua_data
);
2320 /* Check whether we can open a capture file with that file type
2321 * and that encapsulation, and, if the compression type isn't
2322 * "uncompressed", whether we can write a *compressed* file
2323 * of that file type.
2324 * If we're doing compression, can this file type/subtype be
2325 written in compressed form?
2327 * (The particular type doesn't matter - if the file can't
2328 * be written 100% sequentially, we can't compress it,
2329 * because we can't go back and overwrite something we've
2332 if (compression_type
!= WTAP_UNCOMPRESSED
&&
2333 !wtap_dump_can_compress(file_type_subtype
)) {
2334 *err
= WTAP_ERR_COMPRESSION_NOT_SUPPORTED
;
2338 /* Allocate a data structure for the output stream. */
2339 wdh
= g_new0(wtap_dumper
, 1);
2345 wdh
->file_type_subtype
= file_type_subtype
;
2346 wdh
->snaplen
= params
->snaplen
;
2347 wdh
->file_encap
= params
->encap
;
2348 wdh
->compression_type
= compression_type
;
2349 wdh
->wslua_data
= NULL
;
2350 wdh
->shb_iface_to_global
= params
->shb_iface_to_global
;
2351 wdh
->interface_data
= g_array_new(false, false, sizeof(wtap_block_t
));
2353 /* Set Section Header Block data */
2354 wdh
->shb_hdrs
= params
->shb_hdrs
;
2355 /* Set Name Resolution Block data */
2356 wdh
->nrbs_growing
= params
->nrbs_growing
;
2357 /* Set Interface Description Block data */
2358 if (interfaces
&& interfaces
->len
) {
2359 if (!params
->dont_copy_idbs
) { /* XXX */
2362 /* Note: this memory is owned by wtap_dumper and will become
2363 * invalid after wtap_dump_close. */
2364 for (itf_count
= 0; itf_count
< interfaces
->len
; itf_count
++) {
2365 file_int_data
= g_array_index(interfaces
, wtap_block_t
, itf_count
);
2366 file_int_data_mand
= (wtapng_if_descr_mandatory_t
*)wtap_block_get_mandatory_data(file_int_data
);
2367 descr
= wtap_block_make_copy(file_int_data
);
2368 if ((params
->encap
!= WTAP_ENCAP_PER_PACKET
) && (params
->encap
!= file_int_data_mand
->wtap_encap
)) {
2369 descr_mand
= (wtapng_if_descr_mandatory_t
*)wtap_block_get_mandatory_data(descr
);
2370 descr_mand
->wtap_encap
= params
->encap
;
2372 g_array_append_val(wdh
->interface_data
, descr
);
2375 } else if (params
->encap
!= WTAP_ENCAP_NONE
&& params
->encap
!= WTAP_ENCAP_PER_PACKET
) {
2376 /* Generate a fake IDB if we don't have one, unless the
2377 * file encapsulation is none. (WTAP_ENCAP_NONE either
2378 * means that there are no interfaces, or they will be
2379 * provided later when reading the file in single-pass mode.)
2381 * For WTAP_ENCAP_PER_PACKET, we'll have to generate IDBs
2382 * from packet records as they come in. (pcapng does this now.)
2384 * XXX File types should provide their own IDBs (possibly
2385 * fake ones generated by wtap_add_generated_idb()), in
2386 * order to support being used as inputs for mergecap where
2387 * pcapng is the output.
2389 descr
= wtap_dump_params_generate_idb(params
);
2390 g_array_append_val(wdh
->interface_data
, descr
);
2392 /* Set Decryption Secrets Blocks */
2393 wdh
->dsbs_initial
= params
->dsbs_initial
;
2394 wdh
->dsbs_growing
= params
->dsbs_growing
;
2395 /* Set Sysdig meta events */
2396 wdh
->mevs_growing
= params
->mevs_growing
;
2401 wtap_dump_open(const char *filename
, int file_type_subtype
,
2402 wtap_compression_type compression_type
, const wtap_dump_params
*params
,
2403 int *err
, char **err_info
)
2411 /* Allocate and initialize a data structure for the output stream. */
2412 wdh
= wtap_dump_init_dumper(file_type_subtype
, compression_type
, params
,
2417 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2418 to a generic "the open failed" error. */
2419 errno
= WTAP_ERR_CANT_OPEN
;
2420 fh
= wtap_dump_file_open(wdh
, filename
);
2424 return NULL
; /* can't create file */
2428 if (!wtap_dump_open_finish(wdh
, err
, err_info
)) {
2429 /* Get rid of the file we created; we couldn't finish
2431 wtap_dump_file_close(wdh
);
2432 ws_unlink(filename
);
2440 wtap_dump_open_tempfile(const char *tmpdir
, char **filenamep
, const char *pfx
,
2441 int file_type_subtype
, wtap_compression_type compression_type
,
2442 const wtap_dump_params
*params
, int *err
, char **err_info
)
2450 /* No path name for the temporary file yet. */
2456 /* Allocate and initialize a data structure for the output stream. */
2457 wdh
= wtap_dump_init_dumper(file_type_subtype
, compression_type
, params
,
2462 /* Choose an appropriate suffix for the file */
2463 ext
= wtap_default_file_extension(file_type_subtype
);
2468 (void) g_strlcat(sfx
, ext
, 16);
2470 /* Choose a random name for the file */
2471 fd
= create_tempfile(tmpdir
, filenamep
, pfx
, sfx
, NULL
);
2473 *err
= WTAP_ERR_CANT_OPEN
;
2475 return NULL
; /* can't create file */
2478 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2479 to a generic "the open failed" error. */
2480 errno
= WTAP_ERR_CANT_OPEN
;
2481 fh
= wtap_dump_file_fdopen(wdh
, fd
);
2486 return NULL
; /* can't create file */
2490 if (!wtap_dump_open_finish(wdh
, err
, err_info
)) {
2491 /* Get rid of the file we created; we couldn't finish
2493 wtap_dump_file_close(wdh
);
2494 ws_unlink(*filenamep
);
2502 wtap_dump_fdopen(int fd
, int file_type_subtype
, wtap_compression_type compression_type
,
2503 const wtap_dump_params
*params
, int *err
, char **err_info
)
2511 /* Allocate and initialize a data structure for the output stream. */
2512 wdh
= wtap_dump_init_dumper(file_type_subtype
, compression_type
, params
,
2517 /* In case "fopen()" fails but doesn't set "errno", set "errno"
2518 to a generic "the open failed" error. */
2519 errno
= WTAP_ERR_CANT_OPEN
;
2520 fh
= wtap_dump_file_fdopen(wdh
, fd
);
2524 return NULL
; /* can't create standard I/O stream */
2528 if (!wtap_dump_open_finish(wdh
, err
, err_info
)) {
2529 wtap_dump_file_close(wdh
);
2537 wtap_dump_open_stdout(int file_type_subtype
, wtap_compression_type compression_type
,
2538 const wtap_dump_params
*params
, int *err
, char **err_info
)
2544 * Duplicate the file descriptor, so that we can close the
2545 * wtap_dumper handle the same way we close any other
2546 * wtap_dumper handle, without closing the standard output.
2556 * Put the new descriptor into binary mode.
2558 * XXX - even if the file format we're writing is a text
2561 if (_setmode(new_fd
, O_BINARY
) == -1) {
2562 /* "Should not happen" */
2569 wdh
= wtap_dump_fdopen(new_fd
, file_type_subtype
, compression_type
,
2570 params
, err
, err_info
);
2572 /* Failed; close the new FD */
2580 wtap_dump_open_finish(wtap_dumper
*wdh
, int *err
, char **err_info
)
2585 /* Can we do a seek on the file descriptor?
2586 If not, note that fact. */
2587 if (wdh
->compression_type
!= WTAP_UNCOMPRESSED
) {
2590 fd
= ws_fileno((FILE *)wdh
->fh
);
2591 if (ws_lseek64(fd
, 1, SEEK_CUR
) == (off_t
) -1)
2594 /* Undo the seek. */
2595 ws_lseek64(fd
, 0, SEEK_SET
);
2600 /* If this file type requires seeking, and we can't seek, fail. */
2601 if (file_type_subtype_table
[wdh
->file_type_subtype
].writing_must_seek
&& cant_seek
) {
2602 *err
= WTAP_ERR_CANT_WRITE_TO_PIPE
;
2606 /* Set wdh with wslua data if any - this is how we pass the data
2607 * to the file writer.
2609 if (file_type_subtype_table
[wdh
->file_type_subtype
].wslua_info
)
2610 wdh
->wslua_data
= file_type_subtype_table
[wdh
->file_type_subtype
].wslua_info
->wslua_data
;
2612 /* Now try to open the file for writing. */
2613 if (!(*file_type_subtype_table
[wdh
->file_type_subtype
].dump_open
)(wdh
, err
,
2618 return true; /* success! */
2622 wtap_dump_add_idb(wtap_dumper
*wdh
, wtap_block_t idb
, int *err
,
2625 if (wdh
->subtype_add_idb
== NULL
) {
2626 /* Not supported. */
2627 *err
= WTAP_ERR_UNWRITABLE_REC_TYPE
;
2628 *err_info
= g_strdup("Adding IDBs isn't supported by this file type");
2633 return (wdh
->subtype_add_idb
)(wdh
, idb
, err
, err_info
);
2637 wtap_dump(wtap_dumper
*wdh
, const wtap_rec
*rec
,
2638 const uint8_t *pd
, int *err
, char **err_info
)
2642 return (wdh
->subtype_write
)(wdh
, rec
, pd
, err
, err_info
);
2646 wtap_dump_flush(wtap_dumper
*wdh
, int *err
)
2649 if (wdh
->compression_type
== WTAP_GZIP_COMPRESSED
) {
2650 if (gzwfile_flush((GZWFILE_T
)wdh
->fh
) == -1) {
2651 *err
= gzwfile_geterr((GZWFILE_T
)wdh
->fh
);
2657 if (fflush((FILE *)wdh
->fh
) == EOF
) {
2666 wtap_dump_close(wtap_dumper
*wdh
, bool *needs_reload
,
2667 int *err
, char **err_info
)
2673 if (wdh
->subtype_finish
!= NULL
) {
2674 /* There's a finish routine for this dump stream. */
2675 if (!(wdh
->subtype_finish
)(wdh
, err
, err_info
))
2678 errno
= WTAP_ERR_CANT_CLOSE
;
2679 if (wtap_dump_file_close(wdh
) == EOF
) {
2681 /* The per-format finish function succeeded,
2682 but the stream close didn't. Save the
2683 reason why, if our caller asked for it. */
2689 if (needs_reload
!= NULL
)
2690 *needs_reload
= wdh
->needs_reload
;
2692 wtap_block_array_free(wdh
->interface_data
);
2693 wtap_block_array_unref(wdh
->dsbs_initial
);
2699 wtap_dump_file_type_subtype(wtap_dumper
*wdh
)
2701 return wdh
->file_type_subtype
;
2705 wtap_get_bytes_dumped(wtap_dumper
*wdh
)
2707 return wdh
->bytes_dumped
;
2711 wtap_set_bytes_dumped(wtap_dumper
*wdh
, int64_t bytes_dumped
)
2713 wdh
->bytes_dumped
= bytes_dumped
;
2717 wtap_addrinfo_list_empty(addrinfo_lists_t
*addrinfo_lists
)
2719 return (addrinfo_lists
== NULL
) ||
2720 ((addrinfo_lists
->ipv4_addr_list
== NULL
) &&
2721 (addrinfo_lists
->ipv6_addr_list
== NULL
));
2725 wtap_dump_set_addrinfo_list(wtap_dumper
*wdh
, addrinfo_lists_t
*addrinfo_lists
)
2727 if (!wdh
|| wdh
->file_type_subtype
< 0 ||
2728 wdh
->file_type_subtype
>= (int)file_type_subtype_table_arr
->len
||
2729 wtap_file_type_subtype_supports_block(wdh
->file_type_subtype
, WTAP_BLOCK_NAME_RESOLUTION
) == BLOCK_NOT_SUPPORTED
)
2731 wdh
->addrinfo_lists
= addrinfo_lists
;
2736 wtap_dump_discard_name_resolution(wtap_dumper
*wdh
)
2738 /* As below for DSBs. */
2739 if (wdh
->nrbs_growing
) {
2741 * Pretend we've written all of them.
2743 wdh
->nrbs_growing_written
= wdh
->nrbs_growing
->len
;
2748 wtap_dump_discard_decryption_secrets(wtap_dumper
*wdh
)
2751 * This doesn't free the data, as it might be pointed to
2752 * from other structures; it merely marks all of them as
2753 * having been written to the file, so that they don't
2754 * get written by wtap_dump().
2756 * XXX - our APIs for dealing with some metadata, such as
2757 * resolved names, decryption secrets, and interface
2758 * statistics is not very well oriented towards one-pass
2759 * programs; this needs to be cleaned up. See bug 15502.
2761 if (wdh
->dsbs_growing
) {
2763 * Pretend we've written all of them.
2765 wdh
->dsbs_growing_written
= wdh
->dsbs_growing
->len
;
2770 wtap_dump_discard_sysdig_meta_events(wtap_dumper
*wdh
)
2772 /* As above for DSBs. */
2773 if (wdh
->mevs_growing
) {
2775 * Pretend we've written all of them.
2777 wdh
->mevs_growing_written
= wdh
->mevs_growing
->len
;
2781 /* internally open a file for writing (compressed or not) */
2784 wtap_dump_file_open(wtap_dumper
*wdh
, const char *filename
)
2786 if (wdh
->compression_type
== WTAP_GZIP_COMPRESSED
) {
2787 return gzwfile_open(filename
);
2789 return ws_fopen(filename
, "wb");
2794 wtap_dump_file_open(wtap_dumper
*wdh _U_
, const char *filename
)
2796 return ws_fopen(filename
, "wb");
2800 /* internally open a file for writing (compressed or not) */
2803 wtap_dump_file_fdopen(wtap_dumper
*wdh
, int fd
)
2805 if (wdh
->compression_type
== WTAP_GZIP_COMPRESSED
) {
2806 return gzwfile_fdopen(fd
);
2808 return ws_fdopen(fd
, "wb");
2813 wtap_dump_file_fdopen(wtap_dumper
*wdh _U_
, int fd
)
2815 return ws_fdopen(fd
, "wb");
2819 /* internally writing raw bytes (compressed or not). Updates wdh->bytes_dumped on success */
2821 wtap_dump_file_write(wtap_dumper
*wdh
, const void *buf
, size_t bufsize
, int *err
)
2826 if (wdh
->compression_type
== WTAP_GZIP_COMPRESSED
) {
2827 nwritten
= gzwfile_write((GZWFILE_T
)wdh
->fh
, buf
, (unsigned int) bufsize
);
2829 * gzwfile_write() returns 0 on error.
2831 if (nwritten
== 0) {
2832 *err
= gzwfile_geterr((GZWFILE_T
)wdh
->fh
);
2838 errno
= WTAP_ERR_CANT_WRITE
;
2839 nwritten
= fwrite(buf
, 1, bufsize
, (FILE *)wdh
->fh
);
2841 * At least according to the macOS man page,
2842 * this can return a short count on an error.
2844 if (nwritten
!= bufsize
) {
2845 if (ferror((FILE *)wdh
->fh
))
2848 *err
= WTAP_ERR_SHORT_WRITE
;
2852 wdh
->bytes_dumped
+= bufsize
;
2856 /* internally close a file for writing (compressed or not) */
2858 wtap_dump_file_close(wtap_dumper
*wdh
)
2861 if (wdh
->compression_type
== WTAP_GZIP_COMPRESSED
)
2862 return gzwfile_close((GZWFILE_T
)wdh
->fh
);
2865 return fclose((FILE *)wdh
->fh
);
2869 wtap_dump_file_seek(wtap_dumper
*wdh
, int64_t offset
, int whence
, int *err
)
2872 if (wdh
->compression_type
!= WTAP_UNCOMPRESSED
) {
2873 *err
= WTAP_ERR_CANT_SEEK_COMPRESSED
;
2878 if (-1 == ws_fseek64((FILE *)wdh
->fh
, offset
, whence
)) {
2889 wtap_dump_file_tell(wtap_dumper
*wdh
, int *err
)
2893 if (wdh
->compression_type
!= WTAP_UNCOMPRESSED
) {
2894 *err
= WTAP_ERR_CANT_SEEK_COMPRESSED
;
2899 if (-1 == (rval
= ws_ftell64((FILE *)wdh
->fh
))) {
2910 cleanup_open_routines(void)
2913 struct open_info
*i_open
;
2915 if (open_routines
!= NULL
&& open_info_arr
) {
2916 for (i
= 0, i_open
= open_routines
; i
< open_info_arr
->len
; i
++, i_open
++) {
2917 if (i_open
->extensions
!= NULL
)
2918 g_strfreev(i_open
->extensions_set
);
2921 g_array_free(open_info_arr
, true);
2922 open_info_arr
= NULL
;
2927 * Allow built-in file handlers (but *not* plugin file handlers!) to
2928 * register a "backwards-compatibility" name and file type value, to
2929 * put in the Lua wtap_filetypes table.
2931 * This is only to be used as long as we have that table; new Lua
2932 * code should use wtap_name_to_file_type_subtype() to look up
2933 * file types by their name, just as C code should.
2935 * The backwards-ccmpatibility names are the old WTAP_FILE_TYPE_SUBTYPE_
2936 * #define name, with WTAP_FILE_TYPE_SUBTYPE_ removed.
2939 static GArray
*backwards_compatibility_lua_names
;
2942 // NOLINTNEXTLINE(misc-no-recursion)
2943 wtap_register_backwards_compatibility_lua_name(const char *name
, int ft
)
2945 struct backwards_compatibiliity_lua_name entry
;
2948 * Create the table if it doesn't already exist.
2949 * Use the same size as we do for the file type/subtype table.
2951 if (backwards_compatibility_lua_names
== NULL
) {
2952 backwards_compatibility_lua_names
= g_array_sized_new(false,
2953 true, sizeof(struct backwards_compatibiliity_lua_name
),
2954 wtap_module_count
*2);
2957 * Extra backwards compatibility hack - add entries
2958 * for time stamp precision values(!), as well as
2959 * for "UNKNOWN" and types that don't yet register
2962 * If new WS_TSPREC_ value are added, don't bother
2963 * adding them to this table; any Lua program that
2964 * would use them should use the wtap_tsprecs type.
2966 * (Recursion: see "recursion".)
2968 wtap_register_backwards_compatibility_lua_name("TSPREC_SEC",
2970 wtap_register_backwards_compatibility_lua_name("TSPREC_DSEC",
2971 WTAP_TSPREC_100_MSEC
);
2972 wtap_register_backwards_compatibility_lua_name("TSPREC_CSEC",
2973 WTAP_TSPREC_10_MSEC
);
2974 wtap_register_backwards_compatibility_lua_name("TSPREC_MSEC",
2976 wtap_register_backwards_compatibility_lua_name("TSPREC_USEC",
2978 wtap_register_backwards_compatibility_lua_name("TSPREC_NSEC",
2980 wtap_register_backwards_compatibility_lua_name("UNKNOWN",
2981 WTAP_FILE_TYPE_SUBTYPE_UNKNOWN
);
2985 g_array_append_val(backwards_compatibility_lua_names
, entry
);
2989 get_backwards_compatibility_lua_table(void)
2991 return backwards_compatibility_lua_names
;
2995 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3000 * indent-tabs-mode: t
3003 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3004 * :indentSize=8:tabSize=8:noTabs=false: