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