pcap_parser/
pcap.rs

1//! PCAP file format
2//!
3//! See <https://wiki.wireshark.org/Development/LibpcapFileFormat> for details.
4//!
5//! There are 2 main ways of parsing a PCAP file. The first method is to use
6//! [`parse_pcap`]. This method requires to load the entire
7//! file to memory, and thus may not be good for large files.
8//!
9//! The [`PcapCapture`] implements the
10//! [`Capture`](crate::Capture) trait to provide generic methods. However,
11//! this trait also reads the entire file.
12//!
13//! The second method is to first parse the PCAP header
14//! using [`parse_pcap_header`], then
15//! loop over [`parse_pcap_frame`] to get the data.
16//! This can be used in a streaming parser.
17
18mod capture;
19mod frame;
20mod header;
21mod reader;
22
23pub use capture::*;
24pub use frame::*;
25pub use header::*;
26pub use reader::*;
27
28#[cfg(test)]
29pub mod tests {
30    use crate::pcap::{parse_pcap_frame, parse_pcap_header};
31    use crate::traits::tests::FRAME_PCAP;
32    use hex_literal::hex;
33    // ntp.pcap header
34    pub const PCAP_HDR: &[u8] = &hex!(
35        "
36D4 C3 B2 A1 02 00 04 00 00 00 00 00 00 00 00 00
3700 00 04 00 01 00 00 00"
38    );
39
40    // pcap header with nanosecond-precision timestamping
41    pub const PCAP_HDR_NSEC: &[u8] = &hex!(
42        "
434D 3C B2 A1 02 00 04 00 00 00 00 00 00 00 00 00
4400 00 04 00 01 00 00 00"
45    );
46    #[test]
47    fn test_parse_pcap_header() {
48        let (rem, hdr) = parse_pcap_header(PCAP_HDR).expect("header parsing failed");
49        assert!(rem.is_empty());
50        assert_eq!(hdr.magic_number, 0xa1b2_c3d4);
51        assert_eq!(hdr.version_major, 2);
52        assert_eq!(hdr.version_minor, 4);
53        assert_eq!(hdr.snaplen, 262_144);
54        assert!(!hdr.is_nanosecond_precision());
55    }
56    #[test]
57    fn test_parse_nanosecond_precision_pcap_header() {
58        let (rem, hdr) = parse_pcap_header(PCAP_HDR_NSEC).expect("header parsing failed");
59        assert!(rem.is_empty());
60        assert_eq!(hdr.magic_number, 0xa1b2_3c4d);
61        assert_eq!(hdr.version_major, 2);
62        assert_eq!(hdr.version_minor, 4);
63        assert_eq!(hdr.snaplen, 262_144);
64        assert!(hdr.is_nanosecond_precision());
65    }
66    #[test]
67    fn test_parse_pcap_frame() {
68        let (rem, pkt) = parse_pcap_frame(FRAME_PCAP).expect("packet parsing failed");
69        assert!(rem.is_empty());
70        assert_eq!(pkt.origlen, 74);
71        assert_eq!(pkt.ts_usec, 562_913);
72        assert_eq!(pkt.ts_sec, 1_515_933_236);
73    }
74}