### Bug Summary

File: | builds/wireshark/wireshark/wiretap/libpcap.c
Warning: | line 1458, column 3 Value stored to 'bytes_to_read' is never read

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name libpcap.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D wiretap_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -I /builds/wireshark/wireshark/build/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-08-01-100307-3660-1 -x c /builds/wireshark/wireshark/wiretap/libpcap.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

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