packet/icmp/previous/
packet.rs1use std::fmt;
16
17use crate::error::*;
18use crate::packet::{Packet as P, PacketMut as PM, AsPacket, AsPacketMut};
19use crate::size;
20use crate::ip;
21use crate::icmp::Kind;
22
23pub struct Packet<B> {
25 buffer: B,
26}
27
28sized!(Packet,
29 header {
30 min: 8,
31 max: 8,
32 size: 8,
33 }
34
35 payload {
36 min: <ip::v4::Packet<()> as size::header::Min>::min(),
37 max: <ip::v4::Packet<()> as size::header::Max>::max(),
38 size: p => {
39 if let Ok(ip) = p.packet() {
40 size::header::Size::size(&ip)
41 }
42 else {
43 p.buffer.as_ref().len() - 8
44 }
45 },
46 });
47
48impl<B: AsRef<[u8]>> fmt::Debug for Packet<B> {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("icmp::previous::Packet")
51 .field("packet", &self.packet())
52 .finish()
53 }
54}
55
56impl<B: AsRef<[u8]>> Packet<B> {
57 pub fn unchecked(buffer: B) -> Packet<B> {
60 Packet { buffer }
61 }
62
63 pub fn new(buffer: B) -> Result<Packet<B>> {
66 use crate::size::header::Min;
67
68 let packet = Packet::unchecked(buffer);
69
70 if packet.buffer.as_ref().len() < Self::min() {
71 Err(Error::SmallBuffer)?
72 }
73
74 match Kind::from(packet.buffer.as_ref()[0]) {
75 Kind::SourceQuench |
76 Kind::DestinationUnreachable |
77 Kind::TimeExceeded =>
78 (),
79
80 _ =>
81 Err(Error::InvalidPacket)?
82 }
83
84 Ok(packet)
85 }
86}
87
88impl<B: AsRef<[u8]>> Packet<B> {
89 pub fn to_owned(&self) -> Packet<Vec<u8>> {
96 Packet::unchecked(self.buffer.as_ref().to_vec())
97 }
98}
99
100impl<B: AsRef<[u8]>> AsRef<[u8]> for Packet<B> {
101 fn as_ref(&self) -> &[u8] {
102 use crate::size::Size;
103
104 &self.buffer.as_ref()[.. self.size()]
105 }
106}
107
108impl<B: AsRef<[u8]> + AsMut<[u8]>> AsMut<[u8]> for Packet<B> {
109 fn as_mut(&mut self) -> &mut [u8] {
110 use crate::size::Size;
111
112 let size = self.size();
113 &mut self.buffer.as_mut()[.. size]
114 }
115}
116
117impl<'a, B: AsRef<[u8]>> AsPacket<'a, Packet<&'a [u8]>> for B {
118 fn as_packet(&self) -> Result<Packet<&[u8]>> {
119 Packet::new(self.as_ref())
120 }
121}
122
123impl<'a, B: AsRef<[u8]> + AsMut<[u8]>> AsPacketMut<'a, Packet<&'a mut [u8]>> for B {
124 fn as_packet_mut(&mut self) -> Result<Packet<&mut [u8]>> {
125 Packet::new(self.as_mut())
126 }
127}
128
129impl<B: AsRef<[u8]>> P for Packet<B> {
130 fn split(&self) -> (&[u8], &[u8]) {
131 let (header, payload) = self.buffer.as_ref().split_at(8);
132 (&header[.. 4], payload)
133 }
134}
135
136impl<B: AsRef<[u8]> + AsMut<[u8]>> PM for Packet<B> {
137 fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
138 let (header, payload) = self.buffer.as_mut().split_at_mut(8);
139 (&mut header[.. 4], payload)
140 }
141}
142
143impl<B: AsRef<[u8]>> Packet<B> {
144 pub fn packet(&self) -> Result<ip::v4::Packet<&[u8]>> {
146 ip::v4::Packet::new(&self.buffer.as_ref()[8 ..])
147 }
148}