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