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