pcap_parser/pcap/
header.rs1use nom::number::streaming::{be_i32, be_u16, be_u32, le_i32, le_u16, le_u32};
2use nom::IResult;
3
4use crate::linktype::Linktype;
5use crate::PcapError;
6
7#[derive(Clone, Debug)]
9pub struct PcapHeader {
10 pub magic_number: u32,
14 pub version_major: u16,
16 pub version_minor: u16,
18 pub thiszone: i32,
20 pub sigfigs: u32,
22 pub snaplen: u32,
24 pub network: Linktype,
26}
27
28impl PcapHeader {
29 pub fn new() -> PcapHeader {
30 PcapHeader {
31 magic_number: 0xa1b2_c3d4, version_major: 2,
33 version_minor: 4,
34 thiszone: 0,
35 sigfigs: 0,
36 snaplen: 0,
37 network: Linktype(1), }
39 }
40
41 pub const fn size(&self) -> usize {
42 24
43 }
44
45 pub fn is_bigendian(&self) -> bool {
46 (self.magic_number & 0xFFFF) == 0xb2a1 }
48
49 pub fn is_modified_format(&self) -> bool {
50 self.magic_number == 0xa1b2_cd34
51 }
52
53 pub fn is_nanosecond_precision(&self) -> bool {
54 self.magic_number == 0xa1b2_3c4d || self.magic_number == 0x4d3c_b2a1
55 }
56}
57
58impl Default for PcapHeader {
59 fn default() -> Self {
60 PcapHeader::new()
61 }
62}
63
64pub fn parse_pcap_header(i: &[u8]) -> IResult<&[u8], PcapHeader, PcapError<&[u8]>> {
68 let (i, magic_number) = le_u32(i)?;
69 match magic_number {
70 0xa1b2_c3d4 | 0xa1b2_3c4d | 0xa1b2_cd34 => {
71 let (i, version_major) = le_u16(i)?;
72 let (i, version_minor) = le_u16(i)?;
73 let (i, thiszone) = le_i32(i)?;
74 let (i, sigfigs) = le_u32(i)?;
75 let (i, snaplen) = le_u32(i)?;
76 let (i, network) = le_i32(i)?;
77 let header = PcapHeader {
78 magic_number,
79 version_major,
80 version_minor,
81 thiszone,
82 sigfigs,
83 snaplen,
84 network: Linktype(network),
85 };
86 Ok((i, header))
87 }
88 0xd4c3_b2a1 | 0x4d3c_b2a1 => {
89 let (i, version_major) = be_u16(i)?;
90 let (i, version_minor) = be_u16(i)?;
91 let (i, thiszone) = be_i32(i)?;
92 let (i, sigfigs) = be_u32(i)?;
93 let (i, snaplen) = be_u32(i)?;
94 let (i, network) = be_i32(i)?;
95 let header = PcapHeader {
96 magic_number,
97 version_major,
98 version_minor,
99 thiszone,
100 sigfigs,
101 snaplen,
102 network: Linktype(network),
103 };
104 Ok((i, header))
105 }
106 _ => Err(nom::Err::Error(PcapError::HeaderNotRecognized)),
107 }
108}