/src/libpcap-1.9.1/sf-pcapng.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 1993, 1994, 1995, 1996, 1997 |
3 | | * The Regents of the University of California. All rights reserved. |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that: (1) source code distributions |
7 | | * retain the above copyright notice and this paragraph in its entirety, (2) |
8 | | * distributions including binary code include the above copyright notice and |
9 | | * this paragraph in its entirety in the documentation or other materials |
10 | | * provided with the distribution, and (3) all advertising materials mentioning |
11 | | * features or use of this software display the following acknowledgement: |
12 | | * ``This product includes software developed by the University of California, |
13 | | * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of |
14 | | * the University nor the names of its contributors may be used to endorse |
15 | | * or promote products derived from this software without specific prior |
16 | | * written permission. |
17 | | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
18 | | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
19 | | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
20 | | * |
21 | | * sf-pcapng.c - pcapng-file-format-specific code from savefile.c |
22 | | */ |
23 | | |
24 | | #ifdef HAVE_CONFIG_H |
25 | | #include <config.h> |
26 | | #endif |
27 | | |
28 | | #include <pcap/pcap-inttypes.h> |
29 | | |
30 | | #include <errno.h> |
31 | | #include <memory.h> |
32 | | #include <stdio.h> |
33 | | #include <stdlib.h> |
34 | | #include <string.h> |
35 | | |
36 | | #include "pcap-int.h" |
37 | | |
38 | | #include "pcap-common.h" |
39 | | |
40 | | #ifdef HAVE_OS_PROTO_H |
41 | | #include "os-proto.h" |
42 | | #endif |
43 | | |
44 | | #include "sf-pcapng.h" |
45 | | |
46 | | /* |
47 | | * Block types. |
48 | | */ |
49 | | |
50 | | /* |
51 | | * Common part at the beginning of all blocks. |
52 | | */ |
53 | | struct block_header { |
54 | | bpf_u_int32 block_type; |
55 | | bpf_u_int32 total_length; |
56 | | }; |
57 | | |
58 | | /* |
59 | | * Common trailer at the end of all blocks. |
60 | | */ |
61 | | struct block_trailer { |
62 | | bpf_u_int32 total_length; |
63 | | }; |
64 | | |
65 | | /* |
66 | | * Common options. |
67 | | */ |
68 | 128 | #define OPT_ENDOFOPT 0 /* end of options */ |
69 | | #define OPT_COMMENT 1 /* comment string */ |
70 | | |
71 | | /* |
72 | | * Option header. |
73 | | */ |
74 | | struct option_header { |
75 | | u_short option_code; |
76 | | u_short option_length; |
77 | | }; |
78 | | |
79 | | /* |
80 | | * Structures for the part of each block type following the common |
81 | | * part. |
82 | | */ |
83 | | |
84 | | /* |
85 | | * Section Header Block. |
86 | | */ |
87 | 2.31k | #define BT_SHB 0x0A0D0D0A |
88 | 1.03k | #define BT_SHB_INSANE_MAX 1024U*1024U*1U /* 1MB should be enough */ |
89 | | struct section_header_block { |
90 | | bpf_u_int32 byte_order_magic; |
91 | | u_short major_version; |
92 | | u_short minor_version; |
93 | | uint64_t section_length; |
94 | | /* followed by options and trailer */ |
95 | | }; |
96 | | |
97 | | /* |
98 | | * Byte-order magic value. |
99 | | */ |
100 | 1.56k | #define BYTE_ORDER_MAGIC 0x1A2B3C4D |
101 | | |
102 | | /* |
103 | | * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR, |
104 | | * that means that this code can't read the file. |
105 | | */ |
106 | 2.06k | #define PCAP_NG_VERSION_MAJOR 1 |
107 | 885 | #define PCAP_NG_VERSION_MINOR 0 |
108 | | |
109 | | /* |
110 | | * Interface Description Block. |
111 | | */ |
112 | 2.53k | #define BT_IDB 0x00000001 |
113 | | |
114 | | struct interface_description_block { |
115 | | u_short linktype; |
116 | | u_short reserved; |
117 | | bpf_u_int32 snaplen; |
118 | | /* followed by options and trailer */ |
119 | | }; |
120 | | |
121 | | /* |
122 | | * Options in the IDB. |
123 | | */ |
124 | | #define IF_NAME 2 /* interface name string */ |
125 | | #define IF_DESCRIPTION 3 /* interface description string */ |
126 | | #define IF_IPV4ADDR 4 /* interface's IPv4 address and netmask */ |
127 | | #define IF_IPV6ADDR 5 /* interface's IPv6 address and prefix length */ |
128 | | #define IF_MACADDR 6 /* interface's MAC address */ |
129 | | #define IF_EUIADDR 7 /* interface's EUI address */ |
130 | | #define IF_SPEED 8 /* interface's speed, in bits/s */ |
131 | 812 | #define IF_TSRESOL 9 /* interface's time stamp resolution */ |
132 | | #define IF_TZONE 10 /* interface's time zone */ |
133 | | #define IF_FILTER 11 /* filter used when capturing on interface */ |
134 | | #define IF_OS 12 /* string OS on which capture on this interface was done */ |
135 | | #define IF_FCSLEN 13 /* FCS length for this interface */ |
136 | 135 | #define IF_TSOFFSET 14 /* time stamp offset for this interface */ |
137 | | |
138 | | /* |
139 | | * Enhanced Packet Block. |
140 | | */ |
141 | 1.43k | #define BT_EPB 0x00000006 |
142 | | |
143 | | struct enhanced_packet_block { |
144 | | bpf_u_int32 interface_id; |
145 | | bpf_u_int32 timestamp_high; |
146 | | bpf_u_int32 timestamp_low; |
147 | | bpf_u_int32 caplen; |
148 | | bpf_u_int32 len; |
149 | | /* followed by packet data, options, and trailer */ |
150 | | }; |
151 | | |
152 | | /* |
153 | | * Simple Packet Block. |
154 | | */ |
155 | 1.18k | #define BT_SPB 0x00000003 |
156 | | |
157 | | struct simple_packet_block { |
158 | | bpf_u_int32 len; |
159 | | /* followed by packet data and trailer */ |
160 | | }; |
161 | | |
162 | | /* |
163 | | * Packet Block. |
164 | | */ |
165 | 91 | #define BT_PB 0x00000002 |
166 | | |
167 | | struct packet_block { |
168 | | u_short interface_id; |
169 | | u_short drops_count; |
170 | | bpf_u_int32 timestamp_high; |
171 | | bpf_u_int32 timestamp_low; |
172 | | bpf_u_int32 caplen; |
173 | | bpf_u_int32 len; |
174 | | /* followed by packet data, options, and trailer */ |
175 | | }; |
176 | | |
177 | | /* |
178 | | * Block cursor - used when processing the contents of a block. |
179 | | * Contains a pointer into the data being processed and a count |
180 | | * of bytes remaining in the block. |
181 | | */ |
182 | | struct block_cursor { |
183 | | u_char *data; |
184 | | size_t data_remaining; |
185 | | bpf_u_int32 block_type; |
186 | | }; |
187 | | |
188 | | typedef enum { |
189 | | PASS_THROUGH, |
190 | | SCALE_UP_DEC, |
191 | | SCALE_DOWN_DEC, |
192 | | SCALE_UP_BIN, |
193 | | SCALE_DOWN_BIN |
194 | | } tstamp_scale_type_t; |
195 | | |
196 | | /* |
197 | | * Per-interface information. |
198 | | */ |
199 | | struct pcap_ng_if { |
200 | | uint64_t tsresol; /* time stamp resolution */ |
201 | | tstamp_scale_type_t scale_type; /* how to scale */ |
202 | | uint64_t scale_factor; /* time stamp scale factor for power-of-10 tsresol */ |
203 | | uint64_t tsoffset; /* time stamp offset */ |
204 | | }; |
205 | | |
206 | | /* |
207 | | * Per-pcap_t private data. |
208 | | * |
209 | | * max_blocksize is the maximum size of a block that we'll accept. We |
210 | | * reject blocks bigger than this, so we don't consume too much memory |
211 | | * with a truly huge block. It can change as we see IDBs with different |
212 | | * link-layer header types. (Currently, we don't support IDBs with |
213 | | * different link-layer header types, but we will support it in the |
214 | | * future, when we offer file-reading APIs that support it.) |
215 | | * |
216 | | * XXX - that's an issue on ILP32 platforms, where the maximum block |
217 | | * size of 2^31-1 would eat all but one byte of the entire address space. |
218 | | * It's less of an issue on ILP64/LLP64 platforms, but the actual size |
219 | | * of the address space may be limited by 1) the number of *significant* |
220 | | * address bits (currently, x86-64 only supports 48 bits of address), 2) |
221 | | * any limitations imposed by the operating system; 3) any limitations |
222 | | * imposed by the amount of available backing store for anonymous pages, |
223 | | * so we impose a limit regardless of the size of a pointer. |
224 | | */ |
225 | | struct pcap_ng_sf { |
226 | | uint64_t user_tsresol; /* time stamp resolution requested by the user */ |
227 | | u_int max_blocksize; /* don't grow buffer size past this */ |
228 | | bpf_u_int32 ifcount; /* number of interfaces seen in this capture */ |
229 | | bpf_u_int32 ifaces_size; /* size of array below */ |
230 | | struct pcap_ng_if *ifaces; /* array of interface information */ |
231 | | }; |
232 | | |
233 | | /* |
234 | | * The maximum block size we start with; we use an arbitrary value of |
235 | | * 16 MiB. |
236 | | */ |
237 | 955 | #define INITIAL_MAX_BLOCKSIZE (16*1024*1024) |
238 | | |
239 | | /* |
240 | | * Maximum block size for a given maximum snapshot length; we define it |
241 | | * as the size of an EPB with a max_snaplen-sized packet and 128KB of |
242 | | * options. |
243 | | */ |
244 | | #define MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen) \ |
245 | 696 | (sizeof (struct block_header) + \ |
246 | 696 | sizeof (struct enhanced_packet_block) + \ |
247 | 696 | (max_snaplen) + 131072 + \ |
248 | 696 | sizeof (struct block_trailer)) |
249 | | |
250 | | static void pcap_ng_cleanup(pcap_t *p); |
251 | | static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, |
252 | | u_char **data); |
253 | | |
254 | | static int |
255 | | read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof, |
256 | | char *errbuf) |
257 | 14.0k | { |
258 | 14.0k | size_t amt_read; |
259 | | |
260 | 14.0k | amt_read = fread(buf, 1, bytes_to_read, fp); |
261 | 14.0k | if (amt_read != bytes_to_read) { |
262 | 416 | if (ferror(fp)) { |
263 | 0 | pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, |
264 | 0 | errno, "error reading dump file"); |
265 | 416 | } else { |
266 | 416 | if (amt_read == 0 && !fail_on_eof) |
267 | 233 | return (0); /* EOF */ |
268 | 183 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
269 | 183 | "truncated pcapng dump file; tried to read %" PRIsize " bytes, only got %" PRIsize, |
270 | 183 | bytes_to_read, amt_read); |
271 | 183 | } |
272 | 183 | return (-1); |
273 | 416 | } |
274 | 13.6k | return (1); |
275 | 14.0k | } |
276 | | |
277 | | static int |
278 | | read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf) |
279 | 6.76k | { |
280 | 6.76k | struct pcap_ng_sf *ps; |
281 | 6.76k | int status; |
282 | 6.76k | struct block_header bhdr; |
283 | 6.76k | struct block_trailer *btrlr; |
284 | 6.76k | u_char *bdata; |
285 | 6.76k | size_t data_remaining; |
286 | | |
287 | 6.76k | ps = p->priv; |
288 | | |
289 | 6.76k | status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf); |
290 | 6.76k | if (status <= 0) |
291 | 301 | return (status); /* error or EOF */ |
292 | | |
293 | 6.46k | if (p->swapped) { |
294 | 1.15k | bhdr.block_type = SWAPLONG(bhdr.block_type); |
295 | 1.15k | bhdr.total_length = SWAPLONG(bhdr.total_length); |
296 | 1.15k | } |
297 | | |
298 | | /* |
299 | | * Is this block "too small" - i.e., is it shorter than a block |
300 | | * header plus a block trailer? |
301 | | */ |
302 | 6.46k | if (bhdr.total_length < sizeof(struct block_header) + |
303 | 6.46k | sizeof(struct block_trailer)) { |
304 | 6 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
305 | 6 | "block in pcapng dump file has a length of %u < %" PRIsize, |
306 | 6 | bhdr.total_length, |
307 | 6 | sizeof(struct block_header) + sizeof(struct block_trailer)); |
308 | 6 | return (-1); |
309 | 6 | } |
310 | | |
311 | | /* |
312 | | * Is the block total length a multiple of 4? |
313 | | */ |
314 | 6.46k | if ((bhdr.total_length % 4) != 0) { |
315 | | /* |
316 | | * No. Report that as an error. |
317 | | */ |
318 | 16 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
319 | 16 | "block in pcapng dump file has a length of %u that is not a multiple of 4" PRIsize, |
320 | 16 | bhdr.total_length); |
321 | 16 | return (-1); |
322 | 16 | } |
323 | | |
324 | | /* |
325 | | * Is the buffer big enough? |
326 | | */ |
327 | 6.44k | if (p->bufsize < bhdr.total_length) { |
328 | | /* |
329 | | * No - make it big enough, unless it's too big, in |
330 | | * which case we fail. |
331 | | */ |
332 | 119 | void *bigger_buffer; |
333 | | |
334 | 119 | if (bhdr.total_length > ps->max_blocksize) { |
335 | 69 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length, |
336 | 69 | ps->max_blocksize); |
337 | 69 | return (-1); |
338 | 69 | } |
339 | 50 | bigger_buffer = realloc(p->buffer, bhdr.total_length); |
340 | 50 | if (bigger_buffer == NULL) { |
341 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); |
342 | 0 | return (-1); |
343 | 0 | } |
344 | 50 | p->buffer = bigger_buffer; |
345 | 50 | } |
346 | | |
347 | | /* |
348 | | * Copy the stuff we've read to the buffer, and read the rest |
349 | | * of the block. |
350 | | */ |
351 | 6.37k | memcpy(p->buffer, &bhdr, sizeof(bhdr)); |
352 | 6.37k | bdata = (u_char *)p->buffer + sizeof(bhdr); |
353 | 6.37k | data_remaining = bhdr.total_length - sizeof(bhdr); |
354 | 6.37k | if (read_bytes(fp, bdata, data_remaining, 1, errbuf) == -1) |
355 | 57 | return (-1); |
356 | | |
357 | | /* |
358 | | * Get the block size from the trailer. |
359 | | */ |
360 | 6.31k | btrlr = (struct block_trailer *)(bdata + data_remaining - sizeof (struct block_trailer)); |
361 | 6.31k | if (p->swapped) |
362 | 1.12k | btrlr->total_length = SWAPLONG(btrlr->total_length); |
363 | | |
364 | | /* |
365 | | * Is the total length from the trailer the same as the total |
366 | | * length from the header? |
367 | | */ |
368 | 6.31k | if (bhdr.total_length != btrlr->total_length) { |
369 | | /* |
370 | | * No. |
371 | | */ |
372 | 52 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
373 | 52 | "block total length in header and trailer don't match"); |
374 | 52 | return (-1); |
375 | 52 | } |
376 | | |
377 | | /* |
378 | | * Initialize the cursor. |
379 | | */ |
380 | 6.26k | cursor->data = bdata; |
381 | 6.26k | cursor->data_remaining = data_remaining - sizeof(struct block_trailer); |
382 | 6.26k | cursor->block_type = bhdr.block_type; |
383 | 6.26k | return (1); |
384 | 6.31k | } |
385 | | |
386 | | static void * |
387 | | get_from_block_data(struct block_cursor *cursor, size_t chunk_size, |
388 | | char *errbuf) |
389 | 11.7k | { |
390 | 11.7k | void *data; |
391 | | |
392 | | /* |
393 | | * Make sure we have the specified amount of data remaining in |
394 | | * the block data. |
395 | | */ |
396 | 11.7k | if (cursor->data_remaining < chunk_size) { |
397 | 76 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
398 | 76 | "block of type %u in pcapng dump file is too short", |
399 | 76 | cursor->block_type); |
400 | 76 | return (NULL); |
401 | 76 | } |
402 | | |
403 | | /* |
404 | | * Return the current pointer, and skip past the chunk. |
405 | | */ |
406 | 11.7k | data = cursor->data; |
407 | 11.7k | cursor->data += chunk_size; |
408 | 11.7k | cursor->data_remaining -= chunk_size; |
409 | 11.7k | return (data); |
410 | 11.7k | } |
411 | | |
412 | | static struct option_header * |
413 | | get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf) |
414 | 1.75k | { |
415 | 1.75k | struct option_header *opthdr; |
416 | | |
417 | 1.75k | opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf); |
418 | 1.75k | if (opthdr == NULL) { |
419 | | /* |
420 | | * Option header is cut short. |
421 | | */ |
422 | 0 | return (NULL); |
423 | 0 | } |
424 | | |
425 | | /* |
426 | | * Byte-swap it if necessary. |
427 | | */ |
428 | 1.75k | if (p->swapped) { |
429 | 581 | opthdr->option_code = SWAPSHORT(opthdr->option_code); |
430 | 581 | opthdr->option_length = SWAPSHORT(opthdr->option_length); |
431 | 581 | } |
432 | | |
433 | 1.75k | return (opthdr); |
434 | 1.75k | } |
435 | | |
436 | | static void * |
437 | | get_optvalue_from_block_data(struct block_cursor *cursor, |
438 | | struct option_header *opthdr, char *errbuf) |
439 | 1.75k | { |
440 | 1.75k | size_t padded_option_len; |
441 | 1.75k | void *optvalue; |
442 | | |
443 | | /* Pad option length to 4-byte boundary */ |
444 | 1.75k | padded_option_len = opthdr->option_length; |
445 | 1.75k | padded_option_len = ((padded_option_len + 3)/4)*4; |
446 | | |
447 | 1.75k | optvalue = get_from_block_data(cursor, padded_option_len, errbuf); |
448 | 1.75k | if (optvalue == NULL) { |
449 | | /* |
450 | | * Option value is cut short. |
451 | | */ |
452 | 9 | return (NULL); |
453 | 9 | } |
454 | | |
455 | 1.74k | return (optvalue); |
456 | 1.75k | } |
457 | | |
458 | | static int |
459 | | process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, |
460 | | uint64_t *tsoffset, int *is_binary, char *errbuf) |
461 | 2.47k | { |
462 | 2.47k | struct option_header *opthdr; |
463 | 2.47k | void *optvalue; |
464 | 2.47k | int saw_tsresol, saw_tsoffset; |
465 | 2.47k | uint8_t tsresol_opt; |
466 | 2.47k | u_int i; |
467 | | |
468 | 2.47k | saw_tsresol = 0; |
469 | 2.47k | saw_tsoffset = 0; |
470 | 4.07k | while (cursor->data_remaining != 0) { |
471 | | /* |
472 | | * Get the option header. |
473 | | */ |
474 | 1.75k | opthdr = get_opthdr_from_block_data(p, cursor, errbuf); |
475 | 1.75k | if (opthdr == NULL) { |
476 | | /* |
477 | | * Option header is cut short. |
478 | | */ |
479 | 0 | return (-1); |
480 | 0 | } |
481 | | |
482 | | /* |
483 | | * Get option value. |
484 | | */ |
485 | 1.75k | optvalue = get_optvalue_from_block_data(cursor, opthdr, |
486 | 1.75k | errbuf); |
487 | 1.75k | if (optvalue == NULL) { |
488 | | /* |
489 | | * Option value is cut short. |
490 | | */ |
491 | 9 | return (-1); |
492 | 9 | } |
493 | | |
494 | 1.74k | switch (opthdr->option_code) { |
495 | | |
496 | 128 | case OPT_ENDOFOPT: |
497 | 128 | if (opthdr->option_length != 0) { |
498 | 2 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
499 | 2 | "Interface Description Block has opt_endofopt option with length %u != 0", |
500 | 2 | opthdr->option_length); |
501 | 2 | return (-1); |
502 | 2 | } |
503 | 126 | goto done; |
504 | | |
505 | 812 | case IF_TSRESOL: |
506 | 812 | if (opthdr->option_length != 1) { |
507 | 5 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
508 | 5 | "Interface Description Block has if_tsresol option with length %u != 1", |
509 | 5 | opthdr->option_length); |
510 | 5 | return (-1); |
511 | 5 | } |
512 | 807 | if (saw_tsresol) { |
513 | 1 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
514 | 1 | "Interface Description Block has more than one if_tsresol option"); |
515 | 1 | return (-1); |
516 | 1 | } |
517 | 806 | saw_tsresol = 1; |
518 | 806 | memcpy(&tsresol_opt, optvalue, sizeof(tsresol_opt)); |
519 | 806 | if (tsresol_opt & 0x80) { |
520 | | /* |
521 | | * Resolution is negative power of 2. |
522 | | */ |
523 | 562 | uint8_t tsresol_shift = (tsresol_opt & 0x7F); |
524 | | |
525 | 562 | if (tsresol_shift > 63) { |
526 | | /* |
527 | | * Resolution is too high; 2^-{res} |
528 | | * won't fit in a 64-bit value. |
529 | | */ |
530 | 4 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
531 | 4 | "Interface Description Block if_tsresol option resolution 2^-%u is too high", |
532 | 4 | tsresol_shift); |
533 | 4 | return (-1); |
534 | 4 | } |
535 | 558 | *is_binary = 1; |
536 | 558 | *tsresol = ((uint64_t)1) << tsresol_shift; |
537 | 558 | } else { |
538 | | /* |
539 | | * Resolution is negative power of 10. |
540 | | */ |
541 | 244 | if (tsresol_opt > 19) { |
542 | | /* |
543 | | * Resolution is too high; 2^-{res} |
544 | | * won't fit in a 64-bit value (the |
545 | | * largest power of 10 that fits |
546 | | * in a 64-bit value is 10^19, as |
547 | | * the largest 64-bit unsigned |
548 | | * value is ~1.8*10^19). |
549 | | */ |
550 | 3 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
551 | 3 | "Interface Description Block if_tsresol option resolution 10^-%u is too high", |
552 | 3 | tsresol_opt); |
553 | 3 | return (-1); |
554 | 3 | } |
555 | 241 | *is_binary = 0; |
556 | 241 | *tsresol = 1; |
557 | 2.23k | for (i = 0; i < tsresol_opt; i++) |
558 | 1.99k | *tsresol *= 10; |
559 | 241 | } |
560 | 799 | break; |
561 | | |
562 | 799 | case IF_TSOFFSET: |
563 | 135 | if (opthdr->option_length != 8) { |
564 | 3 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
565 | 3 | "Interface Description Block has if_tsoffset option with length %u != 8", |
566 | 3 | opthdr->option_length); |
567 | 3 | return (-1); |
568 | 3 | } |
569 | 132 | if (saw_tsoffset) { |
570 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
571 | 0 | "Interface Description Block has more than one if_tsoffset option"); |
572 | 0 | return (-1); |
573 | 0 | } |
574 | 132 | saw_tsoffset = 1; |
575 | 132 | memcpy(tsoffset, optvalue, sizeof(*tsoffset)); |
576 | 132 | if (p->swapped) |
577 | 66 | *tsoffset = SWAPLL(*tsoffset); |
578 | 132 | break; |
579 | | |
580 | 666 | default: |
581 | 666 | break; |
582 | 1.74k | } |
583 | 1.74k | } |
584 | | |
585 | 2.45k | done: |
586 | 2.45k | return (0); |
587 | 2.47k | } |
588 | | |
589 | | static int |
590 | | add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) |
591 | 2.47k | { |
592 | 2.47k | struct pcap_ng_sf *ps; |
593 | 2.47k | uint64_t tsresol; |
594 | 2.47k | uint64_t tsoffset; |
595 | 2.47k | int is_binary; |
596 | | |
597 | 2.47k | ps = p->priv; |
598 | | |
599 | | /* |
600 | | * Count this interface. |
601 | | */ |
602 | 2.47k | ps->ifcount++; |
603 | | |
604 | | /* |
605 | | * Grow the array of per-interface information as necessary. |
606 | | */ |
607 | 2.47k | if (ps->ifcount > ps->ifaces_size) { |
608 | | /* |
609 | | * We need to grow the array. |
610 | | */ |
611 | 1.04k | bpf_u_int32 new_ifaces_size; |
612 | 1.04k | struct pcap_ng_if *new_ifaces; |
613 | | |
614 | 1.04k | if (ps->ifaces_size == 0) { |
615 | | /* |
616 | | * It's currently empty. |
617 | | * |
618 | | * (The Clang static analyzer doesn't do enough, |
619 | | * err, umm, dataflow *analysis* to realize that |
620 | | * ps->ifaces_size == 0 if ps->ifaces == NULL, |
621 | | * and so complains about a possible zero argument |
622 | | * to realloc(), so we check for the former |
623 | | * condition to shut it up. |
624 | | * |
625 | | * However, it doesn't complain that one of the |
626 | | * multiplications below could overflow, which is |
627 | | * a real, albeit extremely unlikely, problem (you'd |
628 | | * need a pcapng file with tens of millions of |
629 | | * interfaces).) |
630 | | */ |
631 | 712 | new_ifaces_size = 1; |
632 | 712 | new_ifaces = malloc(sizeof (struct pcap_ng_if)); |
633 | 712 | } else { |
634 | | /* |
635 | | * It's not currently empty; double its size. |
636 | | * (Perhaps overkill once we have a lot of interfaces.) |
637 | | * |
638 | | * Check for overflow if we double it. |
639 | | */ |
640 | 330 | if (ps->ifaces_size * 2 < ps->ifaces_size) { |
641 | | /* |
642 | | * The maximum number of interfaces before |
643 | | * ps->ifaces_size overflows is the largest |
644 | | * possible 32-bit power of 2, as we do |
645 | | * size doubling. |
646 | | */ |
647 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
648 | 0 | "more than %u interfaces in the file", |
649 | 0 | 0x80000000U); |
650 | 0 | return (0); |
651 | 0 | } |
652 | | |
653 | | /* |
654 | | * ps->ifaces_size * 2 doesn't overflow, so it's |
655 | | * safe to multiply. |
656 | | */ |
657 | 330 | new_ifaces_size = ps->ifaces_size * 2; |
658 | | |
659 | | /* |
660 | | * Now make sure that's not so big that it overflows |
661 | | * if we multiply by sizeof (struct pcap_ng_if). |
662 | | * |
663 | | * That can happen on 32-bit platforms, with a 32-bit |
664 | | * size_t; it shouldn't happen on 64-bit platforms, |
665 | | * with a 64-bit size_t, as new_ifaces_size is |
666 | | * 32 bits. |
667 | | */ |
668 | 330 | if (new_ifaces_size * sizeof (struct pcap_ng_if) < new_ifaces_size) { |
669 | | /* |
670 | | * As this fails only with 32-bit size_t, |
671 | | * the multiplication was 32x32->32, and |
672 | | * the largest 32-bit value that can safely |
673 | | * be multiplied by sizeof (struct pcap_ng_if) |
674 | | * without overflow is the largest 32-bit |
675 | | * (unsigned) value divided by |
676 | | * sizeof (struct pcap_ng_if). |
677 | | */ |
678 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
679 | 0 | "more than %u interfaces in the file", |
680 | 0 | 0xFFFFFFFFU / ((u_int)sizeof (struct pcap_ng_if))); |
681 | 0 | return (0); |
682 | 0 | } |
683 | 330 | new_ifaces = realloc(ps->ifaces, new_ifaces_size * sizeof (struct pcap_ng_if)); |
684 | 330 | } |
685 | 1.04k | if (new_ifaces == NULL) { |
686 | | /* |
687 | | * We ran out of memory. |
688 | | * Give up. |
689 | | */ |
690 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
691 | 0 | "out of memory for per-interface information (%u interfaces)", |
692 | 0 | ps->ifcount); |
693 | 0 | return (0); |
694 | 0 | } |
695 | 1.04k | ps->ifaces_size = new_ifaces_size; |
696 | 1.04k | ps->ifaces = new_ifaces; |
697 | 1.04k | } |
698 | | |
699 | | /* |
700 | | * Set the default time stamp resolution and offset. |
701 | | */ |
702 | 2.47k | tsresol = 1000000; /* microsecond resolution */ |
703 | 2.47k | is_binary = 0; /* which is a power of 10 */ |
704 | 2.47k | tsoffset = 0; /* absolute timestamps */ |
705 | | |
706 | | /* |
707 | | * Now look for various time stamp options, so we know |
708 | | * how to interpret the time stamps for this interface. |
709 | | */ |
710 | 2.47k | if (process_idb_options(p, cursor, &tsresol, &tsoffset, &is_binary, |
711 | 2.47k | errbuf) == -1) |
712 | 27 | return (0); |
713 | | |
714 | 2.45k | ps->ifaces[ps->ifcount - 1].tsresol = tsresol; |
715 | 2.45k | ps->ifaces[ps->ifcount - 1].tsoffset = tsoffset; |
716 | | |
717 | | /* |
718 | | * Determine whether we're scaling up or down or not |
719 | | * at all for this interface. |
720 | | */ |
721 | 2.45k | if (tsresol == ps->user_tsresol) { |
722 | | /* |
723 | | * The resolution is the resolution the user wants, |
724 | | * so we don't have to do scaling. |
725 | | */ |
726 | 1.65k | ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH; |
727 | 1.65k | } else if (tsresol > ps->user_tsresol) { |
728 | | /* |
729 | | * The resolution is greater than what the user wants, |
730 | | * so we have to scale the timestamps down. |
731 | | */ |
732 | 551 | if (is_binary) |
733 | 422 | ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN_BIN; |
734 | 129 | else { |
735 | | /* |
736 | | * Calculate the scale factor. |
737 | | */ |
738 | 129 | ps->ifaces[ps->ifcount - 1].scale_factor = tsresol/ps->user_tsresol; |
739 | 129 | ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN_DEC; |
740 | 129 | } |
741 | 551 | } else { |
742 | | /* |
743 | | * The resolution is less than what the user wants, |
744 | | * so we have to scale the timestamps up. |
745 | | */ |
746 | 242 | if (is_binary) |
747 | 135 | ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP_BIN; |
748 | 107 | else { |
749 | | /* |
750 | | * Calculate the scale factor. |
751 | | */ |
752 | 107 | ps->ifaces[ps->ifcount - 1].scale_factor = ps->user_tsresol/tsresol; |
753 | 107 | ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP_DEC; |
754 | 107 | } |
755 | 242 | } |
756 | 2.45k | return (1); |
757 | 2.47k | } |
758 | | |
759 | | /* |
760 | | * Check whether this is a pcapng savefile and, if it is, extract the |
761 | | * relevant information from the header. |
762 | | */ |
763 | | pcap_t * |
764 | | pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, |
765 | | char *errbuf, int *err) |
766 | 1.88k | { |
767 | 1.88k | bpf_u_int32 magic_int; |
768 | 1.88k | size_t amt_read; |
769 | 1.88k | bpf_u_int32 total_length; |
770 | 1.88k | bpf_u_int32 byte_order_magic; |
771 | 1.88k | struct block_header *bhdrp; |
772 | 1.88k | struct section_header_block *shbp; |
773 | 1.88k | pcap_t *p; |
774 | 1.88k | int swapped = 0; |
775 | 1.88k | struct pcap_ng_sf *ps; |
776 | 1.88k | int status; |
777 | 1.88k | struct block_cursor cursor; |
778 | 1.88k | struct interface_description_block *idbp; |
779 | | |
780 | | /* |
781 | | * Assume no read errors. |
782 | | */ |
783 | 1.88k | *err = 0; |
784 | | |
785 | | /* |
786 | | * Check whether the first 4 bytes of the file are the block |
787 | | * type for a pcapng savefile. |
788 | | */ |
789 | 1.88k | memcpy(&magic_int, magic, sizeof(magic_int)); |
790 | 1.88k | if (magic_int != BT_SHB) { |
791 | | /* |
792 | | * XXX - check whether this looks like what the block |
793 | | * type would be after being munged by mapping between |
794 | | * UN*X and DOS/Windows text file format and, if it |
795 | | * does, look for the byte-order magic number in |
796 | | * the appropriate place and, if we find it, report |
797 | | * this as possibly being a pcapng file transferred |
798 | | * between UN*X and Windows in text file format? |
799 | | */ |
800 | 814 | return (NULL); /* nope */ |
801 | 814 | } |
802 | | |
803 | | /* |
804 | | * OK, they are. However, that's just \n\r\r\n, so it could, |
805 | | * conceivably, be an ordinary text file. |
806 | | * |
807 | | * It could not, however, conceivably be any other type of |
808 | | * capture file, so we can read the rest of the putative |
809 | | * Section Header Block; put the block type in the common |
810 | | * header, read the rest of the common header and the |
811 | | * fixed-length portion of the SHB, and look for the byte-order |
812 | | * magic value. |
813 | | */ |
814 | 1.07k | amt_read = fread(&total_length, 1, sizeof(total_length), fp); |
815 | 1.07k | if (amt_read < sizeof(total_length)) { |
816 | 2 | if (ferror(fp)) { |
817 | 0 | pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, |
818 | 0 | errno, "error reading dump file"); |
819 | 0 | *err = 1; |
820 | 0 | return (NULL); /* fail */ |
821 | 0 | } |
822 | | |
823 | | /* |
824 | | * Possibly a weird short text file, so just say |
825 | | * "not pcapng". |
826 | | */ |
827 | 2 | return (NULL); |
828 | 2 | } |
829 | 1.07k | amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp); |
830 | 1.07k | if (amt_read < sizeof(byte_order_magic)) { |
831 | 1 | if (ferror(fp)) { |
832 | 0 | pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, |
833 | 0 | errno, "error reading dump file"); |
834 | 0 | *err = 1; |
835 | 0 | return (NULL); /* fail */ |
836 | 0 | } |
837 | | |
838 | | /* |
839 | | * Possibly a weird short text file, so just say |
840 | | * "not pcapng". |
841 | | */ |
842 | 1 | return (NULL); |
843 | 1 | } |
844 | 1.07k | if (byte_order_magic != BYTE_ORDER_MAGIC) { |
845 | 224 | byte_order_magic = SWAPLONG(byte_order_magic); |
846 | 224 | if (byte_order_magic != BYTE_ORDER_MAGIC) { |
847 | | /* |
848 | | * Not a pcapng file. |
849 | | */ |
850 | 77 | return (NULL); |
851 | 77 | } |
852 | 147 | swapped = 1; |
853 | 147 | total_length = SWAPLONG(total_length); |
854 | 147 | } |
855 | | |
856 | | /* |
857 | | * Check the sanity of the total length. |
858 | | */ |
859 | 995 | if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer) || |
860 | 995 | (total_length > BT_SHB_INSANE_MAX)) { |
861 | 40 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
862 | 40 | "Section Header Block in pcapng dump file has invalid length %" PRIsize " < _%u_ < %u (BT_SHB_INSANE_MAX)", |
863 | 40 | sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer), |
864 | 40 | total_length, |
865 | 40 | BT_SHB_INSANE_MAX); |
866 | | |
867 | 40 | *err = 1; |
868 | 40 | return (NULL); |
869 | 40 | } |
870 | | |
871 | | /* |
872 | | * OK, this is a good pcapng file. |
873 | | * Allocate a pcap_t for it. |
874 | | */ |
875 | 955 | p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf)); |
876 | 955 | if (p == NULL) { |
877 | | /* Allocation failed. */ |
878 | 0 | *err = 1; |
879 | 0 | return (NULL); |
880 | 0 | } |
881 | 955 | p->swapped = swapped; |
882 | 955 | ps = p->priv; |
883 | | |
884 | | /* |
885 | | * What precision does the user want? |
886 | | */ |
887 | 955 | switch (precision) { |
888 | | |
889 | 955 | case PCAP_TSTAMP_PRECISION_MICRO: |
890 | 955 | ps->user_tsresol = 1000000; |
891 | 955 | break; |
892 | | |
893 | 0 | case PCAP_TSTAMP_PRECISION_NANO: |
894 | 0 | ps->user_tsresol = 1000000000; |
895 | 0 | break; |
896 | | |
897 | 0 | default: |
898 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
899 | 0 | "unknown time stamp resolution %u", precision); |
900 | 0 | free(p); |
901 | 0 | *err = 1; |
902 | 0 | return (NULL); |
903 | 955 | } |
904 | | |
905 | 955 | p->opt.tstamp_precision = precision; |
906 | | |
907 | | /* |
908 | | * Allocate a buffer into which to read blocks. We default to |
909 | | * the maximum of: |
910 | | * |
911 | | * the total length of the SHB for which we read the header; |
912 | | * |
913 | | * 2K, which should be more than large enough for an Enhanced |
914 | | * Packet Block containing a full-size Ethernet frame, and |
915 | | * leaving room for some options. |
916 | | * |
917 | | * If we find a bigger block, we reallocate the buffer, up to |
918 | | * the maximum size. We start out with a maximum size of |
919 | | * INITIAL_MAX_BLOCKSIZE; if we see any link-layer header types |
920 | | * with a maximum snapshot that results in a larger maximum |
921 | | * block length, we boost the maximum. |
922 | | */ |
923 | 955 | p->bufsize = 2048; |
924 | 955 | if (p->bufsize < total_length) |
925 | 45 | p->bufsize = total_length; |
926 | 955 | p->buffer = malloc(p->bufsize); |
927 | 955 | if (p->buffer == NULL) { |
928 | 0 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); |
929 | 0 | free(p); |
930 | 0 | *err = 1; |
931 | 0 | return (NULL); |
932 | 0 | } |
933 | 955 | ps->max_blocksize = INITIAL_MAX_BLOCKSIZE; |
934 | | |
935 | | /* |
936 | | * Copy the stuff we've read to the buffer, and read the rest |
937 | | * of the SHB. |
938 | | */ |
939 | 955 | bhdrp = (struct block_header *)p->buffer; |
940 | 955 | shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header)); |
941 | 955 | bhdrp->block_type = magic_int; |
942 | 955 | bhdrp->total_length = total_length; |
943 | 955 | shbp->byte_order_magic = byte_order_magic; |
944 | 955 | if (read_bytes(fp, |
945 | 955 | (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), |
946 | 955 | total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), |
947 | 955 | 1, errbuf) == -1) |
948 | 58 | goto fail; |
949 | | |
950 | 897 | if (p->swapped) { |
951 | | /* |
952 | | * Byte-swap the fields we've read. |
953 | | */ |
954 | 127 | shbp->major_version = SWAPSHORT(shbp->major_version); |
955 | 127 | shbp->minor_version = SWAPSHORT(shbp->minor_version); |
956 | | |
957 | | /* |
958 | | * XXX - we don't care about the section length. |
959 | | */ |
960 | 127 | } |
961 | | /* currently only SHB version 1.0 is supported */ |
962 | 897 | if (! (shbp->major_version == PCAP_NG_VERSION_MAJOR && |
963 | 897 | shbp->minor_version == PCAP_NG_VERSION_MINOR)) { |
964 | 18 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
965 | 18 | "unsupported pcapng savefile version %u.%u", |
966 | 18 | shbp->major_version, shbp->minor_version); |
967 | 18 | goto fail; |
968 | 18 | } |
969 | 879 | p->version_major = shbp->major_version; |
970 | 879 | p->version_minor = shbp->minor_version; |
971 | | |
972 | | /* |
973 | | * Save the time stamp resolution the user requested. |
974 | | */ |
975 | 879 | p->opt.tstamp_precision = precision; |
976 | | |
977 | | /* |
978 | | * Now start looking for an Interface Description Block. |
979 | | */ |
980 | 1.20k | for (;;) { |
981 | | /* |
982 | | * Read the next block. |
983 | | */ |
984 | 1.20k | status = read_block(fp, p, &cursor, errbuf); |
985 | 1.20k | if (status == 0) { |
986 | | /* EOF - no IDB in this file */ |
987 | 10 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
988 | 10 | "the capture file has no Interface Description Blocks"); |
989 | 10 | goto fail; |
990 | 10 | } |
991 | 1.19k | if (status == -1) |
992 | 152 | goto fail; /* error */ |
993 | 1.04k | switch (cursor.block_type) { |
994 | | |
995 | 714 | case BT_IDB: |
996 | | /* |
997 | | * Get a pointer to the fixed-length portion of the |
998 | | * IDB. |
999 | | */ |
1000 | 714 | idbp = get_from_block_data(&cursor, sizeof(*idbp), |
1001 | 714 | errbuf); |
1002 | 714 | if (idbp == NULL) |
1003 | 2 | goto fail; /* error */ |
1004 | | |
1005 | | /* |
1006 | | * Byte-swap it if necessary. |
1007 | | */ |
1008 | 712 | if (p->swapped) { |
1009 | 95 | idbp->linktype = SWAPSHORT(idbp->linktype); |
1010 | 95 | idbp->snaplen = SWAPLONG(idbp->snaplen); |
1011 | 95 | } |
1012 | | |
1013 | | /* |
1014 | | * Try to add this interface. |
1015 | | */ |
1016 | 712 | if (!add_interface(p, &cursor, errbuf)) |
1017 | 25 | goto fail; |
1018 | | |
1019 | 687 | goto done; |
1020 | | |
1021 | 687 | case BT_EPB: |
1022 | 2 | case BT_SPB: |
1023 | 3 | case BT_PB: |
1024 | | /* |
1025 | | * Saw a packet before we saw any IDBs. That's |
1026 | | * not valid, as we don't know what link-layer |
1027 | | * encapsulation the packet has. |
1028 | | */ |
1029 | 3 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
1030 | 3 | "the capture file has a packet block before any Interface Description Blocks"); |
1031 | 3 | goto fail; |
1032 | | |
1033 | 323 | default: |
1034 | | /* |
1035 | | * Just ignore it. |
1036 | | */ |
1037 | 323 | break; |
1038 | 1.04k | } |
1039 | 1.04k | } |
1040 | | |
1041 | 687 | done: |
1042 | 687 | p->tzoff = 0; /* XXX - not used in pcap */ |
1043 | 687 | p->linktype = linktype_to_dlt(idbp->linktype); |
1044 | 687 | p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen); |
1045 | 687 | p->linktype_ext = 0; |
1046 | | |
1047 | | /* |
1048 | | * If the maximum block size for a packet with the maximum |
1049 | | * snapshot length for this DLT_ is bigger than the current |
1050 | | * maximum block size, increase the maximum. |
1051 | | */ |
1052 | 687 | if (MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize) |
1053 | 9 | ps->max_blocksize = MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)); |
1054 | | |
1055 | 687 | p->next_packet_op = pcap_ng_next_packet; |
1056 | 687 | p->cleanup_op = pcap_ng_cleanup; |
1057 | | |
1058 | 687 | return (p); |
1059 | | |
1060 | 268 | fail: |
1061 | 268 | free(ps->ifaces); |
1062 | 268 | free(p->buffer); |
1063 | 268 | free(p); |
1064 | 268 | *err = 1; |
1065 | 268 | return (NULL); |
1066 | 879 | } |
1067 | | |
1068 | | static void |
1069 | | pcap_ng_cleanup(pcap_t *p) |
1070 | 687 | { |
1071 | 687 | struct pcap_ng_sf *ps = p->priv; |
1072 | | |
1073 | 687 | free(ps->ifaces); |
1074 | 687 | sf_cleanup(p); |
1075 | 687 | } |
1076 | | |
1077 | | /* |
1078 | | * Read and return the next packet from the savefile. Return the header |
1079 | | * in hdr and a pointer to the contents in data. Return 0 on success, 1 |
1080 | | * if there were no more packets, and -1 on an error. |
1081 | | */ |
1082 | | static int |
1083 | | pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) |
1084 | 3.26k | { |
1085 | 3.26k | struct pcap_ng_sf *ps = p->priv; |
1086 | 3.26k | struct block_cursor cursor; |
1087 | 3.26k | int status; |
1088 | 3.26k | struct enhanced_packet_block *epbp; |
1089 | 3.26k | struct simple_packet_block *spbp; |
1090 | 3.26k | struct packet_block *pbp; |
1091 | 3.26k | bpf_u_int32 interface_id = 0xFFFFFFFF; |
1092 | 3.26k | struct interface_description_block *idbp; |
1093 | 3.26k | struct section_header_block *shbp; |
1094 | 3.26k | FILE *fp = p->rfile; |
1095 | 3.26k | uint64_t t, sec, frac; |
1096 | | |
1097 | | /* |
1098 | | * Look for an Enhanced Packet Block, a Simple Packet Block, |
1099 | | * or a Packet Block. |
1100 | | */ |
1101 | 5.56k | for (;;) { |
1102 | | /* |
1103 | | * Read the block type and length; those are common |
1104 | | * to all blocks. |
1105 | | */ |
1106 | 5.56k | status = read_block(fp, p, &cursor, p->errbuf); |
1107 | 5.56k | if (status == 0) |
1108 | 223 | return (1); /* EOF */ |
1109 | 5.34k | if (status == -1) |
1110 | 116 | return (-1); /* error */ |
1111 | 5.22k | switch (cursor.block_type) { |
1112 | | |
1113 | 1.43k | case BT_EPB: |
1114 | | /* |
1115 | | * Get a pointer to the fixed-length portion of the |
1116 | | * EPB. |
1117 | | */ |
1118 | 1.43k | epbp = get_from_block_data(&cursor, sizeof(*epbp), |
1119 | 1.43k | p->errbuf); |
1120 | 1.43k | if (epbp == NULL) |
1121 | 1 | return (-1); /* error */ |
1122 | | |
1123 | | /* |
1124 | | * Byte-swap it if necessary. |
1125 | | */ |
1126 | 1.43k | if (p->swapped) { |
1127 | | /* these were written in opposite byte order */ |
1128 | 43 | interface_id = SWAPLONG(epbp->interface_id); |
1129 | 43 | hdr->caplen = SWAPLONG(epbp->caplen); |
1130 | 43 | hdr->len = SWAPLONG(epbp->len); |
1131 | 43 | t = ((uint64_t)SWAPLONG(epbp->timestamp_high)) << 32 | |
1132 | 43 | SWAPLONG(epbp->timestamp_low); |
1133 | 1.39k | } else { |
1134 | 1.39k | interface_id = epbp->interface_id; |
1135 | 1.39k | hdr->caplen = epbp->caplen; |
1136 | 1.39k | hdr->len = epbp->len; |
1137 | 1.39k | t = ((uint64_t)epbp->timestamp_high) << 32 | |
1138 | 1.39k | epbp->timestamp_low; |
1139 | 1.39k | } |
1140 | 1.43k | goto found; |
1141 | | |
1142 | 1.17k | case BT_SPB: |
1143 | | /* |
1144 | | * Get a pointer to the fixed-length portion of the |
1145 | | * SPB. |
1146 | | */ |
1147 | 1.17k | spbp = get_from_block_data(&cursor, sizeof(*spbp), |
1148 | 1.17k | p->errbuf); |
1149 | 1.17k | if (spbp == NULL) |
1150 | 1 | return (-1); /* error */ |
1151 | | |
1152 | | /* |
1153 | | * SPB packets are assumed to have arrived on |
1154 | | * the first interface. |
1155 | | */ |
1156 | 1.17k | interface_id = 0; |
1157 | | |
1158 | | /* |
1159 | | * Byte-swap it if necessary. |
1160 | | */ |
1161 | 1.17k | if (p->swapped) { |
1162 | | /* these were written in opposite byte order */ |
1163 | 230 | hdr->len = SWAPLONG(spbp->len); |
1164 | 230 | } else |
1165 | 947 | hdr->len = spbp->len; |
1166 | | |
1167 | | /* |
1168 | | * The SPB doesn't give the captured length; |
1169 | | * it's the minimum of the snapshot length |
1170 | | * and the packet length. |
1171 | | */ |
1172 | 1.17k | hdr->caplen = hdr->len; |
1173 | 1.17k | if (hdr->caplen > (bpf_u_int32)p->snapshot) |
1174 | 422 | hdr->caplen = p->snapshot; |
1175 | 1.17k | t = 0; /* no time stamps */ |
1176 | 1.17k | goto found; |
1177 | | |
1178 | 88 | case BT_PB: |
1179 | | /* |
1180 | | * Get a pointer to the fixed-length portion of the |
1181 | | * PB. |
1182 | | */ |
1183 | 88 | pbp = get_from_block_data(&cursor, sizeof(*pbp), |
1184 | 88 | p->errbuf); |
1185 | 88 | if (pbp == NULL) |
1186 | 2 | return (-1); /* error */ |
1187 | | |
1188 | | /* |
1189 | | * Byte-swap it if necessary. |
1190 | | */ |
1191 | 86 | if (p->swapped) { |
1192 | | /* these were written in opposite byte order */ |
1193 | 12 | interface_id = SWAPSHORT(pbp->interface_id); |
1194 | 12 | hdr->caplen = SWAPLONG(pbp->caplen); |
1195 | 12 | hdr->len = SWAPLONG(pbp->len); |
1196 | 12 | t = ((uint64_t)SWAPLONG(pbp->timestamp_high)) << 32 | |
1197 | 12 | SWAPLONG(pbp->timestamp_low); |
1198 | 74 | } else { |
1199 | 74 | interface_id = pbp->interface_id; |
1200 | 74 | hdr->caplen = pbp->caplen; |
1201 | 74 | hdr->len = pbp->len; |
1202 | 74 | t = ((uint64_t)pbp->timestamp_high) << 32 | |
1203 | 74 | pbp->timestamp_low; |
1204 | 74 | } |
1205 | 86 | goto found; |
1206 | | |
1207 | 1.81k | case BT_IDB: |
1208 | | /* |
1209 | | * Interface Description Block. Get a pointer |
1210 | | * to its fixed-length portion. |
1211 | | */ |
1212 | 1.81k | idbp = get_from_block_data(&cursor, sizeof(*idbp), |
1213 | 1.81k | p->errbuf); |
1214 | 1.81k | if (idbp == NULL) |
1215 | 2 | return (-1); /* error */ |
1216 | | |
1217 | | /* |
1218 | | * Byte-swap it if necessary. |
1219 | | */ |
1220 | 1.81k | if (p->swapped) { |
1221 | 620 | idbp->linktype = SWAPSHORT(idbp->linktype); |
1222 | 620 | idbp->snaplen = SWAPLONG(idbp->snaplen); |
1223 | 620 | } |
1224 | | |
1225 | | /* |
1226 | | * If the link-layer type or snapshot length |
1227 | | * differ from the ones for the first IDB we |
1228 | | * saw, quit. |
1229 | | * |
1230 | | * XXX - just discard packets from those |
1231 | | * interfaces? |
1232 | | */ |
1233 | 1.81k | if (p->linktype != idbp->linktype) { |
1234 | 2 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1235 | 2 | "an interface has a type %u different from the type of the first interface", |
1236 | 2 | idbp->linktype); |
1237 | 2 | return (-1); |
1238 | 2 | } |
1239 | | |
1240 | | /* |
1241 | | * Check against the *adjusted* value of this IDB's |
1242 | | * snapshot length. |
1243 | | */ |
1244 | 1.81k | if ((bpf_u_int32)p->snapshot != |
1245 | 1.81k | pcap_adjust_snapshot(p->linktype, idbp->snaplen)) { |
1246 | 47 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1247 | 47 | "an interface has a snapshot length %u different from the type of the first interface", |
1248 | 47 | idbp->snaplen); |
1249 | 47 | return (-1); |
1250 | 47 | } |
1251 | | |
1252 | | /* |
1253 | | * Try to add this interface. |
1254 | | */ |
1255 | 1.76k | if (!add_interface(p, &cursor, p->errbuf)) |
1256 | 2 | return (-1); |
1257 | 1.76k | break; |
1258 | | |
1259 | 1.76k | case BT_SHB: |
1260 | | /* |
1261 | | * Section Header Block. Get a pointer |
1262 | | * to its fixed-length portion. |
1263 | | */ |
1264 | 427 | shbp = get_from_block_data(&cursor, sizeof(*shbp), |
1265 | 427 | p->errbuf); |
1266 | 427 | if (shbp == NULL) |
1267 | 2 | return (-1); /* error */ |
1268 | | |
1269 | | /* |
1270 | | * Assume the byte order of this section is |
1271 | | * the same as that of the previous section. |
1272 | | * We'll check for that later. |
1273 | | */ |
1274 | 425 | if (p->swapped) { |
1275 | 72 | shbp->byte_order_magic = |
1276 | 72 | SWAPLONG(shbp->byte_order_magic); |
1277 | 72 | shbp->major_version = |
1278 | 72 | SWAPSHORT(shbp->major_version); |
1279 | 72 | } |
1280 | | |
1281 | | /* |
1282 | | * Make sure the byte order doesn't change; |
1283 | | * pcap_is_swapped() shouldn't change its |
1284 | | * return value in the middle of reading a capture. |
1285 | | */ |
1286 | 425 | switch (shbp->byte_order_magic) { |
1287 | | |
1288 | 272 | case BYTE_ORDER_MAGIC: |
1289 | | /* |
1290 | | * OK. |
1291 | | */ |
1292 | 272 | break; |
1293 | | |
1294 | 1 | case SWAPLONG(BYTE_ORDER_MAGIC): |
1295 | | /* |
1296 | | * Byte order changes. |
1297 | | */ |
1298 | 1 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1299 | 1 | "the file has sections with different byte orders"); |
1300 | 1 | return (-1); |
1301 | | |
1302 | 152 | default: |
1303 | | /* |
1304 | | * Not a valid SHB. |
1305 | | */ |
1306 | 152 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1307 | 152 | "the file has a section with a bad byte order magic field"); |
1308 | 152 | return (-1); |
1309 | 425 | } |
1310 | | |
1311 | | /* |
1312 | | * Make sure the major version is the version |
1313 | | * we handle. |
1314 | | */ |
1315 | 272 | if (shbp->major_version != PCAP_NG_VERSION_MAJOR) { |
1316 | 11 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1317 | 11 | "unknown pcapng savefile major version number %u", |
1318 | 11 | shbp->major_version); |
1319 | 11 | return (-1); |
1320 | 11 | } |
1321 | | |
1322 | | /* |
1323 | | * Reset the interface count; this section should |
1324 | | * have its own set of IDBs. If any of them |
1325 | | * don't have the same interface type, snapshot |
1326 | | * length, or resolution as the first interface |
1327 | | * we saw, we'll fail. (And if we don't see |
1328 | | * any IDBs, we'll fail when we see a packet |
1329 | | * block.) |
1330 | | */ |
1331 | 261 | ps->ifcount = 0; |
1332 | 261 | break; |
1333 | | |
1334 | 282 | default: |
1335 | | /* |
1336 | | * Not a packet block, IDB, or SHB; ignore it. |
1337 | | */ |
1338 | 282 | break; |
1339 | 5.22k | } |
1340 | 5.22k | } |
1341 | | |
1342 | 2.69k | found: |
1343 | | /* |
1344 | | * Is the interface ID an interface we know? |
1345 | | */ |
1346 | 2.69k | if (interface_id >= ps->ifcount) { |
1347 | | /* |
1348 | | * Yes. Fail. |
1349 | | */ |
1350 | 45 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1351 | 45 | "a packet arrived on interface %u, but there's no Interface Description Block for that interface", |
1352 | 45 | interface_id); |
1353 | 45 | return (-1); |
1354 | 45 | } |
1355 | | |
1356 | 2.65k | if (hdr->caplen > (bpf_u_int32)p->snapshot) { |
1357 | 23 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
1358 | 23 | "invalid packet capture length %u, bigger than " |
1359 | 23 | "snaplen of %d", hdr->caplen, p->snapshot); |
1360 | 23 | return (-1); |
1361 | 23 | } |
1362 | | |
1363 | | /* |
1364 | | * Convert the time stamp to seconds and fractions of a second, |
1365 | | * with the fractions being in units of the file-supplied resolution. |
1366 | | */ |
1367 | 2.63k | sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset; |
1368 | 2.63k | frac = t % ps->ifaces[interface_id].tsresol; |
1369 | | |
1370 | | /* |
1371 | | * Convert the fractions from units of the file-supplied resolution |
1372 | | * to units of the user-requested resolution. |
1373 | | */ |
1374 | 2.63k | switch (ps->ifaces[interface_id].scale_type) { |
1375 | | |
1376 | 1.55k | case PASS_THROUGH: |
1377 | | /* |
1378 | | * The interface resolution is what the user wants, |
1379 | | * so we're done. |
1380 | | */ |
1381 | 1.55k | break; |
1382 | | |
1383 | 107 | case SCALE_UP_DEC: |
1384 | | /* |
1385 | | * The interface resolution is less than what the user |
1386 | | * wants; scale the fractional part up to the units of |
1387 | | * the resolution the user requested by multiplying by |
1388 | | * the quotient of the user-requested resolution and the |
1389 | | * file-supplied resolution. |
1390 | | * |
1391 | | * Those resolutions are both powers of 10, and the user- |
1392 | | * requested resolution is greater than the file-supplied |
1393 | | * resolution, so the quotient in question is an integer. |
1394 | | * We've calculated that quotient already, so we just |
1395 | | * multiply by it. |
1396 | | */ |
1397 | 107 | frac *= ps->ifaces[interface_id].scale_factor; |
1398 | 107 | break; |
1399 | | |
1400 | 195 | case SCALE_UP_BIN: |
1401 | | /* |
1402 | | * The interface resolution is less than what the user |
1403 | | * wants; scale the fractional part up to the units of |
1404 | | * the resolution the user requested by multiplying by |
1405 | | * the quotient of the user-requested resolution and the |
1406 | | * file-supplied resolution. |
1407 | | * |
1408 | | * The file-supplied resolution is a power of 2, so the |
1409 | | * quotient is not an integer, so, in order to do this |
1410 | | * entirely with integer arithmetic, we multiply by the |
1411 | | * user-requested resolution and divide by the file- |
1412 | | * supplied resolution. |
1413 | | * |
1414 | | * XXX - Is there something clever we could do here, |
1415 | | * given that we know that the file-supplied resolution |
1416 | | * is a power of 2? Doing a multiplication followed by |
1417 | | * a division runs the risk of overflowing, and involves |
1418 | | * two non-simple arithmetic operations. |
1419 | | */ |
1420 | 195 | frac *= ps->user_tsresol; |
1421 | 195 | frac /= ps->ifaces[interface_id].tsresol; |
1422 | 195 | break; |
1423 | | |
1424 | 426 | case SCALE_DOWN_DEC: |
1425 | | /* |
1426 | | * The interface resolution is greater than what the user |
1427 | | * wants; scale the fractional part up to the units of |
1428 | | * the resolution the user requested by multiplying by |
1429 | | * the quotient of the user-requested resolution and the |
1430 | | * file-supplied resolution. |
1431 | | * |
1432 | | * Those resolutions are both powers of 10, and the user- |
1433 | | * requested resolution is less than the file-supplied |
1434 | | * resolution, so the quotient in question isn't an |
1435 | | * integer, but its reciprocal is, and we can just divide |
1436 | | * by the reciprocal of the quotient. We've calculated |
1437 | | * the reciprocal of that quotient already, so we must |
1438 | | * divide by it. |
1439 | | */ |
1440 | 426 | frac /= ps->ifaces[interface_id].scale_factor; |
1441 | 426 | break; |
1442 | | |
1443 | | |
1444 | 345 | case SCALE_DOWN_BIN: |
1445 | | /* |
1446 | | * The interface resolution is greater than what the user |
1447 | | * wants; convert the fractional part to units of the |
1448 | | * resolution the user requested by multiplying by the |
1449 | | * quotient of the user-requested resolution and the |
1450 | | * file-supplied resolution. We do that by multiplying |
1451 | | * by the user-requested resolution and dividing by the |
1452 | | * file-supplied resolution, as the quotient might not |
1453 | | * fit in an integer. |
1454 | | * |
1455 | | * The file-supplied resolution is a power of 2, so the |
1456 | | * quotient is not an integer, and neither is its |
1457 | | * reciprocal, so, in order to do this entirely with |
1458 | | * integer arithmetic, we multiply by the user-requested |
1459 | | * resolution and divide by the file-supplied resolution. |
1460 | | * |
1461 | | * XXX - Is there something clever we could do here, |
1462 | | * given that we know that the file-supplied resolution |
1463 | | * is a power of 2? Doing a multiplication followed by |
1464 | | * a division runs the risk of overflowing, and involves |
1465 | | * two non-simple arithmetic operations. |
1466 | | */ |
1467 | 345 | frac *= ps->user_tsresol; |
1468 | 345 | frac /= ps->ifaces[interface_id].tsresol; |
1469 | 345 | break; |
1470 | 2.63k | } |
1471 | | #ifdef _WIN32 |
1472 | | /* |
1473 | | * tv_sec and tv_used in the Windows struct timeval are both |
1474 | | * longs. |
1475 | | */ |
1476 | | hdr->ts.tv_sec = (long)sec; |
1477 | | hdr->ts.tv_usec = (long)frac; |
1478 | | #else |
1479 | | /* |
1480 | | * tv_sec in the UN*X struct timeval is a time_t; tv_usec is |
1481 | | * suseconds_t in UN*Xes that work the way the current Single |
1482 | | * UNIX Standard specify - but not all older UN*Xes necessarily |
1483 | | * support that type, so just cast to int. |
1484 | | */ |
1485 | 2.63k | hdr->ts.tv_sec = (time_t)sec; |
1486 | 2.63k | hdr->ts.tv_usec = (int)frac; |
1487 | 2.63k | #endif |
1488 | | |
1489 | | /* |
1490 | | * Get a pointer to the packet data. |
1491 | | */ |
1492 | 2.63k | *data = get_from_block_data(&cursor, hdr->caplen, p->errbuf); |
1493 | 2.63k | if (*data == NULL) |
1494 | 57 | return (-1); |
1495 | | |
1496 | 2.57k | if (p->swapped) |
1497 | 274 | swap_pseudo_headers(p->linktype, hdr, *data); |
1498 | | |
1499 | 2.57k | return (0); |
1500 | 2.63k | } |