xref: /minix3/external/bsd/libpcap/dist/sf-pcap-ng.c (revision d56f51ea7d8b9045e5c8e2028422523d3f9a5840)
1 /*	$NetBSD: sf-pcap-ng.c,v 1.6 2015/03/31 21:39:42 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1993, 1994, 1995, 1996, 1997
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  *
23  * sf-pcap-ng.c - pcap-ng-file-format-specific code from savefile.c
24  */
25 
26 #ifndef lint
27 static const char rcsid[] _U_ =
28     "@(#) Header (LBL)";
29 #endif
30 
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: sf-pcap-ng.c,v 1.6 2015/03/31 21:39:42 christos Exp $");
33 
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37 
38 #ifdef WIN32
39 #include <pcap-stdinc.h>
40 #else /* WIN32 */
41 #if HAVE_INTTYPES_H
42 #include <inttypes.h>
43 #elif HAVE_STDINT_H
44 #include <stdint.h>
45 #endif
46 #ifdef HAVE_SYS_BITYPES_H
47 #include <sys/bitypes.h>
48 #endif
49 #include <sys/types.h>
50 #endif /* WIN32 */
51 
52 #include <errno.h>
53 #include <memory.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 
58 #include "pcap-int.h"
59 
60 #include "pcap-common.h"
61 
62 #ifdef HAVE_OS_PROTO_H
63 #include "os-proto.h"
64 #endif
65 
66 #include "sf-pcap-ng.h"
67 
68 /*
69  * Block types.
70  */
71 
72 /*
73  * Common part at the beginning of all blocks.
74  */
75 struct block_header {
76 	bpf_u_int32	block_type;
77 	bpf_u_int32	total_length;
78 };
79 
80 /*
81  * Common trailer at the end of all blocks.
82  */
83 struct block_trailer {
84 	bpf_u_int32	total_length;
85 };
86 
87 /*
88  * Common options.
89  */
90 #define OPT_ENDOFOPT	0	/* end of options */
91 #define OPT_COMMENT	1	/* comment string */
92 
93 /*
94  * Option header.
95  */
96 struct option_header {
97 	u_short		option_code;
98 	u_short		option_length;
99 };
100 
101 /*
102  * Structures for the part of each block type following the common
103  * part.
104  */
105 
106 /*
107  * Section Header Block.
108  */
109 #define BT_SHB			0x0A0D0D0A
110 
111 struct section_header_block {
112 	bpf_u_int32	byte_order_magic;
113 	u_short		major_version;
114 	u_short		minor_version;
115 	u_int64_t	section_length;
116 	/* followed by options and trailer */
117 };
118 
119 /*
120  * Byte-order magic value.
121  */
122 #define BYTE_ORDER_MAGIC	0x1A2B3C4D
123 
124 /*
125  * Current version number.  If major_version isn't PCAP_NG_VERSION_MAJOR,
126  * that means that this code can't read the file.
127  */
128 #define PCAP_NG_VERSION_MAJOR	1
129 
130 /*
131  * Interface Description Block.
132  */
133 #define BT_IDB			0x00000001
134 
135 struct interface_description_block {
136 	u_short		linktype;
137 	u_short		reserved;
138 	bpf_u_int32	snaplen;
139 	/* followed by options and trailer */
140 };
141 
142 /*
143  * Options in the IDB.
144  */
145 #define IF_NAME		2	/* interface name string */
146 #define IF_DESCRIPTION	3	/* interface description string */
147 #define IF_IPV4ADDR	4	/* interface's IPv4 address and netmask */
148 #define IF_IPV6ADDR	5	/* interface's IPv6 address and prefix length */
149 #define IF_MACADDR	6	/* interface's MAC address */
150 #define IF_EUIADDR	7	/* interface's EUI address */
151 #define IF_SPEED	8	/* interface's speed, in bits/s */
152 #define IF_TSRESOL	9	/* interface's time stamp resolution */
153 #define IF_TZONE	10	/* interface's time zone */
154 #define IF_FILTER	11	/* filter used when capturing on interface */
155 #define IF_OS		12	/* string OS on which capture on this interface was done */
156 #define IF_FCSLEN	13	/* FCS length for this interface */
157 #define IF_TSOFFSET	14	/* time stamp offset for this interface */
158 
159 /*
160  * Enhanced Packet Block.
161  */
162 #define BT_EPB			0x00000006
163 
164 struct enhanced_packet_block {
165 	bpf_u_int32	interface_id;
166 	bpf_u_int32	timestamp_high;
167 	bpf_u_int32	timestamp_low;
168 	bpf_u_int32	caplen;
169 	bpf_u_int32	len;
170 	/* followed by packet data, options, and trailer */
171 };
172 
173 /*
174  * Simple Packet Block.
175  */
176 #define BT_SPB			0x00000003
177 
178 struct simple_packet_block {
179 	bpf_u_int32	len;
180 	/* followed by packet data and trailer */
181 };
182 
183 /*
184  * Packet Block.
185  */
186 #define BT_PB			0x00000002
187 
188 struct packet_block {
189 	u_short		interface_id;
190 	u_short		drops_count;
191 	bpf_u_int32	timestamp_high;
192 	bpf_u_int32	timestamp_low;
193 	bpf_u_int32	caplen;
194 	bpf_u_int32	len;
195 	/* followed by packet data, options, and trailer */
196 };
197 
198 /*
199  * Block cursor - used when processing the contents of a block.
200  * Contains a pointer into the data being processed and a count
201  * of bytes remaining in the block.
202  */
203 struct block_cursor {
204 	u_char		*data;
205 	size_t		data_remaining;
206 	bpf_u_int32	block_type;
207 };
208 
209 typedef enum {
210 	PASS_THROUGH,
211 	SCALE_UP,
212 	SCALE_DOWN
213 } tstamp_scale_type_t;
214 
215 /*
216  * Per-interface information.
217  */
218 struct pcap_ng_if {
219 	u_int tsresol;			/* time stamp resolution */
220 	u_int64_t tsoffset;		/* time stamp offset */
221 	tstamp_scale_type_t scale_type;	/* how to scale */
222 };
223 
224 struct pcap_ng_sf {
225 	u_int user_tsresol;		/* time stamp resolution requested by the user */
226 	bpf_u_int32 ifcount;		/* number of interfaces seen in this capture */
227 	bpf_u_int32 ifaces_size;	/* size of arrary below */
228 	struct pcap_ng_if *ifaces;	/* array of interface information */
229 };
230 
231 static void pcap_ng_cleanup(pcap_t *p);
232 static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
233     u_char **data);
234 
235 static int
read_bytes(FILE * fp,void * buf,size_t bytes_to_read,int fail_on_eof,char * errbuf)236 read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
237     char *errbuf)
238 {
239 	size_t amt_read;
240 
241 	amt_read = fread(buf, 1, bytes_to_read, fp);
242 	if (amt_read != bytes_to_read) {
243 		if (ferror(fp)) {
244 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
245 			    "error reading dump file: %s",
246 			    pcap_strerror(errno));
247 		} else {
248 			if (amt_read == 0 && !fail_on_eof)
249 				return (0);	/* EOF */
250 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
251 			    "truncated dump file; tried to read %lu bytes, only got %lu",
252 			    (unsigned long)bytes_to_read,
253 			    (unsigned long)amt_read);
254 		}
255 		return (-1);
256 	}
257 	return (1);
258 }
259 
260 static int
read_block(FILE * fp,pcap_t * p,struct block_cursor * cursor,char * errbuf)261 read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
262 {
263 	int status;
264 	struct block_header bhdr;
265 
266 	status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf);
267 	if (status <= 0)
268 		return (status);	/* error or EOF */
269 
270 	if (p->swapped) {
271 		bhdr.block_type = SWAPLONG(bhdr.block_type);
272 		bhdr.total_length = SWAPLONG(bhdr.total_length);
273 	}
274 
275 	/*
276 	 * Is this block "too big"?
277 	 *
278 	 * We choose 16MB as "too big", for now, so that we handle
279 	 * "reasonably" large buffers but don't chew up all the
280 	 * memory if we read a malformed file.
281 	 */
282 	if (bhdr.total_length > 16*1024*1024) {
283 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
284 		    "pcap-ng block size %u > maximum %u",
285 		    bhdr.total_length, 16*1024*1024);
286 		    return (-1);
287 	}
288 
289 	/*
290 	 * Is this block "too small" - i.e., is it shorter than a block
291 	 * header plus a block trailer?
292 	 */
293 	if (bhdr.total_length < sizeof(struct block_header) +
294 	    sizeof(struct block_trailer)) {
295 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
296 		    "block in pcap-ng dump file has a length of %u < %lu",
297 		    bhdr.total_length,
298 		    (unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
299 		return (-1);
300 	}
301 
302 	/*
303 	 * Is the buffer big enough?
304 	 */
305 	if (p->bufsize < (int)bhdr.total_length) {
306 		/*
307 		 * No - make it big enough.
308 		 */
309 		p->buffer = realloc(p->buffer, bhdr.total_length);
310 		if (p->buffer == NULL) {
311 			snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
312 			return (-1);
313 		}
314 	}
315 
316 	/*
317 	 * Copy the stuff we've read to the buffer, and read the rest
318 	 * of the block.
319 	 */
320 	memcpy(p->buffer, &bhdr, sizeof(bhdr));
321 	if (read_bytes(fp, p->buffer + sizeof(bhdr),
322 	    bhdr.total_length - sizeof(bhdr), 1, errbuf) == -1)
323 		return (-1);
324 
325 	/*
326 	 * Initialize the cursor.
327 	 */
328 	cursor->data = p->buffer + sizeof(bhdr);
329 	cursor->data_remaining = bhdr.total_length - sizeof(bhdr) -
330 	    sizeof(struct block_trailer);
331 	cursor->block_type = bhdr.block_type;
332 	return (1);
333 }
334 
335 static void *
get_from_block_data(struct block_cursor * cursor,size_t chunk_size,char * errbuf)336 get_from_block_data(struct block_cursor *cursor, size_t chunk_size,
337     char *errbuf)
338 {
339 	void *data;
340 
341 	/*
342 	 * Make sure we have the specified amount of data remaining in
343 	 * the block data.
344 	 */
345 	if (cursor->data_remaining < chunk_size) {
346 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
347 		    "block of type %u in pcap-ng dump file is too short",
348 		    cursor->block_type);
349 		return (NULL);
350 	}
351 
352 	/*
353 	 * Return the current pointer, and skip past the chunk.
354 	 */
355 	data = cursor->data;
356 	cursor->data += chunk_size;
357 	cursor->data_remaining -= chunk_size;
358 	return (data);
359 }
360 
361 static struct option_header *
get_opthdr_from_block_data(pcap_t * p,struct block_cursor * cursor,char * errbuf)362 get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf)
363 {
364 	struct option_header *opthdr;
365 
366 	opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf);
367 	if (opthdr == NULL) {
368 		/*
369 		 * Option header is cut short.
370 		 */
371 		return (NULL);
372 	}
373 
374 	/*
375 	 * Byte-swap it if necessary.
376 	 */
377 	if (p->swapped) {
378 		opthdr->option_code = SWAPSHORT(opthdr->option_code);
379 		opthdr->option_length = SWAPSHORT((uint32_t)opthdr->option_length);
380 	}
381 
382 	return (opthdr);
383 }
384 
385 static void *
get_optvalue_from_block_data(struct block_cursor * cursor,struct option_header * opthdr,char * errbuf)386 get_optvalue_from_block_data(struct block_cursor *cursor,
387     struct option_header *opthdr, char *errbuf)
388 {
389 	size_t padded_option_len;
390 	void *optvalue;
391 
392 	/* Pad option length to 4-byte boundary */
393 	padded_option_len = opthdr->option_length;
394 	padded_option_len = ((padded_option_len + 3)/4)*4;
395 
396 	optvalue = get_from_block_data(cursor, padded_option_len, errbuf);
397 	if (optvalue == NULL) {
398 		/*
399 		 * Option value is cut short.
400 		 */
401 		return (NULL);
402 	}
403 
404 	return (optvalue);
405 }
406 
407 static int
process_idb_options(pcap_t * p,struct block_cursor * cursor,u_int * tsresol,u_int64_t * tsoffset,char * errbuf)408 process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
409     u_int64_t *tsoffset, char *errbuf)
410 {
411 	struct option_header *opthdr;
412 	void *optvalue;
413 	int saw_tsresol, saw_tsoffset;
414 	u_char tsresol_opt;
415 	u_int i;
416 
417 	saw_tsresol = 0;
418 	saw_tsoffset = 0;
419 	while (cursor->data_remaining != 0) {
420 		/*
421 		 * Get the option header.
422 		 */
423 		opthdr = get_opthdr_from_block_data(p, cursor, errbuf);
424 		if (opthdr == NULL) {
425 			/*
426 			 * Option header is cut short.
427 			 */
428 			return (-1);
429 		}
430 
431 		/*
432 		 * Get option value.
433 		 */
434 		optvalue = get_optvalue_from_block_data(cursor, opthdr,
435 		    errbuf);
436 		if (optvalue == NULL) {
437 			/*
438 			 * Option value is cut short.
439 			 */
440 			return (-1);
441 		}
442 
443 		switch (opthdr->option_code) {
444 
445 		case OPT_ENDOFOPT:
446 			if (opthdr->option_length != 0) {
447 				snprintf(errbuf, PCAP_ERRBUF_SIZE,
448 				    "Interface Description Block has opt_endofopt option with length %u != 0",
449 				    opthdr->option_length);
450 				return (-1);
451 			}
452 			goto done;
453 
454 		case IF_TSRESOL:
455 			if (opthdr->option_length != 1) {
456 				snprintf(errbuf, PCAP_ERRBUF_SIZE,
457 				    "Interface Description Block has if_tsresol option with length %u != 1",
458 				    opthdr->option_length);
459 				return (-1);
460 			}
461 			if (saw_tsresol) {
462 				snprintf(errbuf, PCAP_ERRBUF_SIZE,
463 				    "Interface Description Block has more than one if_tsresol option");
464 				return (-1);
465 			}
466 			saw_tsresol = 1;
467 			memcpy(&tsresol_opt, optvalue, sizeof(tsresol_opt));
468 			if (tsresol_opt & 0x80) {
469 				/*
470 				 * Resolution is negative power of 2.
471 				 */
472 				*tsresol = 1 << (tsresol_opt & 0x7F);
473 			} else {
474 				/*
475 				 * Resolution is negative power of 10.
476 				 */
477 				*tsresol = 1;
478 				for (i = 0; i < tsresol_opt; i++)
479 					*tsresol *= 10;
480 			}
481 			if (*tsresol == 0) {
482 				/*
483 				 * Resolution is too high.
484 				 */
485 				if (tsresol_opt & 0x80) {
486 					snprintf(errbuf, PCAP_ERRBUF_SIZE,
487 					    "Interface Description Block if_tsresol option resolution 2^-%u is too high",
488 					    tsresol_opt & 0x7F);
489 				} else {
490 					snprintf(errbuf, PCAP_ERRBUF_SIZE,
491 					    "Interface Description Block if_tsresol option resolution 10^-%u is too high",
492 					    tsresol_opt);
493 				}
494 				return (-1);
495 			}
496 			break;
497 
498 		case IF_TSOFFSET:
499 			if (opthdr->option_length != 8) {
500 				snprintf(errbuf, PCAP_ERRBUF_SIZE,
501 				    "Interface Description Block has if_tsoffset option with length %u != 8",
502 				    opthdr->option_length);
503 				return (-1);
504 			}
505 			if (saw_tsoffset) {
506 				snprintf(errbuf, PCAP_ERRBUF_SIZE,
507 				    "Interface Description Block has more than one if_tsoffset option");
508 				return (-1);
509 			}
510 			saw_tsoffset = 1;
511 			memcpy(tsoffset, optvalue, sizeof(*tsoffset));
512 			if (p->swapped)
513 				*tsoffset = (uint64_t)SWAPLL(*tsoffset);
514 			break;
515 
516 		default:
517 			break;
518 		}
519 	}
520 
521 done:
522 	return (0);
523 }
524 
525 static int
add_interface(pcap_t * p,struct block_cursor * cursor,char * errbuf)526 add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
527 {
528 	struct pcap_ng_sf *ps;
529 	u_int tsresol;
530 	u_int64_t tsoffset;
531 
532 	ps = p->priv;
533 
534 	/*
535 	 * Count this interface.
536 	 */
537 	ps->ifcount++;
538 
539 	/*
540 	 * Grow the array of per-interface information as necessary.
541 	 */
542 	if (ps->ifcount > ps->ifaces_size) {
543 		/*
544 		 * We need to grow the array.
545 		 */
546 		if (ps->ifaces == NULL) {
547 			/*
548 			 * It's currently empty.
549 			 */
550 			ps->ifaces_size = 1;
551 			ps->ifaces = malloc(sizeof (struct pcap_ng_if));
552 		} else {
553 			/*
554 			 * It's not currently empty; double its size.
555 			 * (Perhaps overkill once we have a lot of interfaces.)
556 			 */
557 			ps->ifaces_size *= 2;
558 			ps->ifaces = realloc(ps->ifaces, ps->ifaces_size * sizeof (struct pcap_ng_if));
559 		}
560 		if (ps->ifaces == NULL) {
561 			/*
562 			 * We ran out of memory.
563 			 * Give up.
564 			 */
565 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
566 			    "out of memory for per-interface information (%u interfaces)",
567 			    ps->ifcount);
568 			return (0);
569 		}
570 	}
571 
572 	/*
573 	 * Set the default time stamp resolution and offset.
574 	 */
575 	tsresol = 1000000;	/* microsecond resolution */
576 	tsoffset = 0;		/* absolute timestamps */
577 
578 	/*
579 	 * Now look for various time stamp options, so we know
580 	 * how to interpret the time stamps for this interface.
581 	 */
582 	if (process_idb_options(p, cursor, &tsresol, &tsoffset, errbuf) == -1)
583 		return (0);
584 
585 	ps->ifaces[ps->ifcount - 1].tsresol = tsresol;
586 	ps->ifaces[ps->ifcount - 1].tsoffset = tsoffset;
587 
588 	/*
589 	 * Determine whether we're scaling up or down or not
590 	 * at all for this interface.
591 	 */
592 	switch (p->opt.tstamp_precision) {
593 
594 	case PCAP_TSTAMP_PRECISION_MICRO:
595 		if (tsresol == 1000000) {
596 			/*
597 			 * The resolution is 1 microsecond,
598 			 * so we don't have to do scaling.
599 			 */
600 			ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH;
601 		} else if (tsresol > 1000000) {
602 			/*
603 			 * The resolution is greater than
604 			 * 1 microsecond, so we have to
605 			 * scale the timestamps down.
606 			 */
607 			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN;
608 		} else {
609 			/*
610 			 * The resolution is less than 1
611 			 * microsecond, so we have to scale
612 			 * the timestamps up.
613 			 */
614 			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP;
615 		}
616 		break;
617 
618 	case PCAP_TSTAMP_PRECISION_NANO:
619 		if (tsresol == 1000000000) {
620 			/*
621 			 * The resolution is 1 nanosecond,
622 			 * so we don't have to do scaling.
623 			 */
624 			ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH;
625 		} else if (tsresol > 1000000000) {
626 			/*
627 			 * The resolution is greater than
628 			 * 1 nanosecond, so we have to
629 			 * scale the timestamps down.
630 			 */
631 			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN;
632 		} else {
633 			/*
634 			 * The resolution is less than 1
635 			 * nanosecond, so we have to scale
636 			 * the timestamps up.
637 			 */
638 			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP;
639 		}
640 		break;
641 	}
642 	return (1);
643 }
644 
645 /*
646  * Check whether this is a pcap-ng savefile and, if it is, extract the
647  * relevant information from the header.
648  */
649 pcap_t *
pcap_ng_check_header(bpf_u_int32 magic,FILE * fp,u_int precision,char * errbuf,int * err)650 pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
651     int *err)
652 {
653 	size_t amt_read;
654 	bpf_u_int32 total_length;
655 	bpf_u_int32 byte_order_magic;
656 	struct block_header *bhdrp;
657 	struct section_header_block *shbp;
658 	pcap_t *p;
659 	int swapped = 0;
660 	struct pcap_ng_sf *ps;
661 	int status;
662 	struct block_cursor cursor;
663 	struct interface_description_block *idbp;
664 
665 	/*
666 	 * Assume no read errors.
667 	 */
668 	*err = 0;
669 
670 	/*
671 	 * Check whether the first 4 bytes of the file are the block
672 	 * type for a pcap-ng savefile.
673 	 */
674 	if (magic != BT_SHB) {
675 		/*
676 		 * XXX - check whether this looks like what the block
677 		 * type would be after being munged by mapping between
678 		 * UN*X and DOS/Windows text file format and, if it
679 		 * does, look for the byte-order magic number in
680 		 * the appropriate place and, if we find it, report
681 		 * this as possibly being a pcap-ng file transferred
682 		 * between UN*X and Windows in text file format?
683 		 */
684 		return (NULL);	/* nope */
685 	}
686 
687 	/*
688 	 * OK, they are.  However, that's just \n\r\r\n, so it could,
689 	 * conceivably, be an ordinary text file.
690 	 *
691 	 * It could not, however, conceivably be any other type of
692 	 * capture file, so we can read the rest of the putative
693 	 * Section Header Block; put the block type in the common
694 	 * header, read the rest of the common header and the
695 	 * fixed-length portion of the SHB, and look for the byte-order
696 	 * magic value.
697 	 */
698 	amt_read = fread(&total_length, 1, sizeof(total_length), fp);
699 	if (amt_read < sizeof(total_length)) {
700 		if (ferror(fp)) {
701 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
702 			    "error reading dump file: %s",
703 			    pcap_strerror(errno));
704 			*err = 1;
705 			return (NULL);	/* fail */
706 		}
707 
708 		/*
709 		 * Possibly a weird short text file, so just say
710 		 * "not pcap-ng".
711 		 */
712 		return (NULL);
713 	}
714 	amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
715 	if (amt_read < sizeof(byte_order_magic)) {
716 		if (ferror(fp)) {
717 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
718 			    "error reading dump file: %s",
719 			    pcap_strerror(errno));
720 			*err = 1;
721 			return (NULL);	/* fail */
722 		}
723 
724 		/*
725 		 * Possibly a weird short text file, so just say
726 		 * "not pcap-ng".
727 		 */
728 		return (NULL);
729 	}
730 	if (byte_order_magic != BYTE_ORDER_MAGIC) {
731 		byte_order_magic = SWAPLONG(byte_order_magic);
732 		if (byte_order_magic != BYTE_ORDER_MAGIC) {
733 			/*
734 			 * Not a pcap-ng file.
735 			 */
736 			return (NULL);
737 		}
738 		swapped = 1;
739 		total_length = SWAPLONG(total_length);
740 	}
741 
742 	/*
743 	 * Check the sanity of the total length.
744 	 */
745 	if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
746 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
747 		    "Section Header Block in pcap-ng dump file has a length of %u < %lu",
748 		    total_length,
749 		    (unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
750 		*err = 1;
751 		return (NULL);
752 	}
753 
754 	/*
755 	 * OK, this is a good pcap-ng file.
756 	 * Allocate a pcap_t for it.
757 	 */
758 	p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf));
759 	if (p == NULL) {
760 		/* Allocation failed. */
761 		*err = 1;
762 		return (NULL);
763 	}
764 	p->swapped = swapped;
765 	ps = p->priv;
766 
767 	/*
768 	 * What precision does the user want?
769 	 */
770 	switch (precision) {
771 
772 	case PCAP_TSTAMP_PRECISION_MICRO:
773 		ps->user_tsresol = 1000000;
774 		break;
775 
776 	case PCAP_TSTAMP_PRECISION_NANO:
777 		ps->user_tsresol = 1000000000;
778 		break;
779 
780 	default:
781 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
782 		    "unknown time stamp resolution %u", precision);
783 		free(p);
784 		*err = 1;
785 		return (NULL);
786 	}
787 
788 	p->opt.tstamp_precision = precision;
789 
790 	/*
791 	 * Allocate a buffer into which to read blocks.  We default to
792 	 * the maximum of:
793 	 *
794 	 *	the total length of the SHB for which we read the header;
795 	 *
796 	 *	2K, which should be more than large enough for an Enhanced
797 	 *	Packet Block containing a full-size Ethernet frame, and
798 	 *	leaving room for some options.
799 	 *
800 	 * If we find a bigger block, we reallocate the buffer.
801 	 */
802 	p->bufsize = 2048;
803 	if (p->bufsize < (int)total_length)
804 		p->bufsize = total_length;
805 	p->buffer = malloc(p->bufsize);
806 	if (p->buffer == NULL) {
807 		snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
808 		free(p);
809 		*err = 1;
810 		return (NULL);
811 	}
812 
813 	/*
814 	 * Copy the stuff we've read to the buffer, and read the rest
815 	 * of the SHB.
816 	 */
817 	bhdrp = (struct block_header *)(void *)p->buffer;
818 	shbp = (struct section_header_block *)(void *)(p->buffer + sizeof(struct block_header));
819 	bhdrp->block_type = magic;
820 	bhdrp->total_length = total_length;
821 	shbp->byte_order_magic = byte_order_magic;
822 	if (read_bytes(fp,
823 	    p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
824 	    total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
825 	    1, errbuf) == -1)
826 		goto fail;
827 
828 	if (p->swapped) {
829 		/*
830 		 * Byte-swap the fields we've read.
831 		 */
832 		shbp->major_version = SWAPSHORT((uint32_t)shbp->major_version);
833 		shbp->minor_version = SWAPSHORT((uint32_t)shbp->minor_version);
834 
835 		/*
836 		 * XXX - we don't care about the section length.
837 		 */
838 	}
839 	if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
840 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
841 		    "unknown pcap-ng savefile major version number %u",
842 		    shbp->major_version);
843 		goto fail;
844 	}
845 	p->version_major = shbp->major_version;
846 	p->version_minor = shbp->minor_version;
847 
848 	/*
849 	 * Save the time stamp resolution the user requested.
850 	 */
851 	p->opt.tstamp_precision = precision;
852 
853 	/*
854 	 * Now start looking for an Interface Description Block.
855 	 */
856 	for (;;) {
857 		/*
858 		 * Read the next block.
859 		 */
860 		status = read_block(fp, p, &cursor, errbuf);
861 		if (status == 0) {
862 			/* EOF - no IDB in this file */
863 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
864 			    "the capture file has no Interface Description Blocks");
865 			goto fail;
866 		}
867 		if (status == -1)
868 			goto fail;	/* error */
869 		switch (cursor.block_type) {
870 
871 		case BT_IDB:
872 			/*
873 			 * Get a pointer to the fixed-length portion of the
874 			 * IDB.
875 			 */
876 			idbp = get_from_block_data(&cursor, sizeof(*idbp),
877 			    errbuf);
878 			if (idbp == NULL)
879 				goto fail;	/* error */
880 
881 			/*
882 			 * Byte-swap it if necessary.
883 			 */
884 			if (p->swapped) {
885 				idbp->linktype = SWAPSHORT((uint16_t)idbp->linktype);
886 				idbp->snaplen = SWAPLONG(idbp->snaplen);
887 			}
888 
889 			/*
890 			 * Try to add this interface.
891 			 */
892 			if (!add_interface(p, &cursor, errbuf))
893 				goto fail;
894 			goto done;
895 
896 		case BT_EPB:
897 		case BT_SPB:
898 		case BT_PB:
899 			/*
900 			 * Saw a packet before we saw any IDBs.  That's
901 			 * not valid, as we don't know what link-layer
902 			 * encapsulation the packet has.
903 			 */
904 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
905 			    "the capture file has a packet block before any Interface Description Blocks");
906 			goto fail;
907 
908 		default:
909 			/*
910 			 * Just ignore it.
911 			 */
912 			break;
913 		}
914 	}
915 
916 done:
917 	p->tzoff = 0;	/* XXX - not used in pcap */
918 	p->snapshot = idbp->snaplen;
919 	p->linktype = linktype_to_dlt(idbp->linktype);
920 	p->linktype_ext = 0;
921 
922 	p->next_packet_op = pcap_ng_next_packet;
923 	p->cleanup_op = pcap_ng_cleanup;
924 
925 	return (p);
926 
927 fail:
928 	free(ps->ifaces);
929 	free(p->buffer);
930 	free(p);
931 	*err = 1;
932 	return (NULL);
933 }
934 
935 static void
pcap_ng_cleanup(pcap_t * p)936 pcap_ng_cleanup(pcap_t *p)
937 {
938 	struct pcap_ng_sf *ps = p->priv;
939 
940 	free(ps->ifaces);
941 	sf_cleanup(p);
942 }
943 
944 /*
945  * Read and return the next packet from the savefile.  Return the header
946  * in hdr and a pointer to the contents in data.  Return 0 on success, 1
947  * if there were no more packets, and -1 on an error.
948  */
949 static int
pcap_ng_next_packet(pcap_t * p,struct pcap_pkthdr * hdr,u_char ** data)950 pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
951 {
952 	struct pcap_ng_sf *ps = p->priv;
953 	struct block_cursor cursor;
954 	int status;
955 	struct enhanced_packet_block *epbp;
956 	struct simple_packet_block *spbp;
957 	struct packet_block *pbp;
958 	bpf_u_int32 interface_id = 0xFFFFFFFF;
959 	struct interface_description_block *idbp;
960 	struct section_header_block *shbp;
961 	FILE *fp = p->rfile;
962 	u_int64_t t, sec, frac;
963 
964 	/*
965 	 * Look for an Enhanced Packet Block, a Simple Packet Block,
966 	 * or a Packet Block.
967 	 */
968 	for (;;) {
969 		/*
970 		 * Read the block type and length; those are common
971 		 * to all blocks.
972 		 */
973 		status = read_block(fp, p, &cursor, p->errbuf);
974 		if (status == 0)
975 			return (1);	/* EOF */
976 		if (status == -1)
977 			return (-1);	/* error */
978 		switch (cursor.block_type) {
979 
980 		case BT_EPB:
981 			/*
982 			 * Get a pointer to the fixed-length portion of the
983 			 * EPB.
984 			 */
985 			epbp = get_from_block_data(&cursor, sizeof(*epbp),
986 			    p->errbuf);
987 			if (epbp == NULL)
988 				return (-1);	/* error */
989 
990 			/*
991 			 * Byte-swap it if necessary.
992 			 */
993 			if (p->swapped) {
994 				/* these were written in opposite byte order */
995 				interface_id = SWAPLONG(epbp->interface_id);
996 				hdr->caplen = SWAPLONG(epbp->caplen);
997 				hdr->len = SWAPLONG(epbp->len);
998 				t = ((u_int64_t)SWAPLONG(epbp->timestamp_high)) << 32 |
999 				    SWAPLONG(epbp->timestamp_low);
1000 			} else {
1001 				interface_id = epbp->interface_id;
1002 				hdr->caplen = epbp->caplen;
1003 				hdr->len = epbp->len;
1004 				t = ((u_int64_t)epbp->timestamp_high) << 32 |
1005 				    epbp->timestamp_low;
1006 			}
1007 			goto found;
1008 
1009 		case BT_SPB:
1010 			/*
1011 			 * Get a pointer to the fixed-length portion of the
1012 			 * SPB.
1013 			 */
1014 			spbp = get_from_block_data(&cursor, sizeof(*spbp),
1015 			    p->errbuf);
1016 			if (spbp == NULL)
1017 				return (-1);	/* error */
1018 
1019 			/*
1020 			 * SPB packets are assumed to have arrived on
1021 			 * the first interface.
1022 			 */
1023 			interface_id = 0;
1024 
1025 			/*
1026 			 * Byte-swap it if necessary.
1027 			 */
1028 			if (p->swapped) {
1029 				/* these were written in opposite byte order */
1030 				hdr->len = SWAPLONG(spbp->len);
1031 			} else
1032 				hdr->len = spbp->len;
1033 
1034 			/*
1035 			 * The SPB doesn't give the captured length;
1036 			 * it's the minimum of the snapshot length
1037 			 * and the packet length.
1038 			 */
1039 			hdr->caplen = hdr->len;
1040 			if ((int)hdr->caplen > p->snapshot)
1041 				hdr->caplen = p->snapshot;
1042 			t = 0;	/* no time stamps */
1043 			goto found;
1044 
1045 		case BT_PB:
1046 			/*
1047 			 * Get a pointer to the fixed-length portion of the
1048 			 * PB.
1049 			 */
1050 			pbp = get_from_block_data(&cursor, sizeof(*pbp),
1051 			    p->errbuf);
1052 			if (pbp == NULL)
1053 				return (-1);	/* error */
1054 
1055 			/*
1056 			 * Byte-swap it if necessary.
1057 			 */
1058 			if (p->swapped) {
1059 				/* these were written in opposite byte order */
1060 				interface_id = SWAPSHORT((uint32_t)pbp->interface_id);
1061 				hdr->caplen = SWAPLONG(pbp->caplen);
1062 				hdr->len = SWAPLONG(pbp->len);
1063 				t = ((u_int64_t)SWAPLONG(pbp->timestamp_high)) << 32 |
1064 				    SWAPLONG(pbp->timestamp_low);
1065 			} else {
1066 				interface_id = pbp->interface_id;
1067 				hdr->caplen = pbp->caplen;
1068 				hdr->len = pbp->len;
1069 				t = ((u_int64_t)pbp->timestamp_high) << 32 |
1070 				    pbp->timestamp_low;
1071 			}
1072 			goto found;
1073 
1074 		case BT_IDB:
1075 			/*
1076 			 * Interface Description Block.  Get a pointer
1077 			 * to its fixed-length portion.
1078 			 */
1079 			idbp = get_from_block_data(&cursor, sizeof(*idbp),
1080 			    p->errbuf);
1081 			if (idbp == NULL)
1082 				return (-1);	/* error */
1083 
1084 			/*
1085 			 * Byte-swap it if necessary.
1086 			 */
1087 			if (p->swapped) {
1088 				idbp->linktype = SWAPSHORT((uint32_t)idbp->linktype);
1089 				idbp->snaplen = SWAPLONG(idbp->snaplen);
1090 			}
1091 
1092 			/*
1093 			 * If the link-layer type or snapshot length
1094 			 * differ from the ones for the first IDB we
1095 			 * saw, quit.
1096 			 *
1097 			 * XXX - just discard packets from those
1098 			 * interfaces?
1099 			 */
1100 			if (p->linktype != idbp->linktype) {
1101 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1102 				    "an interface has a type %u different from the type of the first interface",
1103 				    idbp->linktype);
1104 				return (-1);
1105 			}
1106 			if (p->snapshot != (int)idbp->snaplen) {
1107 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1108 				    "an interface has a snapshot length %u different from the type of the first interface",
1109 				    idbp->snaplen);
1110 				return (-1);
1111 			}
1112 
1113 			/*
1114 			 * Try to add this interface.
1115 			 */
1116 			if (!add_interface(p, &cursor, p->errbuf))
1117 				return (-1);
1118 			break;
1119 
1120 		case BT_SHB:
1121 			/*
1122 			 * Section Header Block.  Get a pointer
1123 			 * to its fixed-length portion.
1124 			 */
1125 			shbp = get_from_block_data(&cursor, sizeof(*shbp),
1126 			    p->errbuf);
1127 			if (shbp == NULL)
1128 				return (-1);	/* error */
1129 
1130 			/*
1131 			 * Assume the byte order of this section is
1132 			 * the same as that of the previous section.
1133 			 * We'll check for that later.
1134 			 */
1135 			if (p->swapped) {
1136 				shbp->byte_order_magic =
1137 				    SWAPLONG(shbp->byte_order_magic);
1138 				shbp->major_version =
1139 				    SWAPSHORT((uint32_t)shbp->major_version);
1140 			}
1141 
1142 			/*
1143 			 * Make sure the byte order doesn't change;
1144 			 * pcap_is_swapped() shouldn't change its
1145 			 * return value in the middle of reading a capture.
1146 			 */
1147 			switch (shbp->byte_order_magic) {
1148 
1149 			case BYTE_ORDER_MAGIC:
1150 				/*
1151 				 * OK.
1152 				 */
1153 				break;
1154 
1155 			case SWAPLONG(BYTE_ORDER_MAGIC):
1156 				/*
1157 				 * Byte order changes.
1158 				 */
1159 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1160 				    "the file has sections with different byte orders");
1161 				return (-1);
1162 
1163 			default:
1164 				/*
1165 				 * Not a valid SHB.
1166 				 */
1167 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1168 				    "the file has a section with a bad byte order magic field");
1169 				return (-1);
1170 			}
1171 
1172 			/*
1173 			 * Make sure the major version is the version
1174 			 * we handle.
1175 			 */
1176 			if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
1177 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1178 				    "unknown pcap-ng savefile major version number %u",
1179 				    shbp->major_version);
1180 				return (-1);
1181 			}
1182 
1183 			/*
1184 			 * Reset the interface count; this section should
1185 			 * have its own set of IDBs.  If any of them
1186 			 * don't have the same interface type, snapshot
1187 			 * length, or resolution as the first interface
1188 			 * we saw, we'll fail.  (And if we don't see
1189 			 * any IDBs, we'll fail when we see a packet
1190 			 * block.)
1191 			 */
1192 			ps->ifcount = 0;
1193 			break;
1194 
1195 		default:
1196 			/*
1197 			 * Not a packet block, IDB, or SHB; ignore it.
1198 			 */
1199 			break;
1200 		}
1201 	}
1202 
1203 found:
1204 	/*
1205 	 * Is the interface ID an interface we know?
1206 	 */
1207 	if (interface_id >= ps->ifcount) {
1208 		/*
1209 		 * Yes.  Fail.
1210 		 */
1211 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1212 		    "a packet arrived on interface %u, but there's no Interface Description Block for that interface",
1213 		    interface_id);
1214 		return (-1);
1215 	}
1216 
1217 	/*
1218 	 * Convert the time stamp to seconds and fractions of a second,
1219 	 * with the fractions being in units of the file-supplied resolution.
1220 	 */
1221 	sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset;
1222 	frac = t % ps->ifaces[interface_id].tsresol;
1223 
1224 	/*
1225 	 * Convert the fractions from units of the file-supplied resolution
1226 	 * to units of the user-requested resolution.
1227 	 */
1228 	switch (ps->ifaces[interface_id].scale_type) {
1229 
1230 	case PASS_THROUGH:
1231 		/*
1232 		 * The interface resolution is what the user wants,
1233 		 * so we're done.
1234 		 */
1235 		break;
1236 
1237 	case SCALE_UP:
1238 	case SCALE_DOWN:
1239 		/*
1240 		 * The interface resolution is different from what the
1241 		 * user wants; convert the fractions to units of the
1242 		 * resolution the user requested by multiplying by the
1243 		 * quotient of the user-requested resolution and the
1244 		 * file-supplied resolution.  We do that by multiplying
1245 		 * by the user-requested resolution and dividing by the
1246 		 * file-supplied resolution, as the quotient might not
1247 		 * fit in an integer.
1248 		 *
1249 		 * XXX - if ps->ifaces[interface_id].tsresol is a power
1250 		 * of 10, we could just multiply by the quotient of
1251 		 * ps->user_tsresol and ps->ifaces[interface_id].tsresol
1252 		 * in the scale-up case, and divide by the quotient of
1253 		 * ps->ifaces[interface_id].tsresol and ps->user_tsresol
1254 		 * in the scale-down case, as we know those will be integers.
1255 		 * That would involve fewer arithmetic operations, and
1256 		 * would run less risk of overflow.
1257 		 *
1258 		 * Is there something clever we could do if
1259 		 * ps->ifaces[interface_id].tsresol is a power of 2?
1260 		 */
1261 		frac *= ps->user_tsresol;
1262 		frac /= ps->ifaces[interface_id].tsresol;
1263 		break;
1264 	}
1265 	hdr->ts.tv_sec = sec;
1266 	hdr->ts.tv_usec = (suseconds_t)frac;
1267 
1268 	/*
1269 	 * Get a pointer to the packet data.
1270 	 */
1271 	*data = get_from_block_data(&cursor, hdr->caplen, p->errbuf);
1272 	if (*data == NULL)
1273 		return (-1);
1274 
1275 	if (p->swapped)
1276 		swap_pseudo_headers(p->linktype, hdr, *data);
1277 
1278 	return (0);
1279 }
1280