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