1use crate::error::*;
16use crate::packet::{Packet as P, PacketMut as PM, AsPacket, AsPacketMut};
17use crate::size;
18use crate::ip::{v4, v6};
19
20#[derive(Debug)]
22pub enum Packet<B: AsRef<[u8]>> {
23 V4(v4::Packet<B>),
25
26 V6(v6::Packet<B>),
28}
29
30impl<B: AsRef<[u8]>> Packet<B> {
31 pub fn unchecked(buffer: B) -> Packet<B> {
37 match buffer.as_ref()[0] >> 4 {
38 4 =>
39 Packet::V4(v4::Packet::unchecked(buffer)),
40
41 6 =>
42 Packet::V6(v6::Packet::unchecked(buffer)),
43
44 _ =>
45 panic!("not an IPv4 or IPv6 packet")
46 }
47 }
48
49 pub fn no_payload(buffer: B) -> Result<Packet<B>> {
51 match buffer.as_ref()[0] >> 4 {
52 4 =>
53 v4::Packet::no_payload(buffer).map(Packet::V4),
54
55 6 =>
56 v6::Packet::no_payload(buffer).map(Packet::V6),
57
58 _ =>
59 Err(Error::InvalidPacket)
60 }
61 }
62
63 pub fn new(buffer: B) -> Result<Packet<B>> {
65 match buffer.as_ref()[0] >> 4 {
66 4 =>
67 v4::Packet::new(buffer).map(Packet::V4),
68
69 6 =>
70 v6::Packet::new(buffer).map(Packet::V6),
71
72 _ =>
73 Err(Error::InvalidPacket)
74 }
75 }
76}
77
78impl<B: AsRef<[u8]>> From<v4::Packet<B>> for Packet<B> {
79 fn from(value: v4::Packet<B>) -> Packet<B> {
80 Packet::V4(value)
81 }
82}
83
84impl<B: AsRef<[u8]>> From<v6::Packet<B>> for Packet<B> {
85 fn from(value: v6::Packet<B>) -> Packet<B> {
86 Packet::V6(value)
87 }
88}
89
90impl<'a, B: AsRef<[u8]> + Clone> From<&'a v4::Packet<B>> for Packet<B> {
91 fn from(value: &'a v4::Packet<B>) -> Packet<B> {
92 Packet::V4(value.clone())
93 }
94}
95
96impl<'a, B: AsRef<[u8]> + Clone> From<&'a v6::Packet<B>> for Packet<B> {
97 fn from(value: &'a v6::Packet<B>) -> Packet<B> {
98 Packet::V6(value.clone())
99 }
100}
101
102impl<B: AsRef<[u8]>> Packet<B> {
103 pub fn to_owned(&self) -> Packet<Vec<u8>> {
110 match *self {
111 Packet::V4(ref packet) =>
112 Packet::V4(packet.to_owned()),
113
114 Packet::V6(ref packet) =>
115 Packet::V6(packet.to_owned()),
116 }
117 }
118}
119
120impl<B: AsRef<[u8]>> AsRef<[u8]> for Packet<B> {
121 fn as_ref(&self) -> &[u8] {
122 match *self {
123 Packet::V4(ref packet) =>
124 packet.as_ref(),
125
126 Packet::V6(ref packet) =>
127 packet.as_ref(),
128 }
129 }
130}
131
132impl<B: AsRef<[u8]> + AsMut<[u8]>> AsMut<[u8]> for Packet<B> {
133 fn as_mut(&mut self) -> &mut [u8] {
134 match *self {
135 Packet::V4(ref mut packet) =>
136 packet.as_mut(),
137
138 Packet::V6(ref mut packet) =>
139 packet.as_mut(),
140 }
141 }
142}
143
144impl<'a, B: AsRef<[u8]>> AsPacket<'a, Packet<&'a [u8]>> for B {
145 fn as_packet(&self) -> Result<Packet<&[u8]>> {
146 Packet::new(self.as_ref())
147 }
148}
149
150impl<'a, B: AsRef<[u8]> + AsMut<[u8]>> AsPacketMut<'a, Packet<&'a mut [u8]>> for B {
151 fn as_packet_mut(&mut self) -> Result<Packet<&mut [u8]>> {
152 Packet::new(self.as_mut())
153 }
154}
155
156impl<B: AsRef<[u8]>> P for Packet<B> {
157 fn split(&self) -> (&[u8], &[u8]) {
158 match *self {
159 Packet::V4(ref packet) =>
160 packet.split(),
161
162 Packet::V6(ref packet) =>
163 packet.split(),
164 }
165 }
166}
167
168impl<B: AsRef<[u8]> + AsMut<[u8]>> PM for Packet<B> {
169 fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
170 match *self {
171 Packet::V4(ref mut packet) =>
172 packet.split_mut(),
173
174 Packet::V6(ref mut packet) =>
175 packet.split_mut(),
176 }
177 }
178}
179
180impl<B: AsRef<[u8]>> size::header::Size for Packet<B> {
181 fn size(&self) -> usize {
182 match *self {
183 Packet::V4(ref packet) =>
184 size::header::Size::size(packet),
185
186 Packet::V6(ref packet) =>
187 size::header::Size::size(packet),
188 }
189 }
190}
191
192impl<B: AsRef<[u8]>> size::payload::Size for Packet<B> {
193 fn size(&self) -> usize {
194 match *self {
195 Packet::V4(ref packet) =>
196 size::payload::Size::size(packet),
197
198 Packet::V6(ref packet) =>
199 size::payload::Size::size(packet),
200 }
201 }
202}