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