1use crate::{err::macsec, *};
2
3#[derive(Clone, Debug, Eq, PartialEq)]
5pub struct LaxMacsecSlice<'a> {
6 pub header: MacsecHeaderSlice<'a>,
7 pub payload: LaxMacsecPayloadSlice<'a>,
8}
9
10impl<'a> LaxMacsecSlice<'a> {
11 pub fn from_slice(slice: &'a [u8]) -> Result<LaxMacsecSlice<'a>, macsec::HeaderSliceError> {
12 let header = MacsecHeaderSlice::from_slice(slice)?;
13 let (incomplete, payload_slice, len_source) =
15 if let Some(req_payload_len) = header.expected_payload_len() {
16 let required_len = header.header_len() + req_payload_len;
17 if slice.len() < required_len {
18 (
19 true,
20 unsafe {
22 core::slice::from_raw_parts(
23 slice.as_ptr().add(header.slice().len()),
24 slice.len() - header.slice().len(),
25 )
26 },
27 LenSource::Slice,
28 )
29 } else {
30 (
31 false,
32 unsafe {
35 core::slice::from_raw_parts(
36 slice.as_ptr().add(header.slice().len()),
37 req_payload_len,
38 )
39 },
40 LenSource::MacsecShortLength,
41 )
42 }
43 } else {
44 (
45 false,
46 unsafe {
48 core::slice::from_raw_parts(
49 slice.as_ptr().add(header.slice().len()),
50 slice.len() - header.slice().len(),
51 )
52 },
53 LenSource::Slice,
54 )
55 };
56
57 let payload = if let Some(ether_type) = header.next_ether_type() {
58 LaxMacsecPayloadSlice::Unmodified(LaxEtherPayloadSlice {
59 incomplete,
60 ether_type,
61 len_source,
62 payload: payload_slice,
63 })
64 } else {
65 LaxMacsecPayloadSlice::Modified {
66 incomplete,
67 payload: payload_slice,
68 }
69 };
70
71 Ok(LaxMacsecSlice { header, payload })
72 }
73
74 pub fn ether_payload(&self) -> Option<LaxEtherPayloadSlice<'a>> {
76 if let LaxMacsecPayloadSlice::Unmodified(e) = &self.payload {
77 Some(e.clone())
78 } else {
79 None
80 }
81 }
82
83 pub fn next_ether_type(&self) -> Option<EtherType> {
85 self.header.next_ether_type()
86 }
87}
88
89#[cfg(test)]
90mod test {
91 use super::*;
92 use crate::{err::LenError, test_gens::*};
93 use arrayvec::ArrayVec;
94 use proptest::prelude::*;
95
96 proptest! {
97 #[test]
98 fn from_slice(
99 macsec in macsec_any(),
100 ethertype in ether_type_any(),
101 non_zero_sl_unmodified in 3u8..=0b0011_1111,
102 non_zero_sl_modified in 1u8..=0b0011_1111
103 ) {
104 {
106 let mut macsec = macsec.clone();
107 macsec.ptype = MacsecPType::Unmodified(ethertype);
108 macsec.short_len = MacsecShortLen::try_from(non_zero_sl_unmodified).unwrap();
109
110 let mut payload = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize}>::new();
111 for v in 0..(non_zero_sl_unmodified - 2) {
112 payload.push(v);
113 }
114
115 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN}>::new();
116 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
117 bytes.try_extend_from_slice(&payload).unwrap();
118 let m = LaxMacsecSlice::from_slice(&bytes).unwrap();
119 assert_eq!(
120 m.payload,
121 LaxMacsecPayloadSlice::Unmodified(LaxEtherPayloadSlice{
122 incomplete: false,
123 ether_type: ethertype,
124 len_source: LenSource::MacsecShortLength,
125 payload: &payload
126 })
127 );
128 assert_eq!(
129 m.ether_payload(),
130 Some(LaxEtherPayloadSlice{
131 incomplete: false,
132 ether_type: ethertype,
133 len_source: LenSource::MacsecShortLength,
134 payload: &payload
135 })
136 );
137 assert_eq!(m.next_ether_type(), Some(ethertype));
138 }
139 {
141 let mut macsec = macsec.clone();
142 macsec.ptype = MacsecPType::Unmodified(ethertype);
143 macsec.short_len = MacsecShortLen::try_from(non_zero_sl_unmodified).unwrap();
144
145 let mut payload = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize}>::new();
146 for v in 0..non_zero_sl_unmodified-2-1 {
147 payload.push(v);
148 }
149
150 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN}>::new();
151 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
152 bytes.try_extend_from_slice(&payload).unwrap();
153 let m = LaxMacsecSlice::from_slice(&bytes).unwrap();
154 assert_eq!(
155 m.payload,
156 LaxMacsecPayloadSlice::Unmodified(LaxEtherPayloadSlice{
157 incomplete: true,
158 ether_type: ethertype,
159 len_source: LenSource::Slice,
160 payload: &payload
161 })
162 );
163 assert_eq!(
164 m.ether_payload(),
165 Some(LaxEtherPayloadSlice{
166 incomplete: true,
167 ether_type: ethertype,
168 len_source: LenSource::Slice,
169 payload: &payload
170 })
171 );
172 assert_eq!(m.next_ether_type(), Some(ethertype));
173 }
174 {
176 let mut macsec = macsec.clone();
177 macsec.ptype = MacsecPType::Unmodified(ethertype);
178 macsec.short_len = MacsecShortLen::ZERO;
179
180 let mut payload = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + 1}>::new();
181 for v in 0..non_zero_sl_unmodified+1 {
182 payload.push(v);
183 }
184
185 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN + 1}>::new();
186 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
187 bytes.try_extend_from_slice(&payload).unwrap();
188 let m = LaxMacsecSlice::from_slice(&bytes).unwrap();
189 assert_eq!(
190 m.payload,
191 LaxMacsecPayloadSlice::Unmodified(LaxEtherPayloadSlice{
192 incomplete: false,
193 ether_type: ethertype,
194 len_source: LenSource::Slice,
195 payload: &payload
196 })
197 );
198 assert_eq!(
199 m.ether_payload(),
200 Some(LaxEtherPayloadSlice{
201 incomplete: false,
202 ether_type: ethertype,
203 len_source: LenSource::Slice,
204 payload: &payload
205 })
206 );
207 assert_eq!(m.next_ether_type(), Some(ethertype));
208 }
209 for ptype in [MacsecPType::Modified, MacsecPType::Encrypted, MacsecPType::EncryptedUnmodified] {
211 let mut macsec = macsec.clone();
212 macsec.ptype = ptype;
213 macsec.short_len = MacsecShortLen::try_from(non_zero_sl_modified).unwrap();
214
215 let mut payload = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize}>::new();
216 for v in 0..non_zero_sl_modified {
217 payload.push(v);
218 }
219
220 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN}>::new();
221 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
222 bytes.try_extend_from_slice(&payload).unwrap();
223 let m = LaxMacsecSlice::from_slice(&bytes).unwrap();
224 assert_eq!(
225 m.payload,
226 LaxMacsecPayloadSlice::Modified{
227 incomplete: false,
228 payload: &payload,
229 }
230 );
231 assert_eq!(m.ether_payload(), None);
232 assert_eq!(m.next_ether_type(), None);
233 }
234 for ptype in [MacsecPType::Modified, MacsecPType::Encrypted, MacsecPType::EncryptedUnmodified] {
236 let mut macsec = macsec.clone();
237 macsec.ptype = ptype;
238 macsec.short_len = MacsecShortLen::try_from(non_zero_sl_modified).unwrap();
239
240 let mut payload = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize}>::new();
241 for v in 0..non_zero_sl_modified-1 {
242 payload.push(v);
243 }
244
245 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN}>::new();
246 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
247 bytes.try_extend_from_slice(&payload).unwrap();
248 let m = LaxMacsecSlice::from_slice(&bytes).unwrap();
249 assert_eq!(
250 m.payload,
251 LaxMacsecPayloadSlice::Modified{
252 incomplete: true,
253 payload: &payload,
254 }
255 );
256 assert_eq!(m.ether_payload(), None);
257 assert_eq!(m.next_ether_type(), None);
258 }
259 for ptype in [MacsecPType::Modified, MacsecPType::Encrypted, MacsecPType::EncryptedUnmodified] {
261 let mut macsec = macsec.clone();
262 macsec.ptype = ptype;
263 macsec.short_len = MacsecShortLen::ZERO;
264
265 let mut payload = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + 1}>::new();
266 for v in 0..non_zero_sl_modified+1 {
267 payload.push(v);
268 }
269
270 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN + 1}>::new();
271 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
272 bytes.try_extend_from_slice(&payload).unwrap();
273 let m = LaxMacsecSlice::from_slice(&bytes).unwrap();
274 assert_eq!(
275 m.payload,
276 LaxMacsecPayloadSlice::Modified{
277 incomplete: false,
278 payload: &payload,
279 }
280 );
281 assert_eq!(m.ether_payload(), None);
282 assert_eq!(m.next_ether_type(), None);
283 }
284 for ptype in [MacsecPType::Unmodified(ethertype), MacsecPType::Modified, MacsecPType::Encrypted, MacsecPType::EncryptedUnmodified] {
286 let mut macsec = macsec.clone();
287 macsec.ptype = ptype;
288 macsec.short_len = MacsecShortLen::ZERO;
289
290 let mut bytes = ArrayVec::<u8, {MacsecShortLen::MAX_U8 as usize + MacsecHeader::MAX_LEN + 1}>::new();
291 bytes.try_extend_from_slice(&macsec.to_bytes()).unwrap();
292 let m = LaxMacsecSlice::from_slice(&bytes[..bytes.len() - 1]);
293 assert_eq!(
294 m,
295 Err(macsec::HeaderSliceError::Len(LenError{
296 required_len: macsec.header_len(),
297 len: macsec.header_len() - 1,
298 len_source: LenSource::Slice,
299 layer: err::Layer::MacsecHeader,
300 layer_start_offset: 0
301 }))
302 );
303 }
304 }
305 }
306}