packet/icmp/information/
packet.rs1use std::fmt;
16use std::io::Cursor;
17use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
18
19use crate::error::*;
20use crate::packet::{Packet as P, PacketMut as PM, AsPacket, AsPacketMut};
21use crate::icmp::Kind;
22use crate::icmp::packet::Checked;
23
24pub struct Packet<B> {
26 buffer: B,
27}
28
29sized!(Packet,
30 header {
31 min: 8,
32 max: 8,
33 size: 8,
34 }
35
36 payload {
37 min: 0,
38 max: 0,
39 size: 0,
40 });
41
42impl<B: AsRef<[u8]>> fmt::Debug for Packet<B> {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 f.debug_struct("icmp::information::Packet")
45 .field("request", &self.is_request())
46 .field("identifier", &self.identifier())
47 .field("sequence", &self.sequence())
48 .finish()
49 }
50}
51
52impl<B: AsRef<[u8]>> Packet<B> {
53 pub fn unchecked(buffer: B) -> Packet<B> {
54 Packet { buffer }
55 }
56
57 pub fn new(buffer: B) -> Result<Packet<B>> {
60 use crate::size::header::Min;
61
62 let packet = Packet::unchecked(buffer);
63
64 if packet.buffer.as_ref().len() < Self::min() {
65 Err(Error::SmallBuffer)?
66 }
67
68 match Kind::from(packet.buffer.as_ref()[0]) {
69 Kind::InformationRequest |
70 Kind::InformationReply =>
71 (),
72
73 _ =>
74 Err(Error::InvalidPacket)?
75 }
76
77 Ok(packet)
78 }
79}
80
81impl<B: AsRef<[u8]>> Packet<B> {
82 pub fn to_owned(&self) -> Packet<Vec<u8>> {
89 Packet::unchecked(self.buffer.as_ref().to_vec())
90 }
91}
92
93impl<B: AsRef<[u8]>> AsRef<[u8]> for Packet<B> {
94 fn as_ref(&self) -> &[u8] {
95 use crate::size::Size;
96
97 &self.buffer.as_ref()[.. self.size()]
98 }
99}
100
101impl<B: AsRef<[u8]> + AsMut<[u8]>> AsMut<[u8]> for Packet<B> {
102 fn as_mut(&mut self) -> &mut [u8] {
103 use crate::size::Size;
104
105 let size = self.size();
106 &mut self.buffer.as_mut()[.. size]
107 }
108}
109
110impl<'a, B: AsRef<[u8]>> AsPacket<'a, Packet<&'a [u8]>> for B {
111 fn as_packet(&self) -> Result<Packet<&[u8]>> {
112 Packet::new(self.as_ref())
113 }
114}
115
116impl<'a, B: AsRef<[u8]> + AsMut<[u8]>> AsPacketMut<'a, Packet<&'a mut [u8]>> for B {
117 fn as_packet_mut(&mut self) -> Result<Packet<&mut [u8]>> {
118 Packet::new(self.as_mut())
119 }
120}
121
122impl<B: AsRef<[u8]>> P for Packet<B> {
123 fn split(&self) -> (&[u8], &[u8]) {
124 self.buffer.as_ref().split_at(8)
125 }
126}
127
128impl<B: AsRef<[u8]> + AsMut<[u8]>> PM for Packet<B> {
129 fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
130 self.buffer.as_mut().split_at_mut(8)
131 }
132}
133
134impl<B: AsRef<[u8]>> Packet<B> {
135 pub fn is_request(&self) -> bool {
137 Kind::from(self.buffer.as_ref()[0]) == Kind::InformationRequest
138 }
139
140 pub fn is_reply(&self) -> bool {
142 Kind::from(self.buffer.as_ref()[0]) == Kind::InformationReply
143 }
144
145 pub fn identifier(&self) -> u16 {
147 (&self.buffer.as_ref()[4 ..]).read_u16::<BigEndian>().unwrap()
148 }
149
150 pub fn sequence(&self) -> u16 {
152 (&self.buffer.as_ref()[6 ..]).read_u16::<BigEndian>().unwrap()
153 }
154}
155
156impl<B: AsRef<[u8]> + AsMut<[u8]>> Packet<B> {
157 pub fn make_request(&mut self) -> Result<&mut Self> {
159 self.buffer.as_mut()[0] = Kind::EchoRequest.into();
160
161 Ok(self)
162 }
163
164 pub fn make_reply(&mut self) -> Result<&mut Self> {
166 self.buffer.as_mut()[0] = Kind::EchoReply.into();
167
168 Ok(self)
169 }
170
171 pub fn set_identifier(&mut self, value: u16) -> Result<&mut Self> {
173 Cursor::new(&mut self.buffer.as_mut()[4 ..])
174 .write_u16::<BigEndian>(value)?;
175
176 Ok(self)
177 }
178
179 pub fn set_sequence(&mut self, value: u16) -> Result<&mut Self> {
181 Cursor::new(&mut self.buffer.as_mut()[6 ..])
182 .write_u16::<BigEndian>(value)?;
183
184 Ok(self)
185 }
186
187 pub fn checked(&mut self) -> Checked<'_, Self> {
189 Checked {
190 packet: self
191 }
192 }
193}
194
195impl<'a, B: AsRef<[u8]> + AsMut<[u8]> + 'a> Checked<'a, Packet<B>> {
196 pub fn make_request(&mut self) -> Result<&mut Self> {
198 self.packet.make_request()?;
199 Ok(self)
200 }
201
202 pub fn make_reply(&mut self) -> Result<&mut Self> {
204 self.packet.make_reply()?;
205 Ok(self)
206 }
207
208 pub fn set_identifier(&mut self, value: u16) -> Result<&mut Self> {
210 self.packet.set_identifier(value)?;
211 Ok(self)
212 }
213
214 pub fn set_sequence(&mut self, value: u16) -> Result<&mut Self> {
216 self.packet.set_sequence(value)?;
217 Ok(self)
218 }
219}