/rust/registry/src/index.crates.io-6f17d22bba15001f/ntp-parser-0.6.0/src/ntp.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use nom::bytes::streaming::take; |
2 | | use nom::combinator::{complete, map, map_parser, opt}; |
3 | | use nom::error::{make_error, ErrorKind}; |
4 | | use nom::multi::many1; |
5 | | use nom::number::streaming::be_u8; |
6 | | pub use nom::{Err, IResult}; |
7 | | use nom_derive::*; |
8 | | |
9 | | #[derive(Debug, PartialEq)] |
10 | | pub enum NtpPacket<'a> { |
11 | | V3(NtpV3Packet<'a>), |
12 | | V4(NtpV4Packet<'a>), |
13 | | } |
14 | | |
15 | 0 | #[derive(Clone, Copy, Debug, Eq, PartialEq, NomBE)] Unexecuted instantiation: <ntp_parser::ntp::NtpMode as nom_derive::traits::Parse<&[u8]>>::parse_be Unexecuted instantiation: <ntp_parser::ntp::NtpMode as nom_derive::traits::Parse<&[u8]>>::parse_le Unexecuted instantiation: <ntp_parser::ntp::NtpMode as nom_derive::traits::Parse<&[u8]>>::parse Unexecuted instantiation: <ntp_parser::ntp::NtpMode as nom_derive::traits::Parse<&[u8]>>::parse_be Unexecuted instantiation: <ntp_parser::ntp::NtpMode as nom_derive::traits::Parse<&[u8]>>::parse_le Unexecuted instantiation: <ntp_parser::ntp::NtpMode as nom_derive::traits::Parse<&[u8]>>::parse |
16 | | pub struct NtpMode(pub u8); |
17 | | |
18 | | #[allow(non_upper_case_globals)] |
19 | | impl NtpMode { |
20 | | pub const Reserved: NtpMode = NtpMode(0); |
21 | | pub const SymmetricActive: NtpMode = NtpMode(1); |
22 | | pub const SymmetricPassive: NtpMode = NtpMode(2); |
23 | | pub const Client: NtpMode = NtpMode(3); |
24 | | pub const Server: NtpMode = NtpMode(4); |
25 | | pub const Broadcast: NtpMode = NtpMode(5); |
26 | | pub const NtpControlMessage: NtpMode = NtpMode(6); |
27 | | pub const Private: NtpMode = NtpMode(7); |
28 | | } |
29 | | |
30 | | /// An NTP version 3 packet |
31 | 307k | #[derive(Debug, PartialEq, NomBE)] <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#0} Line | Count | Source | 31 | 39.0k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#1} Line | Count | Source | 31 | 39.0k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#2} Line | Count | Source | 31 | 39.0k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#0} Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#1} Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#2} <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse Line | Count | Source | 31 | 39.0k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#0} Line | Count | Source | 31 | 37.9k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#1} Line | Count | Source | 31 | 37.9k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#2} Line | Count | Source | 31 | 37.9k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#0} Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#1} Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#2} <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse Line | Count | Source | 31 | 37.9k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 31 | 39.0k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 31 | 37.9k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV3Packet as nom_derive::traits::Parse<&[u8]>>::parse_le |
32 | | pub struct NtpV3Packet<'a> { |
33 | | #[nom(PreExec = "let (i, b0) = be_u8(i)?;")] |
34 | | #[nom(Value(b0 >> 6))] |
35 | | pub li: u8, |
36 | | #[nom(Value((b0 >> 3) & 0b111))] |
37 | | pub version: u8, |
38 | | #[nom(Value(NtpMode(b0 & 0b111)))] |
39 | | pub mode: NtpMode, |
40 | | pub stratum: u8, |
41 | | pub poll: i8, |
42 | | pub precision: i8, |
43 | | pub root_delay: u32, |
44 | | pub root_dispersion: u32, |
45 | | pub ref_id: u32, |
46 | | pub ts_ref: u64, |
47 | | pub ts_orig: u64, |
48 | | pub ts_recv: u64, |
49 | | pub ts_xmit: u64, |
50 | | |
51 | | #[nom(Parse = "opt(complete(take(12usize)))")] |
52 | | pub authenticator: Option<&'a [u8]>, |
53 | | } |
54 | | |
55 | | /// An NTP version 4 packet |
56 | 57.6k | #[derive(Debug, PartialEq, NomBE)] <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#0} Line | Count | Source | 56 | 8.37k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#1} Line | Count | Source | 56 | 8.37k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#2} Line | Count | Source | 56 | 8.37k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#0} Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#1} Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#2} <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse Line | Count | Source | 56 | 8.37k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#0} Line | Count | Source | 56 | 6.04k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#1} Line | Count | Source | 56 | 6.04k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be::{closure#2} Line | Count | Source | 56 | 6.04k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#0} Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#1} Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le::{closure#2} <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse Line | Count | Source | 56 | 6.04k | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 56 | 8.37k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 56 | 6.04k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet as nom_derive::traits::Parse<&[u8]>>::parse_le |
57 | | pub struct NtpV4Packet<'a> { |
58 | | #[nom(PreExec = "let (i, b0) = be_u8(i)?;")] |
59 | | #[nom(Value(b0 >> 6))] |
60 | | pub li: u8, |
61 | | #[nom(Value((b0 >> 3) & 0b111))] |
62 | | pub version: u8, |
63 | | #[nom(Value(NtpMode(b0 & 0b111)))] |
64 | | pub mode: NtpMode, |
65 | | pub stratum: u8, |
66 | | pub poll: i8, |
67 | | pub precision: i8, |
68 | | pub root_delay: u32, |
69 | | pub root_dispersion: u32, |
70 | | pub ref_id: u32, |
71 | | pub ts_ref: u64, |
72 | | pub ts_orig: u64, |
73 | | pub ts_recv: u64, |
74 | | pub ts_xmit: u64, |
75 | | |
76 | | #[nom(Parse = "try_parse_extensions")] |
77 | | pub extensions: Vec<NtpExtension<'a>>, |
78 | | #[nom(Cond(!i.is_empty()))] |
79 | | pub auth: Option<NtpMac<'a>>, |
80 | | } |
81 | | |
82 | | impl<'a> NtpV4Packet<'a> { |
83 | 0 | pub fn get_precision(&self) -> f32 { |
84 | 0 | 2.0_f32.powf(self.precision as f32) |
85 | 0 | } Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet>::get_precision Unexecuted instantiation: <ntp_parser::ntp::NtpV4Packet>::get_precision |
86 | | } |
87 | | |
88 | 5.93M | #[derive(Debug, PartialEq, NomBE)] <ntp_parser::ntp::NtpExtension as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 88 | 3.37M | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpExtension as nom_derive::traits::Parse<&[u8]>>::parse_le <ntp_parser::ntp::NtpExtension as nom_derive::traits::Parse<&[u8]>>::parse Line | Count | Source | 88 | 3.36M | #[derive(Debug, PartialEq, NomBE)] |
<ntp_parser::ntp::NtpExtension as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 88 | 2.56M | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpExtension as nom_derive::traits::Parse<&[u8]>>::parse_le <ntp_parser::ntp::NtpExtension as nom_derive::traits::Parse<&[u8]>>::parse Line | Count | Source | 88 | 2.55M | #[derive(Debug, PartialEq, NomBE)] |
|
89 | | pub struct NtpExtension<'a> { |
90 | | pub field_type: u16, |
91 | | pub length: u16, |
92 | | #[nom(Parse = "take(length)")] |
93 | | pub value: &'a [u8], |
94 | | /*padding*/ |
95 | | } |
96 | | |
97 | 9.64k | #[derive(Debug, PartialEq, NomBE)] <ntp_parser::ntp::NtpMac as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 97 | 5.90k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpMac as nom_derive::traits::Parse<&[u8]>>::parse_le Unexecuted instantiation: <ntp_parser::ntp::NtpMac as nom_derive::traits::Parse<&[u8]>>::parse <ntp_parser::ntp::NtpMac as nom_derive::traits::Parse<&[u8]>>::parse_be Line | Count | Source | 97 | 3.73k | #[derive(Debug, PartialEq, NomBE)] |
Unexecuted instantiation: <ntp_parser::ntp::NtpMac as nom_derive::traits::Parse<&[u8]>>::parse_le Unexecuted instantiation: <ntp_parser::ntp::NtpMac as nom_derive::traits::Parse<&[u8]>>::parse |
98 | | pub struct NtpMac<'a> { |
99 | | pub key_id: u32, |
100 | | #[nom(Parse = "take(16usize)")] |
101 | | pub mac: &'a [u8], |
102 | | } |
103 | | |
104 | | #[inline] |
105 | 5.92M | pub fn parse_ntp_extension(i: &[u8]) -> IResult<&[u8], NtpExtension> { |
106 | 5.92M | NtpExtension::parse(i) |
107 | 5.92M | } ntp_parser::ntp::parse_ntp_extension Line | Count | Source | 105 | 3.36M | pub fn parse_ntp_extension(i: &[u8]) -> IResult<&[u8], NtpExtension> { | 106 | 3.36M | NtpExtension::parse(i) | 107 | 3.36M | } |
ntp_parser::ntp::parse_ntp_extension Line | Count | Source | 105 | 2.55M | pub fn parse_ntp_extension(i: &[u8]) -> IResult<&[u8], NtpExtension> { | 106 | 2.55M | NtpExtension::parse(i) | 107 | 2.55M | } |
|
108 | | |
109 | | // Attempt to parse extensions. |
110 | | // |
111 | | // See section 7.5 of [RFC5905] and [RFC7822]: |
112 | | // In NTPv4, one or more extension fields can be inserted after the |
113 | | // header and before the MAC, which is always present when an extension |
114 | | // field is present. |
115 | | // |
116 | | // So: |
117 | | // if == 20, only MAC |
118 | | // if > 20, ext + MAC |
119 | | // if == 0, nothing |
120 | | // else error |
121 | 14.1k | fn try_parse_extensions(i: &[u8]) -> IResult<&[u8], Vec<NtpExtension>> { |
122 | 14.1k | if i.is_empty() || i.len() == 20 { |
123 | | // if empty, or if remaining length is exactly the MAC length (20), assume we do not have |
124 | | // extensions |
125 | 4.83k | return Ok((i, Vec::new())); |
126 | 9.32k | } |
127 | 9.32k | if i.len() < 20 { |
128 | 58 | return Err(Err::Error(make_error(i, ErrorKind::Eof))); |
129 | 9.27k | } |
130 | 9.27k | map_parser(take(i.len() - 20), many1(complete(parse_ntp_extension)))(i) |
131 | 14.1k | } ntp_parser::ntp::try_parse_extensions Line | Count | Source | 121 | 8.26k | fn try_parse_extensions(i: &[u8]) -> IResult<&[u8], Vec<NtpExtension>> { | 122 | 8.26k | if i.is_empty() || i.len() == 20 { | 123 | | // if empty, or if remaining length is exactly the MAC length (20), assume we do not have | 124 | | // extensions | 125 | 2.65k | return Ok((i, Vec::new())); | 126 | 5.60k | } | 127 | 5.60k | if i.len() < 20 { | 128 | 27 | return Err(Err::Error(make_error(i, ErrorKind::Eof))); | 129 | 5.58k | } | 130 | 5.58k | map_parser(take(i.len() - 20), many1(complete(parse_ntp_extension)))(i) | 131 | 8.26k | } |
ntp_parser::ntp::try_parse_extensions Line | Count | Source | 121 | 5.89k | fn try_parse_extensions(i: &[u8]) -> IResult<&[u8], Vec<NtpExtension>> { | 122 | 5.89k | if i.is_empty() || i.len() == 20 { | 123 | | // if empty, or if remaining length is exactly the MAC length (20), assume we do not have | 124 | | // extensions | 125 | 2.17k | return Ok((i, Vec::new())); | 126 | 3.72k | } | 127 | 3.72k | if i.len() < 20 { | 128 | 31 | return Err(Err::Error(make_error(i, ErrorKind::Eof))); | 129 | 3.68k | } | 130 | 3.68k | map_parser(take(i.len() - 20), many1(complete(parse_ntp_extension)))(i) | 131 | 5.89k | } |
|
132 | | |
133 | | /// Parse an NTP version 3 packet (RFC 1305) |
134 | | #[inline] |
135 | 0 | pub fn parse_ntpv3(i: &[u8]) -> IResult<&[u8], NtpV3Packet> { |
136 | 0 | NtpV3Packet::parse(i) |
137 | 0 | } Unexecuted instantiation: ntp_parser::ntp::parse_ntpv3 Unexecuted instantiation: ntp_parser::ntp::parse_ntpv3 |
138 | | |
139 | | /// Parse an NTP version 4 packet (RFC 1305) |
140 | | #[inline] |
141 | 0 | pub fn parse_ntpv4(i: &[u8]) -> IResult<&[u8], NtpV4Packet> { |
142 | 0 | NtpV4Packet::parse(i) |
143 | 0 | } Unexecuted instantiation: ntp_parser::ntp::parse_ntpv4 Unexecuted instantiation: ntp_parser::ntp::parse_ntpv4 |
144 | | |
145 | | /// Parse an NTP packet, version 3 or 4 |
146 | | #[inline] |
147 | 91.4k | pub fn parse_ntp(i: &[u8]) -> IResult<&[u8], NtpPacket> { |
148 | 91.4k | let (_, b0) = be_u8(i)?; |
149 | 91.4k | match (b0 >> 3) & 0b111 { |
150 | 76.9k | 3 => map(NtpV3Packet::parse, NtpPacket::V3)(i), |
151 | 14.4k | 4 => map(NtpV4Packet::parse, NtpPacket::V4)(i), |
152 | 83 | _ => Err(Err::Error(make_error(i, ErrorKind::Tag))), |
153 | | } |
154 | 91.4k | } ntp_parser::ntp::parse_ntp Line | Count | Source | 147 | 47.4k | pub fn parse_ntp(i: &[u8]) -> IResult<&[u8], NtpPacket> { | 148 | 47.4k | let (_, b0) = be_u8(i)?; | 149 | 47.4k | match (b0 >> 3) & 0b111 { | 150 | 39.0k | 3 => map(NtpV3Packet::parse, NtpPacket::V3)(i), | 151 | 8.37k | 4 => map(NtpV4Packet::parse, NtpPacket::V4)(i), | 152 | 38 | _ => Err(Err::Error(make_error(i, ErrorKind::Tag))), | 153 | | } | 154 | 47.4k | } |
ntp_parser::ntp::parse_ntp Line | Count | Source | 147 | 43.9k | pub fn parse_ntp(i: &[u8]) -> IResult<&[u8], NtpPacket> { | 148 | 43.9k | let (_, b0) = be_u8(i)?; | 149 | 43.9k | match (b0 >> 3) & 0b111 { | 150 | 37.9k | 3 => map(NtpV3Packet::parse, NtpPacket::V3)(i), | 151 | 6.04k | 4 => map(NtpV4Packet::parse, NtpPacket::V4)(i), | 152 | 45 | _ => Err(Err::Error(make_error(i, ErrorKind::Tag))), | 153 | | } | 154 | 43.9k | } |
|
155 | | |
156 | | #[cfg(test)] |
157 | | mod tests { |
158 | | use crate::ntp::*; |
159 | | |
160 | | static NTP_REQ1: &[u8] = &[ |
161 | | 0xd9, 0x00, 0x0a, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x90, 0x00, 0x00, 0x00, |
162 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
163 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x02, 0x04, 0xec, 0xec, |
164 | | 0x42, 0xee, 0x92, |
165 | | ]; |
166 | | |
167 | | #[test] |
168 | | fn test_ntp_packet_simple() { |
169 | | let empty = &b""[..]; |
170 | | let bytes = NTP_REQ1; |
171 | | let expected = NtpV4Packet { |
172 | | li: 3, |
173 | | version: 3, |
174 | | mode: NtpMode::SymmetricActive, |
175 | | stratum: 0, |
176 | | poll: 10, |
177 | | precision: -6, |
178 | | root_delay: 0, |
179 | | root_dispersion: 0x010290, |
180 | | ref_id: 0, |
181 | | ts_ref: 0, |
182 | | ts_orig: 0, |
183 | | ts_recv: 0, |
184 | | ts_xmit: 14195914391047827090u64, |
185 | | extensions: Vec::new(), |
186 | | auth: None, |
187 | | }; |
188 | | let res = parse_ntpv4(&bytes); |
189 | | assert_eq!(res, Ok((empty, expected))); |
190 | | } |
191 | | |
192 | | static NTP_REQ2: &[u8] = &[ |
193 | | 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
194 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
195 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x25, 0xcc, 0x13, 0x2b, |
196 | | 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x52, 0x80, 0x0c, 0x2b, 0x59, 0x00, 0x64, 0x66, |
197 | | 0x84, 0xf4, 0x4c, 0xa4, 0xee, 0xce, 0x12, 0xb8, |
198 | | ]; |
199 | | |
200 | | #[test] |
201 | | fn test_ntp_packet_mac() { |
202 | | let empty = &b""[..]; |
203 | | let bytes = NTP_REQ2; |
204 | | let expected = NtpV4Packet { |
205 | | li: 0, |
206 | | version: 4, |
207 | | mode: NtpMode::Client, |
208 | | stratum: 0, |
209 | | poll: 0, |
210 | | precision: 0, |
211 | | root_delay: 12, |
212 | | root_dispersion: 0, |
213 | | ref_id: 0, |
214 | | ts_ref: 0, |
215 | | ts_orig: 0, |
216 | | ts_recv: 0, |
217 | | ts_xmit: 14710388140573593600, |
218 | | extensions: Vec::new(), |
219 | | auth: Some(NtpMac { |
220 | | key_id: 1, |
221 | | mac: &bytes[52..], |
222 | | }), |
223 | | }; |
224 | | let res = parse_ntpv4(&bytes); |
225 | | assert_eq!(res, Ok((empty, expected))); |
226 | | } |
227 | | |
228 | | static NTP_REQ2B: &[u8] = &[ |
229 | | 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
230 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
231 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x25, 0xcc, 0x13, 0x2b, |
232 | | 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x52, 0x80, 0x0c, 0x2b, |
233 | | 0x59, 0x00, 0x64, 0x66, 0x84, 0xf4, 0x4c, 0xa4, 0xee, 0xce, 0x12, 0xb8, |
234 | | ]; |
235 | | |
236 | | #[test] |
237 | | fn test_ntp_packet_extension() { |
238 | | let empty = &b""[..]; |
239 | | let bytes = NTP_REQ2B; |
240 | | let expected = NtpV4Packet { |
241 | | li: 0, |
242 | | version: 4, |
243 | | mode: NtpMode::Client, |
244 | | stratum: 0, |
245 | | poll: 0, |
246 | | precision: 0, |
247 | | root_delay: 12, |
248 | | root_dispersion: 0, |
249 | | ref_id: 0, |
250 | | ts_ref: 0, |
251 | | ts_orig: 0, |
252 | | ts_recv: 0, |
253 | | ts_xmit: 14710388140573593600, |
254 | | extensions: vec![NtpExtension { |
255 | | field_type: 0, |
256 | | length: 0, |
257 | | value: empty, |
258 | | }], |
259 | | auth: Some(NtpMac { |
260 | | key_id: 1, |
261 | | mac: &bytes[56..], |
262 | | }), |
263 | | }; |
264 | | let res = parse_ntpv4(&bytes); |
265 | | assert_eq!(res, Ok((empty, expected))); |
266 | | } |
267 | | |
268 | | // from wireshark test captures 'ntp.pcap' |
269 | | static NTPV3_REQ: &[u8] = &[ |
270 | | 0x1b, 0x04, 0x06, 0xf5, 0x00, 0x00, 0x10, 0x0d, 0x00, 0x00, 0x05, 0x57, 0x82, 0xdc, 0x18, |
271 | | 0x18, 0xba, 0x29, 0x66, 0x36, 0x7d, 0xd0, 0x00, 0x00, 0xba, 0x29, 0x66, 0x36, 0x7d, 0x58, |
272 | | 0x40, 0x00, 0xba, 0x29, 0x66, 0x36, 0x7d, 0xd0, 0x00, 0x00, 0xba, 0x29, 0x66, 0x76, 0x7d, |
273 | | 0x50, 0x50, 0x00, |
274 | | ]; |
275 | | |
276 | | #[test] |
277 | | fn test_ntp_packet_v3() { |
278 | | let empty = &b""[..]; |
279 | | let bytes = NTPV3_REQ; |
280 | | let expected = NtpV3Packet { |
281 | | li: 0, |
282 | | version: 3, |
283 | | mode: NtpMode::Client, |
284 | | stratum: 4, |
285 | | poll: 6, |
286 | | precision: -11, |
287 | | root_delay: 4109, |
288 | | root_dispersion: 0x0557, |
289 | | ref_id: 0x82dc1818, |
290 | | ts_ref: 0xba296636_7dd00000, |
291 | | ts_orig: 0xba296636_7d584000, |
292 | | ts_recv: 0xba296636_7dd00000, |
293 | | ts_xmit: 0xba296676_7d505000, |
294 | | authenticator: None, |
295 | | }; |
296 | | let res = NtpV3Packet::parse(&bytes); |
297 | | assert_eq!(res, Ok((empty, expected))); |
298 | | } |
299 | | } |