File: | wiretap/libpcap.c |
Warning: | line 1449, column 3 Value stored to 'bytes_to_read' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* libpcap.c |
2 | * |
3 | * Wiretap Library |
4 | * Copyright (c) 1998 by Gilbert Ramirez <[email protected]> |
5 | * |
6 | * SPDX-License-Identifier: GPL-2.0-or-later |
7 | */ |
8 | |
9 | #include "config.h" |
10 | #include "libpcap.h" |
11 | |
12 | #include <stdlib.h> |
13 | #include <string.h> |
14 | #include "wtap-int.h" |
15 | #include "file_wrappers.h" |
16 | #include "required_file_handlers.h" |
17 | #include "pcap-common.h" |
18 | #include "pcap-encap.h" |
19 | #include "erf-common.h" |
20 | #include <jtckdint.h> |
21 | #include <wsutil/ws_assert.h> |
22 | |
23 | /* |
24 | * The "libpcap" file format was determined by reading the "libpcap" code; |
25 | * wiretap reads the "libpcap" file format with its own code, rather than |
26 | * using the "libpcap" library's code to read it. |
27 | * See source to the "libpcap" library for information on the "libpcap" |
28 | * file format. |
29 | */ |
30 | |
31 | /* |
32 | * Private per-wtap_t data needed to read a file. |
33 | */ |
34 | typedef enum { |
35 | NOT_SWAPPED, |
36 | SWAPPED, |
37 | MAYBE_SWAPPED |
38 | } swapped_type_t; |
39 | |
40 | /* |
41 | * Variants of pcap, some distinguished by the magic number and some, |
42 | * alas, not. |
43 | * |
44 | * (Don't do that. Srsly.) |
45 | */ |
46 | typedef enum { |
47 | PCAP, /* OG pcap */ |
48 | PCAP_NSEC, /* PCAP with nanosecond resolution */ |
49 | PCAP_AIX, /* AIX pcap */ |
50 | PCAP_SS990417, /* Modified, from 1999-04-17 patch */ |
51 | PCAP_SS990915, /* Modified, from 1999-09-15 patch */ |
52 | PCAP_SS991029, /* Modified, from 1999-10-29 patch */ |
53 | PCAP_NOKIA, /* Nokia pcap */ |
54 | PCAP_UNKNOWN /* Unknown as yet */ |
55 | } pcap_variant_t; |
56 | |
57 | typedef struct { |
58 | bool_Bool byte_swapped; |
59 | swapped_type_t lengths_swapped; |
60 | uint16_t version_major; |
61 | uint16_t version_minor; |
62 | pcap_variant_t variant; |
63 | int fcs_len; |
64 | void *encap_priv; |
65 | } libpcap_t; |
66 | |
67 | /* Try to read the first few records of the capture file. */ |
68 | static bool_Bool libpcap_try_variants(wtap *wth, const pcap_variant_t *variants, |
69 | size_t n_variants, int *err, char **err_info); |
70 | static int libpcap_try_variant(wtap *wth, pcap_variant_t variant, |
71 | int *err, char **err_info); |
72 | typedef enum { |
73 | TRY_REC_KEEP_READING, /* Keep reading records */ |
74 | TRY_REC_EOF, /* EOF - no ore records to read */ |
75 | TRY_REC_ERROR /* Error - give up */ |
76 | } try_record_ret_t; |
77 | static try_record_ret_t libpcap_try_record(wtap *wth, pcap_variant_t variant, |
78 | int *figure_of_meritp, int *err, char **err_info); |
79 | |
80 | static bool_Bool libpcap_read(wtap *wth, wtap_rec *rec, |
81 | int *err, char **err_info, int64_t *data_offset); |
82 | static bool_Bool libpcap_seek_read(wtap *wth, int64_t seek_off, |
83 | wtap_rec *rec, int *err, char **err_info); |
84 | static bool_Bool libpcap_read_packet(wtap *wth, FILE_T fh, |
85 | wtap_rec *rec, int *err, char **err_info); |
86 | static bool_Bool libpcap_read_header(wtap *wth, FILE_T fh, int *err, char **err_info, |
87 | struct pcaprec_ss990915_hdr *hdr); |
88 | static void libpcap_close(wtap *wth); |
89 | |
90 | static bool_Bool libpcap_dump_pcap(wtap_dumper *wdh, const wtap_rec *rec, |
91 | int *err, char **err_info); |
92 | static bool_Bool libpcap_dump_pcap_nsec(wtap_dumper *wdh, const wtap_rec *rec, |
93 | int *err, char **err_info); |
94 | static bool_Bool libpcap_dump_pcap_ss990417(wtap_dumper *wdh, const wtap_rec *rec, |
95 | int *err, char **err_info); |
96 | static bool_Bool libpcap_dump_pcap_ss990915(wtap_dumper *wdh, const wtap_rec *rec, |
97 | int *err, char **err_info); |
98 | static bool_Bool libpcap_dump_pcap_ss991029(wtap_dumper *wdh, const wtap_rec *rec, |
99 | int *err, char **err_info); |
100 | static bool_Bool libpcap_dump_pcap_nokia(wtap_dumper *wdh, const wtap_rec *rec, |
101 | int *err, char **err_info); |
102 | |
103 | /* |
104 | * Subfields of the field containing the link-layer header type. |
105 | * |
106 | * Link-layer header types are assigned for both pcap and |
107 | * pcapng, and the same value must work with both. In pcapng, |
108 | * the link-layer header type field in an Interface Description |
109 | * Block is 16 bits, so only the bottommost 16 bits of the |
110 | * link-layer header type in a pcap file can be used for the |
111 | * header type value. |
112 | * |
113 | * In libpcap, the upper 16 bits, from the top down, are divided into: |
114 | * |
115 | * A 4-bit "FCS length" field, to allow the FCS length to |
116 | * be specified, just as it can be specified in the if_fcslen |
117 | * field of the pcapng IDB. The field is in units of 16 bits, |
118 | * i.e. 1 means 16 bits of FCS, 2 means 32 bits of FCS, etc.. |
119 | * |
120 | * A reserved bit, which must be zero. |
121 | * |
122 | * An "FCS length present" flag; if 0, the "FCS length" field |
123 | * should be ignored, and if 1, the "FCS length" field should |
124 | * be used. |
125 | * |
126 | * 10 reserved bits, which must be zero. They were originally |
127 | * intended to be used as a "class" field, allowing additional |
128 | * classes of link-layer types to be defined, with a class value |
129 | * of 0 indicating that the link-layer type is a LINKTYPE_ value. |
130 | * A value of 0x224 was, at one point, used by NetBSD to define |
131 | * "raw" packet types, with the lower 16 bits containing a |
132 | * NetBSD AF_ value; see |
133 | * |
134 | * https://marc.info/?l=tcpdump-workers&m=98296750229149&w=2 |
135 | * |
136 | * It's unknown whether those were ever used in capture files, |
137 | * or if the intent was just to use it as a link-layer type |
138 | * for BPF programs; NetBSD's libpcap used to support them in |
139 | * the BPF code generator, but it no longer does so. If it |
140 | * was ever used in capture files, or if classes other than |
141 | * "LINKTYPE_ value" are ever useful in capture files, we could |
142 | * re-enable this, and use the reserved 16 bits following the |
143 | * link-layer type in pcapng files to hold the class information |
144 | * there. (Note, BTW, that LINKTYPE_RAW/DLT_RAW is now being |
145 | * interpreted by libpcap, tcpdump, and Wireshark as "raw IP", |
146 | * including both IPv4 and IPv6, with the version number in the |
147 | * header being checked to see which it is, not just "raw IPv4"; |
148 | * there are LINKTYPE_IPV4/DLT_IPV4 and LINKTYPE_IPV6/DLT_IPV6 |
149 | * values if "these are IPv{4,6} and only IPv{4,6} packets" |
150 | * types are needed.) |
151 | * |
152 | * Or we might be able to use it for other purposes. |
153 | */ |
154 | #define LT_LINKTYPE(x)((x) & 0x0000FFFF) ((x) & 0x0000FFFF) |
155 | #define LT_RESERVED1(x)((x) & 0x03FF0000) ((x) & 0x03FF0000) |
156 | #define LT_FCS_LENGTH_PRESENT(x)((x) & 0x04000000) ((x) & 0x04000000) |
157 | #define LT_FCS_LENGTH(x)(((x) & 0xF0000000) >> 28) (((x) & 0xF0000000) >> 28) |
158 | #define LT_FCS_DATALINK_EXT(x)(((x) & 0xF) << 28) | 0x04000000) (((x) & 0xF) << 28) | 0x04000000) |
159 | |
160 | /* |
161 | * Private file type/subtype values; pcap and nanosecond-resolution |
162 | * pcap are imported from wiretap/file_access.c. |
163 | */ |
164 | static int pcap_aix_file_type_subtype = -1; |
165 | static int pcap_ss990417_file_type_subtype = -1; |
166 | static int pcap_ss990915_file_type_subtype = -1; |
167 | static int pcap_ss991029_file_type_subtype = -1; |
168 | static int pcap_nokia_file_type_subtype = -1; |
169 | |
170 | /* |
171 | * pcap variants that use the standard magic number. |
172 | */ |
173 | static const pcap_variant_t variants_standard[] = { |
174 | PCAP, |
175 | PCAP_SS990417, |
176 | PCAP_NOKIA |
177 | }; |
178 | #define N_VARIANTS_STANDARD(sizeof (variants_standard) / sizeof ((variants_standard)[0]) ) G_N_ELEMENTS(variants_standard)(sizeof (variants_standard) / sizeof ((variants_standard)[0]) ) |
179 | |
180 | /* |
181 | * pcap variants that use the modified magic number. |
182 | */ |
183 | static const pcap_variant_t variants_modified[] = { |
184 | PCAP_SS991029, |
185 | PCAP_SS990915 |
186 | }; |
187 | #define N_VARIANTS_MODIFIED(sizeof (variants_modified) / sizeof ((variants_modified)[0]) ) G_N_ELEMENTS(variants_modified)(sizeof (variants_modified) / sizeof ((variants_modified)[0]) ) |
188 | |
189 | wtap_open_return_val libpcap_open(wtap *wth, int *err, char **err_info) |
190 | { |
191 | uint32_t magic; |
192 | struct pcap_hdr hdr; |
193 | bool_Bool byte_swapped; |
194 | pcap_variant_t variant; |
195 | libpcap_t *libpcap; |
196 | bool_Bool skip_ixia_extra = false0; |
197 | |
198 | /* Read in the number that should be at the start of a "libpcap" file */ |
199 | if (!wtap_read_bytes(wth->fh, &magic, sizeof magic, err, err_info)) { |
200 | if (*err != WTAP_ERR_SHORT_READ-12) |
201 | return WTAP_OPEN_ERROR; |
202 | return WTAP_OPEN_NOT_MINE; |
203 | } |
204 | |
205 | switch (magic) { |
206 | |
207 | case PCAP_MAGIC0xa1b2c3d4: |
208 | /* Host that wrote it has our byte order, and was running |
209 | a program using either standard or ss990417 libpcap, |
210 | or maybe it was written by AIX. That means we don't |
211 | yet know the variant. */ |
212 | byte_swapped = false0; |
213 | variant = PCAP_UNKNOWN; |
214 | break; |
215 | |
216 | case PCAP_SWAPPED_MAGIC0xd4c3b2a1: |
217 | /* Host that wrote it has a byte order opposite to ours, |
218 | and was running a program using either standard or |
219 | ss990417 libpcap, or maybe it was written by AIX. |
220 | That means we don't yet know the variant. */ |
221 | byte_swapped = true1; |
222 | variant = PCAP_UNKNOWN; |
223 | break; |
224 | |
225 | case PCAP_IXIAHW_MAGIC0x1c0001ac: |
226 | /* Ixia "lcap" hardware-capture variant, in our |
227 | byte order, in which there's an extra 4-byte |
228 | field at the end of the file header, containing |
229 | the total number of bytes of packet records in |
230 | the file, i.e. the file size minus the file header |
231 | size. It's otherwise like standard pcap, with |
232 | nanosecond time-stamp resolution. |
233 | |
234 | See issue #14073. */ |
235 | skip_ixia_extra = true1; |
236 | byte_swapped = false0; |
237 | variant = PCAP_NSEC; |
238 | break; |
239 | |
240 | case PCAP_SWAPPED_IXIAHW_MAGIC0xac01001c: |
241 | /* Ixia "lcap" hardware-capture variant, in a byte |
242 | order opposite to ours, in which there's an extra |
243 | 4-byte field at the end of the file header, |
244 | containing the total number of bytes of packet |
245 | records in the file, i.e. the file size minus |
246 | the file header size. It's otherwise like standard |
247 | pcap with nanosecond time-stamp resolution. |
248 | |
249 | See issue #14073. */ |
250 | skip_ixia_extra = true1; |
251 | byte_swapped = true1; |
252 | variant = PCAP_NSEC; |
253 | break; |
254 | |
255 | case PCAP_IXIASW_MAGIC0x1c0001ab: |
256 | /* Ixia "lcap" software-capture variant, in our |
257 | byte order, in which there's an extra 4-byte |
258 | field at the end of the file header, containing |
259 | the total number of bytes of packet records in |
260 | the file, i.e. the file size minus the file header |
261 | size. It's otherwise like standard pcap, with |
262 | microsecond time-stamp resolution. |
263 | |
264 | See issue #14073. */ |
265 | skip_ixia_extra = true1; |
266 | byte_swapped = false0; |
267 | variant = PCAP; |
268 | break; |
269 | |
270 | case PCAP_SWAPPED_IXIASW_MAGIC0xab01001c: |
271 | /* Ixia "lcap" software-capture variant, in a byte |
272 | order opposite to ours, in which there's an extra |
273 | 4-byte field at the end of the file header, |
274 | containing the total number of bytes of packet |
275 | records in the file, i.e. the file size minus |
276 | the file header size. It's otherwise like standard |
277 | pcap with microsecond time-stamp resolution. |
278 | |
279 | See issue #14073. */ |
280 | skip_ixia_extra = true1; |
281 | byte_swapped = true1; |
282 | variant = PCAP; |
283 | break; |
284 | |
285 | case PCAP_MODIFIED_MAGIC0xa1b2cd34: |
286 | /* Host that wrote it has our byte order, and was running |
287 | a program using either ss990915 or ss991029 libpcap. |
288 | That means we don't yet know the variant; there's |
289 | no obvious default, so default to "unknown". */ |
290 | byte_swapped = false0; |
291 | variant = PCAP_UNKNOWN; |
292 | break; |
293 | |
294 | case PCAP_SWAPPED_MODIFIED_MAGIC0x34cdb2a1: |
295 | /* Host that wrote it out has a byte order opposite to |
296 | ours, and was running a program using either ss990915 |
297 | or ss991029 libpcap. That means we don't yet know |
298 | the variant; there's no obvious default, so default |
299 | to "unknown". */ |
300 | byte_swapped = true1; |
301 | variant = PCAP_UNKNOWN; |
302 | break; |
303 | |
304 | case PCAP_NSEC_MAGIC0xa1b23c4d: |
305 | /* Host that wrote it has our byte order, and was writing |
306 | the file in a format similar to standard libpcap |
307 | except that the time stamps have nanosecond resolution. */ |
308 | byte_swapped = false0; |
309 | variant = PCAP_NSEC; |
310 | break; |
311 | |
312 | case PCAP_SWAPPED_NSEC_MAGIC0x4d3cb2a1: |
313 | /* Host that wrote it out has a byte order opposite to |
314 | ours, and was writing the file in a format similar to |
315 | standard libpcap except that the time stamps have |
316 | nanosecond resolution. */ |
317 | byte_swapped = true1; |
318 | variant = PCAP_NSEC; |
319 | break; |
320 | |
321 | default: |
322 | /* Not a "libpcap" type we know about. */ |
323 | return WTAP_OPEN_NOT_MINE; |
324 | } |
325 | |
326 | /* Read the rest of the header. */ |
327 | if (!wtap_read_bytes(wth->fh, &hdr, sizeof hdr, err, err_info)) |
328 | return WTAP_OPEN_ERROR; |
329 | if (skip_ixia_extra) { |
330 | /* |
331 | * Skip 4 bytes of size information in the file header. |
332 | */ |
333 | if (!wtap_read_bytes(wth->fh, NULL((void*)0), 4, err, err_info)) |
334 | return WTAP_OPEN_ERROR; |
335 | } |
336 | |
337 | if (byte_swapped) { |
338 | /* Byte-swap the header fields about which we care. */ |
339 | magic = GUINT32_SWAP_LE_BE(magic)(((guint32) ( (((guint32) (magic) & (guint32) 0x000000ffU ) << 24) | (((guint32) (magic) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (magic) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (magic) & (guint32) 0xff000000U ) >> 24)))); |
340 | hdr.version_major = GUINT16_SWAP_LE_BE(hdr.version_major)(((guint16) ( (guint16) ((guint16) (hdr.version_major) >> 8) | (guint16) ((guint16) (hdr.version_major) << 8)))); |
341 | hdr.version_minor = GUINT16_SWAP_LE_BE(hdr.version_minor)(((guint16) ( (guint16) ((guint16) (hdr.version_minor) >> 8) | (guint16) ((guint16) (hdr.version_minor) << 8)))); |
342 | hdr.snaplen = GUINT32_SWAP_LE_BE(hdr.snaplen)(((guint32) ( (((guint32) (hdr.snaplen) & (guint32) 0x000000ffU ) << 24) | (((guint32) (hdr.snaplen) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (hdr.snaplen) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (hdr.snaplen) & (guint32) 0xff000000U ) >> 24)))); |
343 | hdr.network = GUINT32_SWAP_LE_BE(hdr.network)(((guint32) ( (((guint32) (hdr.network) & (guint32) 0x000000ffU ) << 24) | (((guint32) (hdr.network) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (hdr.network) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (hdr.network) & (guint32) 0xff000000U ) >> 24)))); |
344 | } |
345 | if (hdr.version_major < 2) { |
346 | /* We only support version 2.0 and later. */ |
347 | *err = WTAP_ERR_UNSUPPORTED-4; |
348 | *err_info = ws_strdup_printf("pcap: major version %u unsupported",wmem_strdup_printf(((void*)0), "pcap: major version %u unsupported" , hdr.version_major) |
349 | hdr.version_major)wmem_strdup_printf(((void*)0), "pcap: major version %u unsupported" , hdr.version_major); |
350 | return WTAP_OPEN_ERROR; |
351 | } |
352 | |
353 | /* This is a libpcap file */ |
354 | wth->subtype_read = libpcap_read; |
355 | wth->subtype_seek_read = libpcap_seek_read; |
356 | wth->subtype_close = libpcap_close; |
357 | wth->snapshot_length = hdr.snaplen; |
358 | libpcap = g_new0(libpcap_t, 1)((libpcap_t *) g_malloc0_n ((1), sizeof (libpcap_t))); |
359 | wth->priv = (void *)libpcap; |
360 | /* |
361 | * Fill in the information we already know or can determine |
362 | * at this point, so the private data is usable by the code |
363 | * that tries reading packets as a heuristic to guess the |
364 | * variant. |
365 | */ |
366 | libpcap->byte_swapped = byte_swapped; |
367 | /* In file format version 2.3, the order of the "incl_len" and |
368 | "orig_len" fields in the per-packet header was reversed, |
369 | in order to match the BPF header layout. |
370 | |
371 | Therefore, in files with versions prior to that, we must swap |
372 | those two fields. |
373 | |
374 | Unfortunately, some files were, according to a comment in the |
375 | "libpcap" source, written with version 2.3 in their headers |
376 | but without the interchanged fields, so if "incl_len" is |
377 | greater than "orig_len" - which would make no sense - we |
378 | assume that we need to swap them in version 2.3 files |
379 | as well. |
380 | |
381 | In addition, DG/UX's tcpdump uses version 543.0, and writes |
382 | the two fields in the pre-2.3 order. |
383 | |
384 | Furthermore, files that don't have a magic number of 2.4 |
385 | were not used by the variant forms of pcap that need |
386 | heuristic tests to detect. */ |
387 | switch (hdr.version_major) { |
388 | |
389 | case 2: |
390 | if (hdr.version_minor < 3) { |
391 | libpcap->lengths_swapped = SWAPPED; |
392 | variant = PCAP; |
393 | } else if (hdr.version_minor == 3) { |
394 | libpcap->lengths_swapped = MAYBE_SWAPPED; |
395 | variant = PCAP; |
396 | } else |
397 | libpcap->lengths_swapped = NOT_SWAPPED; |
398 | break; |
399 | |
400 | case 543: |
401 | libpcap->lengths_swapped = SWAPPED; |
402 | variant = PCAP; |
403 | break; |
404 | |
405 | default: |
406 | libpcap->lengths_swapped = NOT_SWAPPED; |
407 | break; |
408 | } |
409 | libpcap->version_major = hdr.version_major; |
410 | libpcap->version_minor = hdr.version_minor; |
411 | /* |
412 | * Check whether this is an AIX pcap before we convert the |
413 | * link-layer type in the header file to an encapsulation, |
414 | * because AIX pcaps use RFC 1573 ifType values in the header. |
415 | * |
416 | * AIX pcap files use the standard magic number, and have a |
417 | * major and minor version of 2. |
418 | * |
419 | * Unfortunately, that's also true of older versions of libpcap, |
420 | * so we need to do some heuristics to try to identify AIX pcap |
421 | * files. |
422 | */ |
423 | if (magic == PCAP_MAGIC0xa1b2c3d4 && hdr.version_major == 2 && |
424 | hdr.version_minor == 2) { |
425 | /* |
426 | * The AIX libpcap uses RFC 1573 ifType values rather |
427 | * than LINKTYPE_/DLT_ values in the header; the ifType |
428 | * values for LAN devices are: |
429 | * |
430 | * Ethernet 6 |
431 | * Token Ring 9 |
432 | * FDDI 15 |
433 | * |
434 | * which correspond to LINKTYPE_IEEE802_5/DLT_IEEE802 (used |
435 | * for Token Ring), LINKTYPE_PPP/DLT_PPP, and |
436 | * LINKTYPE_SLIP_BSDOS/DLT_SLIP_BSDOS, respectively, and |
437 | * the ifType value for a loopback interface is 24, which |
438 | * currently isn't used by any version of libpcap I know |
439 | * about (and, as tcpdump.org are assigning LINKTYPE_/DLT_ |
440 | * values above 100, and NetBSD started assigning values |
441 | * starting at 50, and the values chosen by other libpcaps |
442 | * appear to stop at 19, it's probably not going to be used |
443 | * by any libpcap in the future). |
444 | * |
445 | * So we shall assume that if the network type is 6, 9, 15, |
446 | * or 24 it's AIX libpcap. |
447 | * |
448 | * We also assume those older versions of libpcap didn't use |
449 | * LINKTYPE_IEEE802_5/DLT_IEEE802 for Token Ring, and didn't |
450 | * use LINKTYPE_SLIP_BSDOS/DLT_SLIP_BSDOS as that came later. |
451 | * It may have used LINKTYPE_PPP/DLT_PPP, however, in which |
452 | * case we're out of luck; we assume it's Token Ring in AIX |
453 | * libpcap rather than PPP in standard libpcap, as you're |
454 | * probably more likely to be handing an AIX libpcap token- |
455 | *ring capture than an old (pre-libpcap 0.4) PPP capture to |
456 | * Wireshark. |
457 | * |
458 | * AIX pcap files didn't use the upper 16 bits, so we don't |
459 | * need to ignore them here - they'll be 0. |
460 | */ |
461 | switch (hdr.network) { |
462 | |
463 | case 6: |
464 | hdr.network = 1; /* LINKTYPE_EN10MB, Ethernet */ |
465 | variant = PCAP_AIX; |
466 | break; |
467 | |
468 | case 9: |
469 | hdr.network = 6; /* LINKTYPE_IEEE802_5, Token Ring */ |
470 | variant = PCAP_AIX; |
471 | break; |
472 | |
473 | case 15: |
474 | hdr.network = 10; /* LINKTYPE_FDDI, FDDI */ |
475 | variant = PCAP_AIX; |
476 | break; |
477 | |
478 | case 24: |
479 | hdr.network = 0; /* LINKTYPE_NULL, loopback */ |
480 | variant = PCAP_AIX; |
481 | break; |
482 | } |
483 | } |
484 | |
485 | /* |
486 | * Check the main reserved field. |
487 | */ |
488 | if (LT_RESERVED1(hdr.network)((hdr.network) & 0x03FF0000) != 0) { |
489 | *err = WTAP_ERR_UNSUPPORTED-4; |
490 | *err_info = ws_strdup_printf("pcap: network type reserved field not zero (0x%08x)",wmem_strdup_printf(((void*)0), "pcap: network type reserved field not zero (0x%08x)" , ((hdr.network) & 0x03FF0000)) |
491 | LT_RESERVED1(hdr.network))wmem_strdup_printf(((void*)0), "pcap: network type reserved field not zero (0x%08x)" , ((hdr.network) & 0x03FF0000)); |
492 | return WTAP_OPEN_ERROR; |
493 | } |
494 | |
495 | /* |
496 | * Map the link-layer type from the "network" field in |
497 | * the header to a Wiretap encapsulation. |
498 | */ |
499 | wth->file_encap = wtap_pcap_encap_to_wtap_encap(LT_LINKTYPE(hdr.network)((hdr.network) & 0x0000FFFF)); |
500 | if (wth->file_encap == WTAP_ENCAP_UNKNOWN0) { |
501 | *err = WTAP_ERR_UNSUPPORTED-4; |
502 | *err_info = ws_strdup_printf("pcap: network type %u unknown or unsupported",wmem_strdup_printf(((void*)0), "pcap: network type %u unknown or unsupported" , hdr.network) |
503 | hdr.network)wmem_strdup_printf(((void*)0), "pcap: network type %u unknown or unsupported" , hdr.network); |
504 | return WTAP_OPEN_ERROR; |
505 | } |
506 | |
507 | /* |
508 | * Extract the FCS information, if present. |
509 | */ |
510 | libpcap->fcs_len = -1; |
511 | if (LT_FCS_LENGTH_PRESENT(hdr.network)((hdr.network) & 0x04000000)) { |
512 | /* |
513 | * We have an FCS length, in units of 16 bits. |
514 | * Convert it to bits. |
515 | */ |
516 | libpcap->fcs_len = LT_FCS_LENGTH(hdr.network)(((hdr.network) & 0xF0000000) >> 28) * 16; |
517 | } |
518 | |
519 | libpcap->encap_priv = NULL((void*)0); |
520 | |
521 | /* |
522 | * If this file has the standard magic number, it could be |
523 | * one of a number of variants, including regular pcap, the |
524 | * AIX variant, the ss990417 variant, and a Nokia variant. |
525 | * The ss990417 variant is used in, for example, Red Hat 6.1, |
526 | * so some versions of AIX, RH 6.1, and some Nokia devices |
527 | * write files that can't be read by any software that expects |
528 | * standard libpcap packet record headers if the magic number |
529 | * is the standard magic number (e.g., any program such as |
530 | * tcpdump that uses libpcap, when using the standard libpcap, |
531 | * and Wireshark if we don't do the heuristics below). |
532 | * |
533 | * If this file has the patched magic number, used by the |
534 | * ss990915 and ss991029 variants, then it could be either |
535 | * of those. The ss991029 variant uses the same packet |
536 | * record header as the ss990417 variant, but the ss990915 |
537 | * variant uses a packet record header with some additional |
538 | * fields and it is used in, for example, SuSE 6.3, so SuSE |
539 | * 6.3 writes files that can't be read by any software that |
540 | * expects ss990417 packet record headers if the magic number |
541 | * is the modified magic number. |
542 | * |
543 | * So, for the standard and modified magic number: |
544 | * |
545 | * For the standard magic number, we first do some heuristic |
546 | * checks of data from the file header to see if it looks like |
547 | * an AIX libpcap file. If so, we choose PCAP_AIX as the variant, |
548 | * and we don't have to do any more guessing. |
549 | * |
550 | * Otherwise, we determine the variant by, for each variant, |
551 | * trying to read the first few packets as if that file were |
552 | * in that variant's format, and seeing whether the packet |
553 | * record headers make sense. |
554 | * |
555 | * But don't do the latter if the input is a pipe; that would mean |
556 | * the open won't complete until two packets have been written to |
557 | * the pipe, unless the pipe is closed after one packet has been |
558 | * written, so a program reading from the file won't see the |
559 | * first packet until the second packet has been written. |
560 | */ |
561 | switch (magic) { |
562 | |
563 | case PCAP_MAGIC0xa1b2c3d4: |
564 | /* |
565 | * Original libpcap magic. |
566 | * |
567 | * If we still don't know the variant, look at the first |
568 | * few packets to see what type of per-packet header they |
569 | * have. |
570 | * |
571 | * Default to PCAP, as that's probably what this is; |
572 | * libpcap_try_variants() will just give up if we're |
573 | * reading from a pipe. |
574 | */ |
575 | if (variant == PCAP_UNKNOWN) { |
576 | if (wth->ispipe) { |
577 | /* |
578 | * We can't do the heuristics. |
579 | * Just go with standard libpcap. |
580 | */ |
581 | libpcap->variant = PCAP; |
582 | } else { |
583 | /* |
584 | * Try the variants that use the standard |
585 | * pcap magic number. |
586 | */ |
587 | if (!libpcap_try_variants(wth, variants_standard, |
588 | N_VARIANTS_STANDARD(sizeof (variants_standard) / sizeof ((variants_standard)[0]) ), err, err_info)) { |
589 | /* |
590 | * File read error. |
591 | */ |
592 | return WTAP_OPEN_ERROR; |
593 | } |
594 | } |
595 | } else { |
596 | /* |
597 | * Use the variant we found. |
598 | */ |
599 | libpcap->variant = variant; |
600 | } |
601 | break; |
602 | |
603 | case PCAP_MODIFIED_MAGIC0xa1b2cd34: |
604 | /* |
605 | * Modified libpcap magic, from Alexey's later two |
606 | * patches. |
607 | * |
608 | * This might be one of two different flavors of |
609 | * pcap file, with different modified per-packet |
610 | * headers. |
611 | * |
612 | * If we're reading from a pipe, we don't have an |
613 | * obvious choice to use as a default. |
614 | */ |
615 | if (wth->ispipe) { |
616 | /* |
617 | * We can't do the heuristics. |
618 | * There's no obvious choice to use as a |
619 | * default, so just report an error. |
620 | */ |
621 | *err = WTAP_ERR_UNSUPPORTED-4; |
622 | *err_info = g_strdup("pcap: that type of pcap file can't be read from a pipe")g_strdup_inline ("pcap: that type of pcap file can't be read from a pipe" ); |
623 | return WTAP_OPEN_ERROR; |
624 | } else { |
625 | /* |
626 | * Try the variants that use the modified |
627 | * pcap magic number. |
628 | */ |
629 | if (!libpcap_try_variants(wth, variants_modified, |
630 | N_VARIANTS_MODIFIED(sizeof (variants_modified) / sizeof ((variants_modified)[0]) ), err, err_info)) { |
631 | /* |
632 | * File read error. |
633 | */ |
634 | return WTAP_OPEN_ERROR; |
635 | } |
636 | } |
637 | break; |
638 | |
639 | default: |
640 | /* |
641 | * None of these require heuristics to guess the |
642 | * variant; just use the variant we found. |
643 | */ |
644 | libpcap->variant = variant; |
645 | break; |
646 | } |
647 | |
648 | /* |
649 | * Set the file type and subtype, and handle some variants |
650 | * specially. |
651 | */ |
652 | switch (libpcap->variant) { |
653 | |
654 | case PCAP: |
655 | wth->file_type_subtype = pcap_file_type_subtype; |
656 | wth->file_tsprec = WTAP_TSPREC_USEC6; |
657 | break; |
658 | |
659 | case PCAP_NSEC: |
660 | wth->file_type_subtype = pcap_nsec_file_type_subtype; |
661 | wth->file_tsprec = WTAP_TSPREC_NSEC9; |
662 | break; |
663 | |
664 | case PCAP_SS990417: |
665 | wth->file_type_subtype = pcap_ss990417_file_type_subtype; |
666 | wth->file_tsprec = WTAP_TSPREC_USEC6; |
667 | break; |
668 | |
669 | case PCAP_SS990915: |
670 | wth->file_type_subtype = pcap_ss990915_file_type_subtype; |
671 | wth->file_tsprec = WTAP_TSPREC_USEC6; |
672 | break; |
673 | |
674 | case PCAP_SS991029: |
675 | wth->file_type_subtype = pcap_ss991029_file_type_subtype; |
676 | wth->file_tsprec = WTAP_TSPREC_USEC6; |
677 | break; |
678 | |
679 | case PCAP_AIX: |
680 | wth->file_type_subtype = pcap_aix_file_type_subtype; |
681 | wth->file_tsprec = WTAP_TSPREC_NSEC9; |
682 | break; |
683 | |
684 | case PCAP_NOKIA: |
685 | wth->file_type_subtype = pcap_nokia_file_type_subtype; |
686 | wth->file_tsprec = WTAP_TSPREC_USEC6; |
687 | /* |
688 | * We treat a DLT_ value of 13 specially - it appears |
689 | * that in Nokia libpcap format, it's some form of ATM |
690 | * with what I suspect is a pseudo-header (even though |
691 | * Nokia's IPSO is based on FreeBSD, which #defines |
692 | * DLT_SLIP_BSDOS as 13). |
693 | * |
694 | * Treat 13 as WTAP_ENCAP_ATM_PDUS, rather than as what |
695 | * we normally treat it. |
696 | */ |
697 | switch (hdr.network) { |
698 | |
699 | case 13: |
700 | wth->file_encap = WTAP_ENCAP_ATM_PDUS13; |
701 | break; |
702 | } |
703 | break; |
704 | |
705 | default: |
706 | ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "wiretap/libpcap.c", 706 , __func__, "assertion \"not reached\" failed"); |
707 | } |
708 | |
709 | if (wth->file_encap == WTAP_ENCAP_ERF98) { |
710 | /* Reset the ERF interface lookup table */ |
711 | libpcap->encap_priv = erf_priv_create(); |
712 | } else { |
713 | /* |
714 | * Add an IDB; we don't know how many interfaces were |
715 | * involved, so we just say one interface, about which |
716 | * we only know the link-layer type, snapshot length, |
717 | * and time stamp resolution. |
718 | */ |
719 | wtap_add_generated_idb(wth); |
720 | } |
721 | |
722 | return WTAP_OPEN_MINE; |
723 | } |
724 | |
725 | static bool_Bool libpcap_try_variants(wtap *wth, const pcap_variant_t *variants, |
726 | size_t n_variants, int *err, char **err_info) |
727 | { |
728 | libpcap_t *libpcap = (libpcap_t *)wth->priv; |
729 | #define MAX_FIGURES_OF_MERIT((((sizeof (variants_modified) / sizeof ((variants_modified)[ 0]))) > ((sizeof (variants_standard) / sizeof ((variants_standard )[0])))) ? ((sizeof (variants_modified) / sizeof ((variants_modified )[0]))) : ((sizeof (variants_standard) / sizeof ((variants_standard )[0])))) \ |
730 | MAX(N_VARIANTS_MODIFIED, N_VARIANTS_STANDARD)((((sizeof (variants_modified) / sizeof ((variants_modified)[ 0]))) > ((sizeof (variants_standard) / sizeof ((variants_standard )[0])))) ? ((sizeof (variants_modified) / sizeof ((variants_modified )[0]))) : ((sizeof (variants_standard) / sizeof ((variants_standard )[0])))) |
731 | int figures_of_merit[MAX_FIGURES_OF_MERIT((((sizeof (variants_modified) / sizeof ((variants_modified)[ 0]))) > ((sizeof (variants_standard) / sizeof ((variants_standard )[0])))) ? ((sizeof (variants_modified) / sizeof ((variants_modified )[0]))) : ((sizeof (variants_standard) / sizeof ((variants_standard )[0]))))]; |
732 | int best_variant; |
733 | int64_t first_packet_offset; |
734 | |
735 | first_packet_offset = file_tell(wth->fh); |
736 | for (size_t i = 0; i < n_variants; i++) { |
737 | figures_of_merit[i] = libpcap_try_variant(wth, variants[i], |
738 | err, err_info); |
739 | if (figures_of_merit[i] == -1) { |
740 | /* |
741 | * Well, we couldn't even read it. Give up. |
742 | */ |
743 | return false0; |
744 | } |
745 | if (figures_of_merit[i] == 0) { |
746 | /* |
747 | * This format doesn't have any issues. |
748 | * Put the seek pointer back, and finish, |
749 | * using that format as the subtype. |
750 | */ |
751 | if (file_seek(wth->fh, first_packet_offset, SEEK_SET0, |
752 | err) == -1) { |
753 | return false0; |
754 | } |
755 | libpcap->variant = variants[i]; |
756 | return true1; |
757 | } |
758 | |
759 | /* |
760 | * OK, we've recorded the figure of merit for this |
761 | * one; go back to the first packet and try the |
762 | * next one. |
763 | */ |
764 | if (file_seek(wth->fh, first_packet_offset, SEEK_SET0, |
765 | err) == -1) { |
766 | return false0; |
767 | } |
768 | } |
769 | |
770 | /* |
771 | * OK, none are perfect; let's see which one is least bad. |
772 | */ |
773 | best_variant = INT_MAX2147483647; |
774 | for (size_t i = 0; i < n_variants; i++) { |
775 | /* |
776 | * Is this subtype better than the last one we saw? |
777 | */ |
778 | if (figures_of_merit[i] < best_variant) { |
779 | /* |
780 | * Yes. Choose it until we find a better one. |
781 | */ |
782 | libpcap->variant = variants[i]; |
783 | best_variant = figures_of_merit[i]; |
784 | } |
785 | } |
786 | return true1; |
787 | } |
788 | |
789 | /* |
790 | * Maximum number of records to try to read. Must be >= 2. |
791 | */ |
792 | #define MAX_RECORDS_TO_TRY3 3 |
793 | |
794 | /* Try to read the first MAX_RECORDS_TO_TRY records of the capture file. */ |
795 | static int libpcap_try_variant(wtap *wth, pcap_variant_t variant, |
796 | int *err, char **err_info) |
797 | { |
798 | int figure_of_merit; |
799 | |
800 | figure_of_merit = 0; |
801 | |
802 | /* |
803 | * Attempt to read the MAX_RECORDS_TO_TRY records. |
804 | */ |
805 | for (unsigned int i = 0; i < MAX_RECORDS_TO_TRY3; i++) { |
806 | /* |
807 | * Attempt to read this record. |
808 | */ |
809 | try_record_ret_t try_record_ret; |
810 | |
811 | try_record_ret = libpcap_try_record(wth, variant, |
812 | &figure_of_merit, err, err_info); |
813 | |
814 | if (try_record_ret == TRY_REC_ERROR) { |
815 | /* |
816 | * Error; return the error indication. |
817 | */ |
818 | return -1; |
819 | } |
820 | if (try_record_ret == TRY_REC_EOF) { |
821 | /* |
822 | * Nothing more to read from this file. |
823 | */ |
824 | break; |
825 | } |
826 | } |
827 | |
828 | return figure_of_merit; |
829 | } |
830 | |
831 | /* Read the header of the next packet and, if that succeeds, read the |
832 | data of the next packet. |
833 | |
834 | Return -1 on an I/O error, 0 on success, or a positive number if the |
835 | header looks corrupt. The higher the positive number, the more things |
836 | are wrong with the header; this is used by the heuristics that try to |
837 | guess what type of file it is, with the type with the fewest problems |
838 | being chosen. */ |
839 | static try_record_ret_t libpcap_try_record(wtap *wth, pcap_variant_t variant, |
840 | int *figure_of_meritp, int *err, char **err_info) |
841 | { |
842 | libpcap_t *libpcap = (libpcap_t *)wth->priv; |
843 | struct pcaprec_hdr hdr; |
844 | /* Fields from PCAP_SS* modified headers */ |
845 | uint32_t ifindex; |
846 | uint16_t protocol; |
847 | uint8_t pkt_type; |
848 | uint32_t nokia_stuff; |
849 | bool_Bool incl_len_ok = true1; |
850 | |
851 | /* |
852 | * Read the header, one field at a time. |
853 | * First, do the fields that all pcap formats have - the |
854 | * time stamp, the captured length, and the original |
855 | * length. |
856 | */ |
857 | if (!wtap_read_bytes_or_eof(wth->fh, &hdr.ts_sec, 4, err, err_info)) { |
858 | if (*err == 0) { |
859 | /* |
860 | * EOF - assume the file is in this format. |
861 | * This means it doesn't have all the |
862 | * records we're trying to read. |
863 | */ |
864 | return TRY_REC_EOF; |
865 | } |
866 | if (*err == WTAP_ERR_SHORT_READ-12) { |
867 | /* |
868 | * Short read; this might be a corrupt |
869 | * file in this format or might not be |
870 | * in this format. Return a figure of |
871 | * merit of 1 more than what we've |
872 | * accumulated so far, to note the |
873 | * short read in addition to any other |
874 | * issues we've found. |
875 | */ |
876 | *figure_of_meritp += 1; |
877 | return TRY_REC_EOF; |
878 | } |
879 | /* Hard error. */ |
880 | return TRY_REC_ERROR; |
881 | } |
882 | |
883 | if (libpcap->byte_swapped) { |
884 | /* Byte-swap the field. */ |
885 | hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr.ts_sec)(((guint32) ( (((guint32) (hdr.ts_sec) & (guint32) 0x000000ffU ) << 24) | (((guint32) (hdr.ts_sec) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (hdr.ts_sec) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (hdr.ts_sec) & (guint32) 0xff000000U ) >> 24)))); |
886 | } |
887 | |
888 | if (!wtap_read_bytes(wth->fh, &hdr.ts_usec, 4, err, err_info)) { |
889 | if (*err == WTAP_ERR_SHORT_READ-12) { |
890 | /* |
891 | * Short read; this might be a corrupt |
892 | * file in this format or might not be |
893 | * in this format. Return a figure of |
894 | * merit of 1 more than what we've |
895 | * accumulated so far, to note the |
896 | * short read in addition to any other |
897 | * issues we've found. |
898 | */ |
899 | *figure_of_meritp += 1; |
900 | return TRY_REC_EOF; |
901 | } |
902 | /* Hard error. */ |
903 | return TRY_REC_ERROR; |
904 | } |
905 | |
906 | if (libpcap->byte_swapped) { |
907 | /* Byte-swap the field. */ |
908 | hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr.ts_usec)(((guint32) ( (((guint32) (hdr.ts_usec) & (guint32) 0x000000ffU ) << 24) | (((guint32) (hdr.ts_usec) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (hdr.ts_usec) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (hdr.ts_usec) & (guint32) 0xff000000U ) >> 24)))); |
909 | } |
910 | |
911 | /* |
912 | * The only file types for which we have to do variant |
913 | * determination by looking at packets have microsecond |
914 | * resolution; treat fractions-of-a-second values >= 1 000 000 |
915 | * as an indication that the header format might not be |
916 | * what we think it is. |
917 | */ |
918 | if (hdr.ts_usec >= 1000000) |
919 | *figure_of_meritp += 1; |
920 | |
921 | if (!wtap_read_bytes(wth->fh, &hdr.incl_len, 4, err, err_info)) { |
922 | if (*err == WTAP_ERR_SHORT_READ-12) { |
923 | /* |
924 | * Short read; this might be a corrupt |
925 | * file in this format or might not be |
926 | * in this format. Return a figure of |
927 | * merit of 1 more than what we've |
928 | * accumulated so far, to note the |
929 | * short read in addition to any other |
930 | * issues we've found. |
931 | */ |
932 | *figure_of_meritp += 1; |
933 | return TRY_REC_EOF; |
934 | } |
935 | /* Hard error. */ |
936 | return TRY_REC_ERROR; |
937 | } |
938 | |
939 | if (libpcap->byte_swapped) { |
940 | /* Byte-swap the field. */ |
941 | hdr.incl_len = GUINT32_SWAP_LE_BE(hdr.incl_len)(((guint32) ( (((guint32) (hdr.incl_len) & (guint32) 0x000000ffU ) << 24) | (((guint32) (hdr.incl_len) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (hdr.incl_len) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (hdr.incl_len) & (guint32) 0xff000000U ) >> 24)))); |
942 | } |
943 | |
944 | if (hdr.incl_len > wtap_max_snaplen_for_encap(wth->file_encap)) { |
945 | /* |
946 | * Probably either a corrupt capture file or a file |
947 | * of a type different from the one we're trying. |
948 | */ |
949 | incl_len_ok = false0; |
950 | *figure_of_meritp += 1; |
951 | } |
952 | |
953 | if (hdr.incl_len > wth->snapshot_length) { |
954 | /* |
955 | * This is not a fatal error, and packets that have one |
956 | * such packet probably have thousands. For discussion, |
957 | * see |
958 | * https://lists.wireshark.org/archives/wireshark-dev/201307/msg00076.html |
959 | * and related messages. |
960 | * |
961 | * The packet contents will be copied to a Buffer, which |
962 | * expands as necessary to hold the contents; we don't have |
963 | * to worry about fixed-length buffers allocated based on |
964 | * the original snapshot length. |
965 | * |
966 | * We just treat this as an indication that we might be |
967 | * trying the wrong file type here. |
968 | */ |
969 | *figure_of_meritp += 1; |
970 | } |
971 | |
972 | if (!wtap_read_bytes(wth->fh, &hdr.orig_len, 4, err, err_info)) { |
973 | if (*err == WTAP_ERR_SHORT_READ-12) { |
974 | /* |
975 | * Short read; this might be a corrupt |
976 | * file in this format or might not be |
977 | * in this format. Return a figure of |
978 | * merit of 1 more than what we've |
979 | * accumulated so far, to note the |
980 | * short read in addition to any other |
981 | * issues we've found. |
982 | */ |
983 | *figure_of_meritp += 1; |
984 | return TRY_REC_EOF; |
985 | } |
986 | /* Hard error. */ |
987 | return TRY_REC_ERROR; |
988 | } |
989 | |
990 | if (libpcap->byte_swapped) { |
991 | /* Byte-swap the field. */ |
992 | hdr.orig_len = GUINT32_SWAP_LE_BE(hdr.orig_len)(((guint32) ( (((guint32) (hdr.orig_len) & (guint32) 0x000000ffU ) << 24) | (((guint32) (hdr.orig_len) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (hdr.orig_len) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (hdr.orig_len) & (guint32) 0xff000000U ) >> 24)))); |
993 | } |
994 | |
995 | if (hdr.orig_len > 128*1024*1024) { |
996 | /* |
997 | * In theory I guess the on-the-wire packet size can be |
998 | * arbitrarily large, and it can certainly be larger than the |
999 | * maximum snapshot length which bounds the snapshot size, |
1000 | * but any file claiming 128MB in a single packet is *probably* |
1001 | * corrupt, and treating them as such makes the heuristics |
1002 | * much more reliable. See, for example, |
1003 | * |
1004 | * https://gitlab.com/wireshark/wireshark/-/issues/9634 |
1005 | * |
1006 | * (128MB is an arbitrary size at this point, chosen to be |
1007 | * large enough for the largest D-Bus packet). |
1008 | */ |
1009 | *figure_of_meritp += 1; |
1010 | } |
1011 | |
1012 | if (hdr.incl_len > hdr.orig_len) { |
1013 | /* |
1014 | * Another hint that this might be the wrong file type. |
1015 | */ |
1016 | *figure_of_meritp += 1; |
1017 | } |
1018 | |
1019 | /* |
1020 | * Now check any additional fields that the variant we're |
1021 | * trying has. |
1022 | */ |
1023 | switch (variant) { |
1024 | |
1025 | case PCAP: |
1026 | case PCAP_AIX: |
1027 | case PCAP_NSEC: |
1028 | /* No more fields. */ |
1029 | break; |
1030 | |
1031 | case PCAP_SS990417: |
1032 | case PCAP_SS991029: |
1033 | case PCAP_SS990915: |
1034 | /* struct pcaprec_modified_hdr */ |
1035 | |
1036 | /* 32-bit interface index. */ |
1037 | if (!wtap_read_bytes(wth->fh, &ifindex, 4, err, err_info)) { |
1038 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1039 | /* |
1040 | * Short read; this might be a corrupt |
1041 | * file in this format or might not be |
1042 | * in this format. Return a figure of |
1043 | * merit of 1 more than what we've |
1044 | * accumulated so far, to note the |
1045 | * short read in addition to any other |
1046 | * issues we've found. |
1047 | */ |
1048 | *figure_of_meritp += 1; |
1049 | return TRY_REC_EOF; |
1050 | } |
1051 | /* Hard error. */ |
1052 | return TRY_REC_ERROR; |
1053 | } |
1054 | |
1055 | if (libpcap->byte_swapped) { |
1056 | /* Byte-swap the field. */ |
1057 | ifindex = GUINT32_SWAP_LE_BE(ifindex)(((guint32) ( (((guint32) (ifindex) & (guint32) 0x000000ffU ) << 24) | (((guint32) (ifindex) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (ifindex) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (ifindex) & (guint32) 0xff000000U ) >> 24)))); |
1058 | } |
1059 | |
1060 | /* |
1061 | * Make sure it's not too large; those files date |
1062 | * from an era when a Linux box probably didn't |
1063 | * have more than 10000 interfaces, so check for |
1064 | * a value >= 10000. |
1065 | */ |
1066 | if (ifindex > 10000) |
1067 | *figure_of_meritp += 1; |
1068 | |
1069 | /* |
1070 | * 16-bit "Ethernet packet type", which is either an |
1071 | * Ethertype or one of the internal Linux ETH_P_ |
1072 | * values from linux/if_ether.h. |
1073 | */ |
1074 | if (!wtap_read_bytes(wth->fh, &protocol, 2, err, err_info)) { |
1075 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1076 | /* |
1077 | * Short read; this might be a corrupt |
1078 | * file in this format or might not be |
1079 | * in this format. Return a figure of |
1080 | * merit of 1 more than what we've |
1081 | * accumulated so far, to note the |
1082 | * short read in addition to any other |
1083 | * issues we've found. |
1084 | */ |
1085 | *figure_of_meritp += 1; |
1086 | return TRY_REC_EOF; |
1087 | } |
1088 | /* Hard error. */ |
1089 | return TRY_REC_ERROR; |
1090 | } |
1091 | |
1092 | if (libpcap->byte_swapped) { |
1093 | /* Byte-swap the field. */ |
1094 | protocol = GUINT16_SWAP_LE_BE(protocol)(((guint16) ( (guint16) ((guint16) (protocol) >> 8) | ( guint16) ((guint16) (protocol) << 8)))); |
1095 | } |
1096 | |
1097 | /* |
1098 | * Valid values are: |
1099 | * |
1100 | * anything >= 0x0600 (normal Ethertype range) |
1101 | * 0x0060 (ETH_P_LOOP) |
1102 | * 0x0200 (ETH_P_ECHO) |
1103 | * 0x0400 (ETH_P_PUP) |
1104 | * 0x0000 (see in some such captures) |
1105 | * 0x0001 to 0x0017 ("Non DIX types") |
1106 | */ |
1107 | if (!(protocol >= 0x0600 || |
1108 | protocol == 0x0060 || |
1109 | protocol == 0x0200 || |
1110 | protocol == 0x0400 || |
1111 | protocol == 0x0000 || |
1112 | (protocol >= 0x0001 && protocol <= 0x0017))) |
1113 | *figure_of_meritp += 1; |
1114 | |
1115 | /* |
1116 | * 8-bit packet type - one of the Linux PACKET_ |
1117 | * types from linux/if_packet.h. The ones that |
1118 | * would appear in files from the era in which |
1119 | * these formats existed (the patches that |
1120 | * introduced them from are from 1999) are in |
1121 | * the range 0 through 4; anything else is treated |
1122 | * as a sign that this is unlikely to be in that |
1123 | * format. |
1124 | */ |
1125 | if (!wtap_read_bytes(wth->fh, &pkt_type, 1, err, err_info)) { |
1126 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1127 | /* |
1128 | * Short read; this might be a corrupt |
1129 | * file in this format or might not be |
1130 | * in this format. Return a figure of |
1131 | * merit of 1 more than what we've |
1132 | * accumulated so far, to note the |
1133 | * short read in addition to any other |
1134 | * issues we've found. |
1135 | */ |
1136 | *figure_of_meritp += 1; |
1137 | return TRY_REC_EOF; |
1138 | } |
1139 | /* Hard error. */ |
1140 | return TRY_REC_ERROR; |
1141 | } |
1142 | |
1143 | if (pkt_type > 4) |
1144 | *figure_of_meritp += 1; |
1145 | |
1146 | if (variant == PCAP_SS990915) { |
1147 | /* |
1148 | * 2 8-bit values that are filled in only |
1149 | * if libpcap is built with SMP debugging, |
1150 | * fllowed by 3 bytes of 8-bit padding, |
1151 | * not guaranteed to be zero. |
1152 | * |
1153 | * Just skip them. |
1154 | */ |
1155 | if (!wtap_read_bytes(wth->fh, NULL((void*)0), 5, err, err_info)) { |
1156 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1157 | /* |
1158 | * Short read; this might be a corrupt |
1159 | * file in this format or might not be |
1160 | * in this format. Return a figure of |
1161 | * merit of 1 more than what we've |
1162 | * accumulated so far, to note the |
1163 | * short read in addition to any other |
1164 | * issues we've found. |
1165 | */ |
1166 | *figure_of_meritp += 1; |
1167 | return TRY_REC_EOF; |
1168 | } |
1169 | /* Hard error. */ |
1170 | return TRY_REC_ERROR; |
1171 | } |
1172 | } else { |
1173 | /* |
1174 | * 8-bit structure padding, not guaranteed to be |
1175 | * zero. |
1176 | */ |
1177 | if (!wtap_read_bytes(wth->fh, NULL((void*)0), 1, err, err_info)) { |
1178 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1179 | /* |
1180 | * Short read; this might be a corrupt |
1181 | * file in this format or might not be |
1182 | * in this format. Return a figure of |
1183 | * merit of 1 more than what we've |
1184 | * accumulated so far, to note the |
1185 | * short read in addition to any other |
1186 | * issues we've found. |
1187 | */ |
1188 | *figure_of_meritp += 1; |
1189 | return TRY_REC_EOF; |
1190 | } |
1191 | /* Hard error. */ |
1192 | return TRY_REC_ERROR; |
1193 | } |
1194 | } |
1195 | break; |
1196 | |
1197 | case PCAP_NOKIA: |
1198 | /* |
1199 | * pcaprec_nokia_hdr. |
1200 | * |
1201 | * 4 bytes of unknown stuff. |
1202 | */ |
1203 | if (!wtap_read_bytes(wth->fh, &nokia_stuff, 4, err, err_info)) { |
1204 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1205 | /* |
1206 | * Short read; this might be a corrupt |
1207 | * file in this format or might not be |
1208 | * in this format. Return a figure of |
1209 | * merit of 1 more than what we've |
1210 | * accumulated so far, to note the |
1211 | * short read in addition to any other |
1212 | * issues we've found. |
1213 | */ |
1214 | *figure_of_meritp += 1; |
1215 | return TRY_REC_EOF; |
1216 | } |
1217 | /* Hard error. */ |
1218 | return TRY_REC_ERROR; |
1219 | } |
1220 | |
1221 | /* |
1222 | * Values we've seen in this field are of the form |
1223 | * |
1224 | * 0xXfbfYZ0W |
1225 | * |
1226 | * where X is either 9/1001 or b/1011, Y is either b/1011 |
1227 | * or d/1101, Z is either 6/0110 or 9/1001, and W is either |
1228 | * 1/0001 or 2/0010. |
1229 | * |
1230 | * Check for those values. |
1231 | */ |
1232 | #define NOKIA_STUFF_CONSTANT(ns)((ns) & 0x0FFF00F0) ((ns) & 0x0FFF00F0) |
1233 | #define NOKIA_STUFF_PART_1(ns)((ns) & 0xF0000000) ((ns) & 0xF0000000) |
1234 | #define NOKIA_STUFF_PART_2(ns)((ns) & 0x0000F000) ((ns) & 0x0000F000) |
1235 | #define NOKIA_STUFF_PART_3(ns)((ns) & 0x00000F00) ((ns) & 0x00000F00) |
1236 | #define NOKIA_STUFF_PART_4(ns)((ns) & 0x0000000F) ((ns) & 0x0000000F) |
1237 | if (!(NOKIA_STUFF_CONSTANT(nokia_stuff)((nokia_stuff) & 0x0FFF00F0) == 0x0fbf0000 && |
1238 | (NOKIA_STUFF_PART_1(nokia_stuff)((nokia_stuff) & 0xF0000000) == 0x90000000 || |
1239 | NOKIA_STUFF_PART_1(nokia_stuff)((nokia_stuff) & 0xF0000000) == 0xb0000000) && |
1240 | (NOKIA_STUFF_PART_2(nokia_stuff)((nokia_stuff) & 0x0000F000) == 0x0000b000 || |
1241 | NOKIA_STUFF_PART_2(nokia_stuff)((nokia_stuff) & 0x0000F000) == 0x0000d000) && |
1242 | (NOKIA_STUFF_PART_3(nokia_stuff)((nokia_stuff) & 0x00000F00) == 0x00000600 || |
1243 | NOKIA_STUFF_PART_3(nokia_stuff)((nokia_stuff) & 0x00000F00) == 0x00000900) && |
1244 | (NOKIA_STUFF_PART_4(nokia_stuff)((nokia_stuff) & 0x0000000F) == 0x00000001 || |
1245 | NOKIA_STUFF_PART_4(nokia_stuff)((nokia_stuff) & 0x0000000F) == 0x00000002))) |
1246 | *figure_of_meritp += 1; |
1247 | break; |
1248 | |
1249 | default: |
1250 | ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "wiretap/libpcap.c", 1250 , __func__, "assertion \"not reached\" failed"); |
1251 | } |
1252 | |
1253 | if (!incl_len_ok) { |
1254 | /* |
1255 | * Might be the wrong file type; stop trying, and give |
1256 | * this as the figure of merit for this file type. |
1257 | */ |
1258 | return TRY_REC_EOF; |
1259 | } |
1260 | |
1261 | /* |
1262 | * Now skip over the record's data, under the assumption that |
1263 | * the header is sane. |
1264 | */ |
1265 | if (!wtap_read_bytes(wth->fh, NULL((void*)0), hdr.incl_len, err, err_info)) { |
1266 | if (*err == WTAP_ERR_SHORT_READ-12) { |
1267 | /* |
1268 | * Short read; this might be a corrupt |
1269 | * file in this format or might not be |
1270 | * in this format. Return a figure of |
1271 | * merit of 1 more than what we've |
1272 | * accumulated so far, to note the |
1273 | * short read in addition to any other |
1274 | * issues we've found. |
1275 | */ |
1276 | *figure_of_meritp += 1; |
1277 | return TRY_REC_EOF; |
1278 | } |
1279 | /* Hard error. */ |
1280 | return TRY_REC_ERROR; |
1281 | } |
1282 | |
1283 | return TRY_REC_KEEP_READING; |
1284 | } |
1285 | |
1286 | /* Read the next packet */ |
1287 | static bool_Bool libpcap_read(wtap *wth, wtap_rec *rec, |
1288 | int *err, char **err_info, int64_t *data_offset) |
1289 | { |
1290 | *data_offset = file_tell(wth->fh); |
1291 | |
1292 | return libpcap_read_packet(wth, wth->fh, rec, err, err_info); |
1293 | } |
1294 | |
1295 | static bool_Bool |
1296 | libpcap_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec, |
1297 | int *err, char **err_info) |
1298 | { |
1299 | if (file_seek(wth->random_fh, seek_off, SEEK_SET0, err) == -1) |
1300 | return false0; |
1301 | |
1302 | if (!libpcap_read_packet(wth, wth->random_fh, rec, err, err_info)) { |
1303 | if (*err == 0) |
1304 | *err = WTAP_ERR_SHORT_READ-12; |
1305 | return false0; |
1306 | } |
1307 | return true1; |
1308 | } |
1309 | |
1310 | static bool_Bool |
1311 | libpcap_read_packet(wtap *wth, FILE_T fh, wtap_rec *rec, |
1312 | int *err, char **err_info) |
1313 | { |
1314 | struct pcaprec_ss990915_hdr hdr; |
1315 | unsigned packet_size; |
1316 | unsigned orig_size; |
1317 | int phdr_len; |
1318 | libpcap_t *libpcap = (libpcap_t *)wth->priv; |
1319 | bool_Bool is_nokia; |
1320 | |
1321 | if (!libpcap_read_header(wth, fh, err, err_info, &hdr)) |
1322 | return false0; |
1323 | |
1324 | if (hdr.hdr.incl_len > wtap_max_snaplen_for_encap(wth->file_encap)) { |
1325 | /* |
1326 | * Probably a corrupt capture file; return an error, |
1327 | * so that our caller doesn't blow up trying to allocate |
1328 | * space for an immensely-large packet. |
1329 | */ |
1330 | *err = WTAP_ERR_BAD_FILE-13; |
1331 | if (err_info != NULL((void*)0)) { |
1332 | *err_info = ws_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",wmem_strdup_printf(((void*)0), "pcap: File has %u-byte packet, bigger than maximum of %u" , hdr.hdr.incl_len, wtap_max_snaplen_for_encap(wth->file_encap )) |
1333 | hdr.hdr.incl_len,wmem_strdup_printf(((void*)0), "pcap: File has %u-byte packet, bigger than maximum of %u" , hdr.hdr.incl_len, wtap_max_snaplen_for_encap(wth->file_encap )) |
1334 | wtap_max_snaplen_for_encap(wth->file_encap))wmem_strdup_printf(((void*)0), "pcap: File has %u-byte packet, bigger than maximum of %u" , hdr.hdr.incl_len, wtap_max_snaplen_for_encap(wth->file_encap )); |
1335 | } |
1336 | return false0; |
1337 | } |
1338 | |
1339 | packet_size = hdr.hdr.incl_len; |
1340 | orig_size = hdr.hdr.orig_len; |
1341 | |
1342 | /* |
1343 | * AIX appears to put 3 bytes of padding in front of FDDI |
1344 | * frames; strip that crap off. |
1345 | */ |
1346 | if (libpcap->variant == PCAP_AIX && |
1347 | (wth->file_encap == WTAP_ENCAP_FDDI5 || |
1348 | wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED6)) { |
1349 | /* |
1350 | * The packet size is really a record size and includes |
1351 | * the padding. |
1352 | */ |
1353 | if (ckd_sub(&packet_size, packet_size, 3)__builtin_sub_overflow((packet_size), (3), (&packet_size) ) || |
1354 | ckd_sub(&orig_size, orig_size, 3)__builtin_sub_overflow((orig_size), (3), (&orig_size))) { |
1355 | *err = WTAP_ERR_BAD_FILE-13; |
1356 | if (err_info != NULL((void*)0)) { |
1357 | *err_info = ws_strdup("pcap: AIX FDDI padding is absent")wmem_strdup(((void*)0), "pcap: AIX FDDI padding is absent"); |
1358 | } |
1359 | return false0; |
1360 | } |
1361 | |
1362 | /* |
1363 | * Skip the padding. |
1364 | */ |
1365 | if (!wtap_read_bytes(fh, NULL((void*)0), 3, err, err_info)) |
1366 | return false0; |
1367 | } |
1368 | |
1369 | is_nokia = (libpcap->variant == PCAP_NOKIA); |
1370 | phdr_len = pcap_process_pseudo_header(fh, is_nokia, |
1371 | wth->file_encap, packet_size, rec, err, err_info); |
1372 | if (phdr_len < 0) |
1373 | return false0; /* error */ |
1374 | |
1375 | /* |
1376 | * Don't count any pseudo-header as part of the packet. |
1377 | */ |
1378 | orig_size -= phdr_len; |
1379 | packet_size -= phdr_len; |
1380 | |
1381 | wtap_setup_packet_rec(rec, wth->file_encap); |
1382 | rec->block = wtap_block_create(WTAP_BLOCK_PACKET); |
1383 | rec->presence_flags = WTAP_HAS_TS0x00000001|WTAP_HAS_CAP_LEN0x00000002; |
1384 | |
1385 | /* Update the timestamp, if not already done */ |
1386 | if (wth->file_encap != WTAP_ENCAP_ERF98) { |
1387 | rec->ts.secs = hdr.hdr.ts_sec; |
1388 | if (libpcap->variant == PCAP_NSEC || |
1389 | libpcap->variant == PCAP_AIX) |
1390 | rec->ts.nsecs = hdr.hdr.ts_usec; |
1391 | else |
1392 | rec->ts.nsecs = hdr.hdr.ts_usec * 1000; |
1393 | } else { |
1394 | int interface_id; |
1395 | /* Set interface ID for ERF format */ |
1396 | rec->presence_flags |= WTAP_HAS_INTERFACE_ID0x00000004; |
1397 | if ((interface_id = erf_populate_interface_from_header((erf_t*) libpcap->encap_priv, wth, &rec->rec_header.packet_header.pseudo_header, err, err_info)) < 0) |
1398 | return false0; |
1399 | |
1400 | rec->rec_header.packet_header.interface_id = (unsigned) interface_id; |
1401 | } |
1402 | rec->rec_header.packet_header.caplen = packet_size; |
1403 | rec->rec_header.packet_header.len = orig_size; |
1404 | |
1405 | /* |
1406 | * Read the packet data. |
1407 | */ |
1408 | if (!wtap_read_bytes_buffer(fh, &rec->data, packet_size, err, err_info)) |
1409 | return false0; /* failed */ |
1410 | |
1411 | pcap_read_post_process(is_nokia, wth->file_encap, rec, |
1412 | libpcap->byte_swapped, libpcap->fcs_len); |
1413 | return true1; |
1414 | } |
1415 | |
1416 | /* Read the header of the next packet. |
1417 | |
1418 | Return false on an error, true on success. */ |
1419 | static bool_Bool |
1420 | libpcap_read_header(wtap *wth, FILE_T fh, int *err, char **err_info, |
1421 | struct pcaprec_ss990915_hdr *hdr) |
1422 | { |
1423 | int bytes_to_read; |
1424 | uint32_t temp; |
1425 | libpcap_t *libpcap = (libpcap_t *)wth->priv; |
1426 | |
1427 | switch (libpcap->variant) { |
1428 | |
1429 | case PCAP: |
1430 | case PCAP_AIX: |
1431 | case PCAP_NSEC: |
1432 | bytes_to_read = sizeof (struct pcaprec_hdr); |
1433 | break; |
1434 | |
1435 | case PCAP_SS990417: |
1436 | case PCAP_SS991029: |
1437 | bytes_to_read = sizeof (struct pcaprec_modified_hdr); |
1438 | break; |
1439 | |
1440 | case PCAP_SS990915: |
1441 | bytes_to_read = sizeof (struct pcaprec_ss990915_hdr); |
1442 | break; |
1443 | |
1444 | case PCAP_NOKIA: |
1445 | bytes_to_read = sizeof (struct pcaprec_nokia_hdr); |
1446 | break; |
1447 | |
1448 | default: |
1449 | bytes_to_read = 0; |
Value stored to 'bytes_to_read' is never read | |
1450 | ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "wiretap/libpcap.c", 1450 , __func__, "assertion \"not reached\" failed"); |
1451 | } |
1452 | if (!wtap_read_bytes_or_eof(fh, hdr, bytes_to_read, err, err_info)) |
1453 | return false0; |
1454 | |
1455 | if (libpcap->byte_swapped) { |
1456 | /* Byte-swap the record header fields. */ |
1457 | hdr->hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr->hdr.ts_sec)(((guint32) ( (((guint32) (hdr->hdr.ts_sec) & (guint32 ) 0x000000ffU) << 24) | (((guint32) (hdr->hdr.ts_sec ) & (guint32) 0x0000ff00U) << 8) | (((guint32) (hdr ->hdr.ts_sec) & (guint32) 0x00ff0000U) >> 8) | ( ((guint32) (hdr->hdr.ts_sec) & (guint32) 0xff000000U) >> 24)))); |
1458 | hdr->hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr->hdr.ts_usec)(((guint32) ( (((guint32) (hdr->hdr.ts_usec) & (guint32 ) 0x000000ffU) << 24) | (((guint32) (hdr->hdr.ts_usec ) & (guint32) 0x0000ff00U) << 8) | (((guint32) (hdr ->hdr.ts_usec) & (guint32) 0x00ff0000U) >> 8) | ( ((guint32) (hdr->hdr.ts_usec) & (guint32) 0xff000000U) >> 24)))); |
1459 | hdr->hdr.incl_len = GUINT32_SWAP_LE_BE(hdr->hdr.incl_len)(((guint32) ( (((guint32) (hdr->hdr.incl_len) & (guint32 ) 0x000000ffU) << 24) | (((guint32) (hdr->hdr.incl_len ) & (guint32) 0x0000ff00U) << 8) | (((guint32) (hdr ->hdr.incl_len) & (guint32) 0x00ff0000U) >> 8) | (((guint32) (hdr->hdr.incl_len) & (guint32) 0xff000000U ) >> 24)))); |
1460 | hdr->hdr.orig_len = GUINT32_SWAP_LE_BE(hdr->hdr.orig_len)(((guint32) ( (((guint32) (hdr->hdr.orig_len) & (guint32 ) 0x000000ffU) << 24) | (((guint32) (hdr->hdr.orig_len ) & (guint32) 0x0000ff00U) << 8) | (((guint32) (hdr ->hdr.orig_len) & (guint32) 0x00ff0000U) >> 8) | (((guint32) (hdr->hdr.orig_len) & (guint32) 0xff000000U ) >> 24)))); |
1461 | } |
1462 | |
1463 | /* Swap the "incl_len" and "orig_len" fields, if necessary. */ |
1464 | switch (libpcap->lengths_swapped) { |
1465 | |
1466 | case NOT_SWAPPED: |
1467 | break; |
1468 | |
1469 | case MAYBE_SWAPPED: |
1470 | if (hdr->hdr.incl_len <= hdr->hdr.orig_len) { |
1471 | /* |
1472 | * The captured length is <= the actual length, |
1473 | * so presumably they weren't swapped. |
1474 | */ |
1475 | break; |
1476 | } |
1477 | /* FALLTHROUGH */ |
1478 | |
1479 | case SWAPPED: |
1480 | temp = hdr->hdr.orig_len; |
1481 | hdr->hdr.orig_len = hdr->hdr.incl_len; |
1482 | hdr->hdr.incl_len = temp; |
1483 | break; |
1484 | } |
1485 | |
1486 | return true1; |
1487 | } |
1488 | |
1489 | /* Returns 0 if we could write the specified encapsulation type, |
1490 | an error indication otherwise. */ |
1491 | static int libpcap_dump_can_write_encap(int encap) |
1492 | { |
1493 | /* Per-packet encapsulations aren't supported. */ |
1494 | if (encap == WTAP_ENCAP_PER_PACKET-1) |
1495 | return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED-9; |
1496 | |
1497 | if (wtap_wtap_encap_to_pcap_encap(encap) == -1) |
1498 | return WTAP_ERR_UNWRITABLE_ENCAP-8; |
1499 | |
1500 | return 0; |
1501 | } |
1502 | |
1503 | static bool_Bool libpcap_dump_write_file_header(wtap_dumper *wdh, uint32_t magic, |
1504 | int *err) |
1505 | { |
1506 | struct pcap_hdr file_hdr; |
1507 | |
1508 | if (!wtap_dump_file_write(wdh, &magic, sizeof magic, err)) |
1509 | return false0; |
1510 | |
1511 | /* current "libpcap" format is 2.4 */ |
1512 | file_hdr.version_major = 2; |
1513 | file_hdr.version_minor = 4; |
1514 | file_hdr.thiszone = 0; /* XXX - current offset? */ |
1515 | file_hdr.sigfigs = 0; /* unknown, but also apparently unused */ |
1516 | /* |
1517 | * Tcpdump cannot handle capture files with a snapshot length of 0, |
1518 | * as BPF filters return either 0 if they fail or the snapshot length |
1519 | * if they succeed, and a snapshot length of 0 means success is |
1520 | * indistinguishable from failure and the filter expression would |
1521 | * reject all packets. |
1522 | * |
1523 | * A snapshot length of 0, inside Wiretap, means "snapshot length |
1524 | * unknown"; if the snapshot length supplied to us is 0, we make |
1525 | * the snapshot length in the header file the maximum for the |
1526 | * link-layer type we'll be writing. |
1527 | */ |
1528 | file_hdr.snaplen = (wdh->snaplen != 0) ? (unsigned)wdh->snaplen : |
1529 | wtap_max_snaplen_for_encap(wdh->file_encap); |
1530 | file_hdr.network = wtap_wtap_encap_to_pcap_encap(wdh->file_encap); |
1531 | if (!wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr, err)) |
1532 | return false0; |
1533 | |
1534 | return true1; |
1535 | } |
1536 | |
1537 | /* Good old fashioned pcap. |
1538 | Returns true on success, false on failure; sets "*err" to an error code on |
1539 | failure */ |
1540 | static bool_Bool |
1541 | libpcap_dump_open_pcap(wtap_dumper *wdh, int *err, char **err_info _U___attribute__((unused))) |
1542 | { |
1543 | /* This is a libpcap file */ |
1544 | wdh->subtype_write = libpcap_dump_pcap; |
1545 | |
1546 | /* Write the file header. */ |
1547 | return libpcap_dump_write_file_header(wdh, PCAP_MAGIC0xa1b2c3d4, err); |
1548 | } |
1549 | |
1550 | /* Like classic pcap, but with nanosecond resolution. |
1551 | Returns true on success, false on failure; sets "*err" to an error code on |
1552 | failure */ |
1553 | static bool_Bool |
1554 | libpcap_dump_open_pcap_nsec(wtap_dumper *wdh, int *err, char **err_info _U___attribute__((unused))) |
1555 | { |
1556 | /* This is a nanosecond-resolution libpcap file */ |
1557 | wdh->subtype_write = libpcap_dump_pcap_nsec; |
1558 | |
1559 | /* Write the file header. */ |
1560 | return libpcap_dump_write_file_header(wdh, PCAP_NSEC_MAGIC0xa1b23c4d, err); |
1561 | } |
1562 | |
1563 | /* Modified, but with the old magic, sigh. |
1564 | Returns true on success, false on failure; sets "*err" to an error code on |
1565 | failure */ |
1566 | static bool_Bool |
1567 | libpcap_dump_open_pcap_ss990417(wtap_dumper *wdh, int *err, |
1568 | char **err_info _U___attribute__((unused))) |
1569 | { |
1570 | /* This is a modified-by-patch-SS990417 libpcap file */ |
1571 | wdh->subtype_write = libpcap_dump_pcap_ss990417; |
1572 | |
1573 | /* Write the file header. */ |
1574 | return libpcap_dump_write_file_header(wdh, PCAP_MAGIC0xa1b2c3d4, err); |
1575 | } |
1576 | |
1577 | /* New magic, extra crap. |
1578 | Returns true on success, false on failure; sets "*err" to an error code on |
1579 | failure */ |
1580 | static bool_Bool |
1581 | libpcap_dump_open_pcap_ss990915(wtap_dumper *wdh, int *err, |
1582 | char **err_info _U___attribute__((unused))) |
1583 | { |
1584 | /* This is a modified-by-patch-SS990915 libpcap file */ |
1585 | wdh->subtype_write = libpcap_dump_pcap_ss990915; |
1586 | |
1587 | /* Write the file header. */ |
1588 | return libpcap_dump_write_file_header(wdh, PCAP_MODIFIED_MAGIC0xa1b2cd34, err); |
1589 | } |
1590 | |
1591 | /* Same magic as SS990915, *different* extra crap, sigh. |
1592 | Returns true on success, false on failure; sets "*err" to an error code on |
1593 | failure */ |
1594 | static bool_Bool |
1595 | libpcap_dump_open_pcap_ss991029(wtap_dumper *wdh, int *err, |
1596 | char **err_info _U___attribute__((unused))) |
1597 | { |
1598 | /* This is a modified-by-patch-SS991029 libpcap file */ |
1599 | wdh->subtype_write = libpcap_dump_pcap_ss991029; |
1600 | |
1601 | /* Write the file header. */ |
1602 | return libpcap_dump_write_file_header(wdh, PCAP_MODIFIED_MAGIC0xa1b2cd34, err); |
1603 | } |
1604 | |
1605 | static void libpcap_close(wtap *wth) |
1606 | { |
1607 | libpcap_t *libpcap = (libpcap_t *)wth->priv; |
1608 | |
1609 | if (libpcap->encap_priv) { |
1610 | switch (wth->file_encap) { |
1611 | |
1612 | case WTAP_ENCAP_ERF98: |
1613 | erf_priv_free((erf_t*) libpcap->encap_priv); |
1614 | break; |
1615 | |
1616 | default: |
1617 | g_free(libpcap->encap_priv); |
1618 | break; |
1619 | } |
1620 | } |
1621 | } |
1622 | |
1623 | /* Nokia libpcap of some sort. |
1624 | Returns true on success, false on failure; sets "*err" to an error code on |
1625 | failure */ |
1626 | static bool_Bool |
1627 | libpcap_dump_open_pcap_nokia(wtap_dumper *wdh, int *err, char **err_info _U___attribute__((unused))) |
1628 | { |
1629 | /* This is a Nokia libpcap file */ |
1630 | wdh->subtype_write = libpcap_dump_pcap_nokia; |
1631 | |
1632 | /* Write the file header. */ |
1633 | return libpcap_dump_write_file_header(wdh, PCAP_MAGIC0xa1b2c3d4, err); |
1634 | } |
1635 | |
1636 | static bool_Bool |
1637 | libpcap_dump_write_packet(wtap_dumper *wdh, const wtap_rec *rec, |
1638 | struct pcaprec_hdr *hdr, size_t hdr_size, int *err, char **err_info) |
1639 | { |
1640 | const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header; |
1641 | unsigned phdrsize; |
1642 | |
1643 | phdrsize = pcap_get_phdr_size(wdh->file_encap, pseudo_header); |
1644 | |
1645 | /* We can only write packet records. */ |
1646 | if (rec->rec_type != REC_TYPE_PACKET0) { |
1647 | *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24; |
1648 | *err_info = wtap_unwritable_rec_type_err_string(rec); |
1649 | return false0; |
1650 | } |
1651 | |
1652 | /* |
1653 | * Make sure this packet doesn't have a link-layer type that |
1654 | * differs from the one for the file. |
1655 | */ |
1656 | if (wdh->file_encap != rec->rec_header.packet_header.pkt_encap) { |
1657 | *err = WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED-9; |
1658 | return false0; |
1659 | } |
1660 | |
1661 | /* |
1662 | * Don't write anything we're not willing to read. |
1663 | * (The cast is to prevent an overflow.) |
1664 | */ |
1665 | if ((uint64_t)rec->rec_header.packet_header.caplen + phdrsize > wtap_max_snaplen_for_encap(wdh->file_encap)) { |
1666 | *err = WTAP_ERR_PACKET_TOO_LARGE-22; |
1667 | return false0; |
1668 | } |
1669 | |
1670 | hdr->incl_len = rec->rec_header.packet_header.caplen + phdrsize; |
1671 | hdr->orig_len = rec->rec_header.packet_header.len + phdrsize; |
1672 | |
1673 | if (!wtap_dump_file_write(wdh, hdr, hdr_size, err)) |
1674 | return false0; |
1675 | |
1676 | if (!pcap_write_phdr(wdh, wdh->file_encap, pseudo_header, err)) |
1677 | return false0; |
1678 | |
1679 | if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), |
1680 | rec->rec_header.packet_header.caplen, err)) |
1681 | return false0; |
1682 | return true1; |
1683 | } |
1684 | |
1685 | /* Good old fashioned pcap. |
1686 | Write a record for a packet to a dump file. |
1687 | Returns true on success, false on failure. */ |
1688 | static bool_Bool |
1689 | libpcap_dump_pcap(wtap_dumper *wdh, const wtap_rec *rec, |
1690 | int *err, char **err_info) |
1691 | { |
1692 | struct pcaprec_hdr rec_hdr; |
1693 | |
1694 | /* |
1695 | * Some code that reads libpcap files may handle time |
1696 | * stamps as unsigned, but most of it probably handles |
1697 | * them as signed. |
1698 | */ |
1699 | if (rec->ts.secs < 0 || rec->ts.secs > INT32_MAX(2147483647)) { |
1700 | *err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED-27; |
1701 | return false0; |
1702 | } |
1703 | rec_hdr.ts_sec = (uint32_t) rec->ts.secs; |
1704 | rec_hdr.ts_usec = rec->ts.nsecs / 1000; |
1705 | return libpcap_dump_write_packet(wdh, rec, &rec_hdr, sizeof rec_hdr, |
1706 | err, err_info); |
1707 | } |
1708 | |
1709 | /* Like classic pcap, but with nanosecond resolution. |
1710 | Write a record for a packet to a dump file. |
1711 | Returns true on success, false on failure. */ |
1712 | static bool_Bool |
1713 | libpcap_dump_pcap_nsec(wtap_dumper *wdh, const wtap_rec *rec, |
1714 | int *err, char **err_info) |
1715 | { |
1716 | struct pcaprec_hdr rec_hdr; |
1717 | |
1718 | /* |
1719 | * Some code that reads libpcap files may handle time |
1720 | * stamps as unsigned, but most of it probably handles |
1721 | * them as signed. |
1722 | */ |
1723 | if (rec->ts.secs < 0 || rec->ts.secs > INT32_MAX(2147483647)) { |
1724 | *err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED-27; |
1725 | return false0; |
1726 | } |
1727 | rec_hdr.ts_sec = (uint32_t) rec->ts.secs; |
1728 | rec_hdr.ts_usec = rec->ts.nsecs; |
1729 | return libpcap_dump_write_packet(wdh, rec, &rec_hdr, sizeof rec_hdr, |
1730 | err, err_info); |
1731 | } |
1732 | |
1733 | /* Modified, but with the old magic, sigh. |
1734 | Write a record for a packet to a dump file. |
1735 | Returns true on success, false on failure. */ |
1736 | static bool_Bool |
1737 | libpcap_dump_pcap_ss990417(wtap_dumper *wdh, const wtap_rec *rec, |
1738 | int *err, char **err_info) |
1739 | { |
1740 | struct pcaprec_modified_hdr rec_hdr; |
1741 | |
1742 | /* |
1743 | * Some code that reads libpcap files may handle time |
1744 | * stamps as unsigned, but most of it probably handles |
1745 | * them as signed. |
1746 | */ |
1747 | if (rec->ts.secs < 0 || rec->ts.secs > INT32_MAX(2147483647)) { |
1748 | *err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED-27; |
1749 | return false0; |
1750 | } |
1751 | rec_hdr.hdr.ts_sec = (uint32_t) rec->ts.secs; |
1752 | rec_hdr.hdr.ts_usec = rec->ts.nsecs / 1000; |
1753 | /* XXX - what should we supply here? |
1754 | |
1755 | Alexey's "libpcap" looks up the interface in the system's |
1756 | interface list if "ifindex" is non-zero, and prints |
1757 | the interface name. It ignores "protocol", and uses |
1758 | "pkt_type" to tag the packet as "host", "broadcast", |
1759 | "multicast", "other host", "outgoing", or "none of the |
1760 | above", but that's it. |
1761 | |
1762 | If the capture we're writing isn't a modified or |
1763 | RH 6.1 capture, we'd have to do some work to |
1764 | generate the packet type and interface index - and |
1765 | we can't generate the interface index unless we |
1766 | just did the capture ourselves in any case. |
1767 | |
1768 | I'm inclined to continue to punt; systems other than |
1769 | those with the older patch can read standard "libpcap" |
1770 | files, and systems with the older patch, e.g. RH 6.1, |
1771 | will just have to live with this. */ |
1772 | rec_hdr.ifindex = 0; |
1773 | rec_hdr.protocol = 0; |
1774 | rec_hdr.pkt_type = 0; |
1775 | return libpcap_dump_write_packet(wdh, rec, &rec_hdr.hdr, sizeof rec_hdr, |
1776 | err, err_info); |
1777 | } |
1778 | |
1779 | /* New magic, extra crap. |
1780 | Write a record for a packet to a dump file. |
1781 | Returns true on success, false on failure. */ |
1782 | static bool_Bool |
1783 | libpcap_dump_pcap_ss990915(wtap_dumper *wdh, const wtap_rec *rec, |
1784 | int *err, char **err_info) |
1785 | { |
1786 | struct pcaprec_ss990915_hdr rec_hdr; |
1787 | |
1788 | /* |
1789 | * Some code that reads libpcap files may handle time |
1790 | * stamps as unsigned, but most of it probably handles |
1791 | * them as signed. |
1792 | */ |
1793 | if (rec->ts.secs < 0 || rec->ts.secs > INT32_MAX(2147483647)) { |
1794 | *err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED-27; |
1795 | return false0; |
1796 | } |
1797 | rec_hdr.hdr.ts_sec = (uint32_t) rec->ts.secs; |
1798 | rec_hdr.hdr.ts_usec = rec->ts.nsecs / 1000; |
1799 | rec_hdr.ifindex = 0; |
1800 | rec_hdr.protocol = 0; |
1801 | rec_hdr.pkt_type = 0; |
1802 | rec_hdr.cpu1 = 0; |
1803 | rec_hdr.cpu2 = 0; |
1804 | return libpcap_dump_write_packet(wdh, rec, &rec_hdr.hdr, sizeof rec_hdr, |
1805 | err, err_info); |
1806 | } |
1807 | |
1808 | /* Same magic as SS990915, *different* extra crap, sigh. |
1809 | Write a record for a packet to a dump file. |
1810 | Returns true on success, false on failure. */ |
1811 | static bool_Bool |
1812 | libpcap_dump_pcap_ss991029(wtap_dumper *wdh, const wtap_rec *rec, |
1813 | int *err, char **err_info) |
1814 | { |
1815 | struct pcaprec_modified_hdr rec_hdr; |
1816 | |
1817 | /* |
1818 | * Some code that reads libpcap files may handle time |
1819 | * stamps as unsigned, but most of it probably handles |
1820 | * them as signed. |
1821 | */ |
1822 | if (rec->ts.secs < 0 || rec->ts.secs > INT32_MAX(2147483647)) { |
1823 | *err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED-27; |
1824 | return false0; |
1825 | } |
1826 | rec_hdr.hdr.ts_sec = (uint32_t) rec->ts.secs; |
1827 | rec_hdr.hdr.ts_usec = rec->ts.nsecs / 1000; |
1828 | /* XXX - what should we supply here? |
1829 | |
1830 | Alexey's "libpcap" looks up the interface in the system's |
1831 | interface list if "ifindex" is non-zero, and prints |
1832 | the interface name. It ignores "protocol", and uses |
1833 | "pkt_type" to tag the packet as "host", "broadcast", |
1834 | "multicast", "other host", "outgoing", or "none of the |
1835 | above", but that's it. |
1836 | |
1837 | If the capture we're writing isn't a modified or |
1838 | RH 6.1 capture, we'd have to do some work to |
1839 | generate the packet type and interface index - and |
1840 | we can't generate the interface index unless we |
1841 | just did the capture ourselves in any case. |
1842 | |
1843 | I'm inclined to continue to punt; systems other than |
1844 | those with the older patch can read standard "libpcap" |
1845 | files, and systems with the older patch, e.g. RH 6.1, |
1846 | will just have to live with this. */ |
1847 | rec_hdr.ifindex = 0; |
1848 | rec_hdr.protocol = 0; |
1849 | rec_hdr.pkt_type = 0; |
1850 | return libpcap_dump_write_packet(wdh, rec, &rec_hdr.hdr, sizeof rec_hdr, |
1851 | err, err_info); |
1852 | } |
1853 | |
1854 | /* Nokia libpcap of some sort. |
1855 | Write a record for a packet to a dump file. |
1856 | Returns true on success, false on failure. */ |
1857 | static bool_Bool |
1858 | libpcap_dump_pcap_nokia(wtap_dumper *wdh, const wtap_rec *rec, |
1859 | int *err, char **err_info) |
1860 | { |
1861 | struct pcaprec_nokia_hdr rec_hdr; |
1862 | const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header; |
1863 | |
1864 | /* |
1865 | * Some code that reads libpcap files may handle time |
1866 | * stamps as unsigned, but most of it probably handles |
1867 | * them as signed. |
1868 | */ |
1869 | if (rec->ts.secs < 0 || rec->ts.secs > INT32_MAX(2147483647)) { |
1870 | *err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED-27; |
1871 | return false0; |
1872 | } |
1873 | rec_hdr.hdr.ts_sec = (uint32_t) rec->ts.secs; |
1874 | rec_hdr.hdr.ts_usec = rec->ts.nsecs / 1000; |
1875 | /* restore the "mysterious stuff" that came with the packet */ |
1876 | memcpy(rec_hdr.stuff, pseudo_header->nokia.stuff, 4); |
1877 | return libpcap_dump_write_packet(wdh, rec, &rec_hdr.hdr, sizeof rec_hdr, |
1878 | err, err_info); |
1879 | } |
1880 | |
1881 | static const struct supported_block_type pcap_blocks_supported[] = { |
1882 | /* |
1883 | * We support packet blocks, with no comments or other options. |
1884 | */ |
1885 | { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED0, ((void*)0) } |
1886 | }; |
1887 | |
1888 | static const struct file_type_subtype_info pcap_info = { |
1889 | /* Gianluca Varenni suggests that we add "deprecated" to the description. */ |
1890 | "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp", |
1891 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1892 | libpcap_dump_can_write_encap, libpcap_dump_open_pcap, NULL((void*)0) |
1893 | }; |
1894 | |
1895 | static const struct file_type_subtype_info pcap_nsec_info = { |
1896 | "Wireshark/tcpdump/... - nanosecond pcap", "nsecpcap", "pcap", "cap;dmp", |
1897 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1898 | libpcap_dump_can_write_encap, libpcap_dump_open_pcap_nsec, NULL((void*)0) |
1899 | }; |
1900 | |
1901 | static const struct file_type_subtype_info pcap_aix_info = { |
1902 | "AIX tcpdump - pcap", "aixpcap", "pcap", "cap;dmp", |
1903 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1904 | NULL((void*)0), NULL((void*)0), NULL((void*)0) |
1905 | }; |
1906 | |
1907 | static const struct file_type_subtype_info pcap_ss990417_info = { |
1908 | "RedHat 6.1 tcpdump - pcap", "rh6_1pcap", "pcap", "cap;dmp", |
1909 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1910 | libpcap_dump_can_write_encap, libpcap_dump_open_pcap_ss990417, NULL((void*)0) |
1911 | }; |
1912 | |
1913 | static const struct file_type_subtype_info pcap_ss990915_info = { |
1914 | "SuSE 6.3 tcpdump - pcap", "suse6_3pcap", "pcap", "cap;dmp", |
1915 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1916 | libpcap_dump_can_write_encap, libpcap_dump_open_pcap_ss990915, NULL((void*)0) |
1917 | }; |
1918 | |
1919 | static const struct file_type_subtype_info pcap_ss991029_info = { |
1920 | "Modified tcpdump - pcap", "modpcap", "pcap", "cap;dmp", |
1921 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1922 | libpcap_dump_can_write_encap, libpcap_dump_open_pcap_ss991029, NULL((void*)0) |
1923 | }; |
1924 | |
1925 | static const struct file_type_subtype_info pcap_nokia_info = { |
1926 | "Nokia tcpdump - pcap", "nokiapcap", "pcap", "cap;dmp", |
1927 | false0, BLOCKS_SUPPORTED(pcap_blocks_supported)(sizeof (pcap_blocks_supported) / sizeof (pcap_blocks_supported )[0]), pcap_blocks_supported, |
1928 | libpcap_dump_can_write_encap, libpcap_dump_open_pcap_nokia, NULL((void*)0) |
1929 | }; |
1930 | |
1931 | void register_pcap(void) |
1932 | { |
1933 | pcap_file_type_subtype = wtap_register_file_type_subtype(&pcap_info); |
1934 | pcap_nsec_file_type_subtype = wtap_register_file_type_subtype(&pcap_nsec_info); |
1935 | pcap_aix_file_type_subtype = wtap_register_file_type_subtype(&pcap_aix_info); |
1936 | pcap_ss990417_file_type_subtype = wtap_register_file_type_subtype(&pcap_ss990417_info); |
1937 | pcap_ss990915_file_type_subtype = wtap_register_file_type_subtype(&pcap_ss990915_info); |
1938 | pcap_ss991029_file_type_subtype = wtap_register_file_type_subtype(&pcap_ss991029_info); |
1939 | pcap_nokia_file_type_subtype = wtap_register_file_type_subtype(&pcap_nokia_info); |
1940 | |
1941 | /* |
1942 | * We now call the libpcap file format just pcap, but we allow |
1943 | * the various variants of it to be specified using names |
1944 | * containing "libpcap" as well as "pcap", for backwards |
1945 | * compatibility. |
1946 | * |
1947 | * Register names for that purpose. |
1948 | */ |
1949 | wtap_register_compatibility_file_subtype_name("libpcap", "pcap"); |
1950 | wtap_register_compatibility_file_subtype_name("nseclibpcap", "nsecpcap"); |
1951 | wtap_register_compatibility_file_subtype_name("aixlibpcap", "aixpcap"); |
1952 | wtap_register_compatibility_file_subtype_name("modlibpcap", "modpcap"); |
1953 | wtap_register_compatibility_file_subtype_name("nokialibpcap", "nokiapcap"); |
1954 | wtap_register_compatibility_file_subtype_name("rh6_1libpcap", "rh6_1pcap"); |
1955 | wtap_register_compatibility_file_subtype_name("suse6_3libpcap", "suse6_3pcap"); |
1956 | |
1957 | /* |
1958 | * Register names for backwards compatibility with the |
1959 | * wtap_filetypes table in Lua. |
1960 | */ |
1961 | wtap_register_backwards_compatibility_lua_name("PCAP", |
1962 | pcap_file_type_subtype); |
1963 | wtap_register_backwards_compatibility_lua_name("PCAP_NSEC", |
1964 | pcap_nsec_file_type_subtype); |
1965 | wtap_register_backwards_compatibility_lua_name("PCAP_AIX", |
1966 | pcap_aix_file_type_subtype); |
1967 | wtap_register_backwards_compatibility_lua_name("PCAP_SS990417", |
1968 | pcap_ss990417_file_type_subtype); |
1969 | wtap_register_backwards_compatibility_lua_name("PCAP_SS990915", |
1970 | pcap_ss990915_file_type_subtype); |
1971 | wtap_register_backwards_compatibility_lua_name("PCAP_SS991029", |
1972 | pcap_ss991029_file_type_subtype); |
1973 | wtap_register_backwards_compatibility_lua_name("PCAP_NOKIA", |
1974 | pcap_nokia_file_type_subtype); |
1975 | } |
1976 | |
1977 | /* |
1978 | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1979 | * |
1980 | * Local variables: |
1981 | * c-basic-offset: 8 |
1982 | * tab-width: 8 |
1983 | * indent-tabs-mode: t |
1984 | * End: |
1985 | * |
1986 | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
1987 | * :indentSize=8:tabSize=8:noTabs=false: |
1988 | */ |