1 use crate::{err::Layer, *}; 2 3 /// Packet slice split into multiple slices containing 4 /// the different headers & payload. 5 #[derive(Clone, Debug, Eq, PartialEq)] 6 pub struct LaxSlicedPacket<'a> { 7 /// Ethernet II header if present. 8 pub link: Option<LinkSlice<'a>>, 9 10 /// Single or double vlan headers if present. 11 pub vlan: Option<VlanSlice<'a>>, 12 13 /// IPv4 or IPv6 header, IP extension headers & payload if present. 14 pub net: Option<LaxNetSlice<'a>>, 15 16 /// TCP or UDP header & payload if present. 17 pub transport: Option<TransportSlice<'a>>, 18 19 /// Error that stopped the parsing and the layer on which the stop occurred. 20 pub stop_err: Option<(err::packet::SliceError, Layer)>, 21 } 22 23 impl<'a> LaxSlicedPacket<'a> { 24 /// Separates a network packet slice into different slices containing the 25 /// headers from the ethernet header downwards with lax length checks and 26 /// non-terminating errors. 27 /// 28 /// # Example 29 /// 30 /// Basic usage: 31 /// 32 ///``` 33 /// # use etherparse::{Ethernet2Header, PacketBuilder}; 34 /// # let builder = PacketBuilder:: 35 /// # ethernet2([1,2,3,4,5,6], //source mac 36 /// # [7,8,9,10,11,12]) //destionation mac 37 /// # .ipv4([192,168,1,1], //source ip 38 /// # [192,168,1,2], //destination ip 39 /// # 20) //time to life 40 /// # .udp(21, //source port 41 /// # 1234); //desitnation port 42 /// # // payload of the udp packet 43 /// # let payload = [1,2,3,4,5,6,7,8]; 44 /// # // get some memory to store the serialized data 45 /// # let mut packet = Vec::<u8>::with_capacity( 46 /// # builder.size(payload.len()) 47 /// # ); 48 /// # builder.write(&mut packet, &payload).unwrap(); 49 /// # 50 /// use etherparse::{ether_type, LaxSlicedPacket, LenSource}; 51 /// 52 /// match LaxSlicedPacket::from_ethernet(&packet) { 53 /// Err(value) => { 54 /// // An error is returned in case the ethernet II header could 55 /// // not be parsed (other errors are stored in the "stop_err" field) 56 /// println!("Err {:?}", value) 57 /// }, 58 /// Ok(value) => { 59 /// if let Some((stop_err, error_layer)) = value.stop_err.as_ref() { 60 /// // error was encountered after parsing the ethernet 2 header 61 /// println!("Error on layer {}: {:?}", error_layer, stop_err); 62 /// } 63 /// 64 /// // parts that could be parsed without error 65 /// println!("link: {:?}", value.link); 66 /// println!("vlan: {:?}", value.vlan); 67 /// println!("net: {:?}", value.net); 68 /// println!("transport: {:?}", value.transport); 69 /// 70 /// // net (ip) & transport (udp or tcp) 71 /// println!("net: {:?}", value.net); 72 /// if let Some(ip_payload) = value.net.as_ref().map(|net| net.ip_payload_ref()).flatten() { 73 /// // the ip payload len_source field can be used to check 74 /// // if the slice length was used as a fallback value 75 /// if ip_payload.len_source == LenSource::Slice { 76 /// println!(" Used slice length as fallback to identify the IP payload"); 77 /// } else { 78 /// println!(" IP payload could correctly be identfied via the length field in the header"); 79 /// } 80 /// } 81 /// println!("transport: {:?}", value.transport); 82 /// } 83 /// } 84 /// 85 /// ``` from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::LenError>86 pub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::LenError> { 87 LaxSlicedPacketCursor::parse_from_ethernet2(slice) 88 } 89 90 /// Separates a network packet slice into different slices containing the headers using 91 /// the given `ether_type` number to identify the first header with lax length 92 /// checks and non-terminating errors. 93 /// 94 /// The result is returned as a [`LaxSlicedPacket`] struct. Currently supported 95 /// ether type numbers are: 96 /// 97 /// * `ether_type::IPV4` 98 /// * `ether_type::IPV6` 99 /// * `ether_type::VLAN_TAGGED_FRAME` 100 /// * `ether_type::PROVIDER_BRIDGING` 101 /// * `ether_type::VLAN_DOUBLE_TAGGED_FRAME` 102 /// 103 /// If an unsupported ether type is given the given slice will be set as payload 104 /// and all other fields will be set to `None`. 105 /// 106 /// # Example 107 /// 108 /// Basic usage: 109 /// 110 ///``` 111 /// # use etherparse::{Ethernet2Header, PacketBuilder}; 112 /// # let builder = PacketBuilder:: 113 /// # ethernet2([1,2,3,4,5,6], //source mac 114 /// # [7,8,9,10,11,12]) //destionation mac 115 /// # .ipv4([192,168,1,1], //source ip 116 /// # [192,168,1,2], //destination ip 117 /// # 20) //time to life 118 /// # .udp(21, //source port 119 /// # 1234); //desitnation port 120 /// # // payload of the udp packet 121 /// # let payload = [1,2,3,4,5,6,7,8]; 122 /// # // get some memory to store the serialized data 123 /// # let mut complete_packet = Vec::<u8>::with_capacity( 124 /// # builder.size(payload.len()) 125 /// # ); 126 /// # builder.write(&mut complete_packet, &payload).unwrap(); 127 /// # 128 /// # // skip ethernet 2 header so we can parse from there downwards 129 /// # let packet = &complete_packet[Ethernet2Header::LEN..]; 130 /// # 131 /// use etherparse::{ether_type, LaxSlicedPacket}; 132 /// 133 /// let packet = LaxSlicedPacket::from_ether_type(ether_type::IPV4, packet); 134 /// if let Some((stop_err, error_layer)) = packet.stop_err.as_ref() { 135 /// // in case an error is encountered parsing is stopped 136 /// println!("Error on layer {}: {:?}", error_layer, stop_err); 137 /// } 138 /// 139 /// // parts that could be parsed without error 140 /// println!("link: {:?}", packet.link); 141 /// println!("vlan: {:?}", packet.vlan); 142 /// println!("net: {:?}", packet.net); 143 /// println!("transport: {:?}", packet.transport); 144 /// 145 /// ``` from_ether_type(ether_type: EtherType, slice: &'a [u8]) -> LaxSlicedPacket<'a>146 pub fn from_ether_type(ether_type: EtherType, slice: &'a [u8]) -> LaxSlicedPacket<'a> { 147 LaxSlicedPacketCursor::parse_from_ether_type(ether_type, slice) 148 } 149 150 /// Separates a network packet slice into different slices containing 151 /// the headers from the ip header downwards with lax length checks 152 /// and will still return a result even if an error is encountered in 153 /// a layer (except IP). 154 /// 155 /// This function has two main differences to `SlicedPacket::from_ip`: 156 /// 157 /// * Errors encountered bellow the IpHeader will only stop the parsing and 158 /// return an `Ok` with the successfully parsed parts and the error as optional. 159 /// Only if an unrecoverable error is encountered in the IP header itself an 160 /// `Err` is returned. 161 /// * Length in the IP header & UDP headers are allowed to be inconsistent with the 162 /// given slice length (e.g. data is missing from the slice). In this case it falls 163 /// back to the length of slice. See [`LaxIpSlice::from_slice`] for a detailed 164 /// description of when the slice length is used as a fallback. 165 /// 166 /// The result is returned as a [`SlicedPacket`] struct. This function 167 /// assumes the given data starts with an IPv4 or IPv6 header. 168 /// 169 /// # Examples 170 /// 171 /// Basic usage: 172 /// 173 ///``` 174 /// # use etherparse::{PacketBuilder, IpSlice, LenSource}; 175 /// # let builder = PacketBuilder:: 176 /// # ipv4([192,168,1,1], //source ip 177 /// # [192,168,1,2], //destination ip 178 /// # 20) //time to life 179 /// # .udp(21, //source port 180 /// # 1234); //desitnation port 181 /// # //payload of the udp packet 182 /// # let payload = [1,2,3,4,5,6,7,8]; 183 /// # //get some memory to store the serialized data 184 /// # let mut packet = Vec::<u8>::with_capacity( 185 /// # builder.size(payload.len())); 186 /// # builder.write(&mut packet, &payload).unwrap(); 187 /// use etherparse::LaxSlicedPacket; 188 /// 189 /// match LaxSlicedPacket::from_ip(&packet) { 190 /// Err(value) => { 191 /// // An error is returned in case the ip header could 192 /// // not parsed (other errors are stored in the "stop_err" field) 193 /// println!("Err {:?}", value) 194 /// }, 195 /// Ok(value) => { 196 /// if let Some((stop_err, error_layer)) = value.stop_err.as_ref() { 197 /// // error is encountered after the ip header (stops parsing) 198 /// println!("Error on layer {}: {:?}", error_layer, stop_err); 199 /// } 200 /// 201 /// // link & vlan fields are empty when parsing from ip downwards 202 /// assert_eq!(None, value.link); 203 /// assert_eq!(None, value.vlan); 204 /// 205 /// // net (ip) & transport (udp or tcp) 206 /// println!("net: {:?}", value.net); 207 /// if let Some(ip_payload) = value.net.as_ref().map(|net| net.ip_payload_ref()).flatten() { 208 /// // the ip payload len_source field can be used to check 209 /// // if the slice length was used as a fallback value 210 /// if ip_payload.len_source == LenSource::Slice { 211 /// println!(" Used slice length as fallback to identify the IP payload"); 212 /// } else { 213 /// println!(" IP payload could correctly be identfied via the length field in the header"); 214 /// } 215 /// } 216 /// println!("transport: {:?}", value.transport); 217 /// } 218 /// } 219 /// ``` from_ip(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::ip::LaxHeaderSliceError>220 pub fn from_ip(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::ip::LaxHeaderSliceError> { 221 LaxSlicedPacketCursor::parse_from_ip(slice) 222 } 223 224 /// Returns the last ether payload of the packet (if one is present). 225 /// 226 /// If VLAN header is present the payload after the most inner VLAN 227 /// header is returned and if there is no VLAN header is present in the 228 /// link field is returned. ether_payload(&self) -> Option<EtherPayloadSlice<'a>>229 pub fn ether_payload(&self) -> Option<EtherPayloadSlice<'a>> { 230 if let Some(vlan) = self.vlan.as_ref() { 231 match vlan { 232 VlanSlice::SingleVlan(s) => Some(s.payload()), 233 VlanSlice::DoubleVlan(s) => Some(s.payload()), 234 } 235 } else if let Some(link) = self.link.as_ref() { 236 match link { 237 LinkSlice::Ethernet2(e) => Some(e.payload()), 238 LinkSlice::LinuxSll(e) => match e.protocol_type() { 239 LinuxSllProtocolType::EtherType(_) 240 | LinuxSllProtocolType::LinuxNonstandardEtherType(_) => { 241 Some(EtherPayloadSlice::try_from(e.payload()).ok()?) 242 } 243 _ => None, 244 }, 245 LinkSlice::EtherPayload(e) => Some(e.clone()), 246 LinkSlice::LinuxSllPayload(e) => match e.protocol_type { 247 LinuxSllProtocolType::EtherType(_) 248 | LinuxSllProtocolType::LinuxNonstandardEtherType(_) => { 249 Some(EtherPayloadSlice::try_from(e.clone()).ok()?) 250 } 251 _ => None, 252 }, 253 } 254 } else { 255 None 256 } 257 } 258 259 /// Return the IP payload after the the IP header and the IP extension 260 /// headers (if one is present). ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>>261 pub fn ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>> { 262 if let Some(net) = self.net.as_ref() { 263 use LaxNetSlice::*; 264 match net { 265 Ipv4(v) => Some(v.payload()), 266 Ipv6(v) => Some(v.payload()), 267 } 268 } else { 269 None 270 } 271 } 272 } 273 274 #[cfg(test)] 275 mod test { 276 use super::*; 277 use crate::err::{packet::SliceError, LenError}; 278 use crate::test_packet::TestPacket; 279 280 const VLAN_ETHER_TYPES: [EtherType; 3] = [ 281 ether_type::VLAN_TAGGED_FRAME, 282 ether_type::PROVIDER_BRIDGING, 283 ether_type::VLAN_DOUBLE_TAGGED_FRAME, 284 ]; 285 286 #[test] clone_eq()287 fn clone_eq() { 288 let header = LaxSlicedPacket { 289 link: None, 290 vlan: None, 291 net: None, 292 transport: None, 293 stop_err: None, 294 }; 295 assert_eq!(header.clone(), header); 296 } 297 298 #[test] debug()299 fn debug() { 300 use alloc::format; 301 let header = LaxSlicedPacket { 302 link: None, 303 vlan: None, 304 net: None, 305 transport: None, 306 stop_err: None, 307 }; 308 assert_eq!( 309 format!("{:?}", header), 310 format!( 311 "LaxSlicedPacket {{ link: {:?}, vlan: {:?}, net: {:?}, transport: {:?}, stop_err: {:?} }}", 312 header.link, header.vlan, header.net, header.transport, header.stop_err 313 ) 314 ); 315 } 316 317 #[test] ether_payload()318 fn ether_payload() { 319 use alloc::vec::*; 320 321 // no content 322 assert_eq!( 323 LaxSlicedPacket { 324 link: None, 325 vlan: None, 326 net: None, 327 transport: None, 328 stop_err: None 329 } 330 .ether_payload(), 331 None 332 ); 333 334 // only ethernet header II 335 { 336 let payload = [1, 2, 3, 4]; 337 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + 4); 338 buf.extend_from_slice( 339 &Ethernet2Header { 340 ether_type: EtherType::WAKE_ON_LAN, 341 ..Default::default() 342 } 343 .to_bytes(), 344 ); 345 buf.extend_from_slice(&payload); 346 assert_eq!( 347 LaxSlicedPacket::from_ethernet(&buf) 348 .unwrap() 349 .ether_payload(), 350 Some(EtherPayloadSlice { 351 ether_type: EtherType::WAKE_ON_LAN, 352 payload: &payload 353 }) 354 ); 355 } 356 357 // ether type payload 358 { 359 let payload = [1, 2, 3, 4]; 360 assert_eq!( 361 LaxSlicedPacket { 362 link: Some(LinkSlice::EtherPayload(EtherPayloadSlice { 363 ether_type: EtherType::WAKE_ON_LAN, 364 payload: &payload 365 })), 366 vlan: None, 367 net: None, 368 transport: None, 369 stop_err: None, 370 } 371 .ether_payload(), 372 Some(EtherPayloadSlice { 373 ether_type: EtherType::WAKE_ON_LAN, 374 payload: &payload 375 }) 376 ); 377 } 378 379 // single vlan header 380 { 381 let payload = [1, 2, 3, 4]; 382 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN + 4); 383 buf.extend_from_slice( 384 &Ethernet2Header { 385 ether_type: EtherType::VLAN_TAGGED_FRAME, 386 ..Default::default() 387 } 388 .to_bytes(), 389 ); 390 buf.extend_from_slice( 391 &SingleVlanHeader { 392 ether_type: EtherType::WAKE_ON_LAN, 393 ..Default::default() 394 } 395 .to_bytes(), 396 ); 397 buf.extend_from_slice(&payload); 398 assert_eq!( 399 LaxSlicedPacket::from_ethernet(&buf) 400 .unwrap() 401 .ether_payload(), 402 Some(EtherPayloadSlice { 403 ether_type: EtherType::WAKE_ON_LAN, 404 payload: &payload 405 }) 406 ); 407 } 408 409 // double vlan header 410 { 411 let payload = [1, 2, 3, 4]; 412 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN * 2 + 4); 413 buf.extend_from_slice( 414 &Ethernet2Header { 415 ether_type: EtherType::VLAN_DOUBLE_TAGGED_FRAME, 416 ..Default::default() 417 } 418 .to_bytes(), 419 ); 420 buf.extend_from_slice( 421 &SingleVlanHeader { 422 ether_type: EtherType::VLAN_TAGGED_FRAME, 423 ..Default::default() 424 } 425 .to_bytes(), 426 ); 427 buf.extend_from_slice( 428 &SingleVlanHeader { 429 ether_type: EtherType::WAKE_ON_LAN, 430 ..Default::default() 431 } 432 .to_bytes(), 433 ); 434 buf.extend_from_slice(&payload); 435 assert_eq!( 436 LaxSlicedPacket::from_ethernet(&buf) 437 .unwrap() 438 .ether_payload(), 439 Some(EtherPayloadSlice { 440 ether_type: EtherType::WAKE_ON_LAN, 441 payload: &payload 442 }) 443 ); 444 } 445 } 446 447 #[test] ip_payload()448 fn ip_payload() { 449 use alloc::vec::*; 450 451 // no content 452 assert_eq!( 453 LaxSlicedPacket { 454 link: None, 455 vlan: None, 456 net: None, 457 transport: None, 458 stop_err: None, 459 } 460 .ip_payload(), 461 None 462 ); 463 464 // ipv4 465 { 466 let payload = [1, 2, 3, 4]; 467 let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4); 468 buf.extend_from_slice( 469 &Ipv4Header { 470 protocol: IpNumber::ARIS, 471 total_len: Ipv4Header::MIN_LEN_U16 + 4, 472 ..Default::default() 473 } 474 .to_bytes(), 475 ); 476 buf.extend_from_slice(&payload); 477 assert_eq!( 478 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(), 479 Some(&LaxIpPayloadSlice { 480 payload: &payload, 481 ip_number: IpNumber::ARIS, 482 fragmented: false, 483 len_source: LenSource::Ipv4HeaderTotalLen, 484 incomplete: false, 485 }) 486 ); 487 } 488 489 // ipv6 490 { 491 let payload = [1, 2, 3, 4]; 492 let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4); 493 buf.extend_from_slice( 494 &Ipv6Header { 495 payload_length: 4, 496 next_header: IpNumber::ARGUS, 497 ..Default::default() 498 } 499 .to_bytes(), 500 ); 501 buf.extend_from_slice(&payload); 502 assert_eq!( 503 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(), 504 Some(&LaxIpPayloadSlice { 505 payload: &payload, 506 ip_number: IpNumber::ARGUS, 507 fragmented: false, 508 len_source: LenSource::Ipv6HeaderPayloadLen, 509 incomplete: false, 510 }) 511 ); 512 } 513 } 514 515 #[test] from_x_slice()516 fn from_x_slice() { 517 // no eth 518 from_x_slice_vlan_variants(&TestPacket { 519 link: None, 520 vlan: None, 521 net: None, 522 transport: None, 523 }); 524 525 // eth 526 { 527 let eth = Ethernet2Header { 528 source: [1, 2, 3, 4, 5, 6], 529 destination: [1, 2, 3, 4, 5, 6], 530 ether_type: 0.into(), 531 }; 532 let test = TestPacket { 533 link: Some(LinkHeader::Ethernet2(eth.clone())), 534 vlan: None, 535 net: None, 536 transport: None, 537 }; 538 539 // ok ethernet header (with unknown next) 540 from_x_slice_vlan_variants(&test); 541 542 // eth len error 543 { 544 let data = test.to_vec(&[]); 545 for len in 0..data.len() { 546 assert_test_result(&test, &[], &data[..len], None, None); 547 } 548 } 549 } 550 551 // unknown ether_type 552 { 553 let payload = [1, 2, 3, 4]; 554 let actual = LaxSlicedPacket::from_ether_type(0.into(), &payload); 555 assert_eq!( 556 actual.link, 557 Some(LinkSlice::EtherPayload(EtherPayloadSlice { 558 ether_type: 0.into(), 559 payload: &payload 560 })) 561 ); 562 assert_eq!(None, actual.vlan); 563 assert_eq!(None, actual.net); 564 assert_eq!(None, actual.transport); 565 assert_eq!(None, actual.stop_err); 566 } 567 } 568 from_x_slice_vlan_variants(base: &TestPacket)569 fn from_x_slice_vlan_variants(base: &TestPacket) { 570 // none 571 from_x_slice_ip_variants(base); 572 573 // single vlan header 574 { 575 let single = SingleVlanHeader { 576 pcp: 1.try_into().unwrap(), 577 drop_eligible_indicator: false, 578 vlan_id: 2.try_into().unwrap(), 579 ether_type: 3.into(), 580 }; 581 582 for vlan_ether_type in VLAN_ETHER_TYPES { 583 let mut test = base.clone(); 584 test.set_ether_type(vlan_ether_type); 585 test.vlan = Some(VlanHeader::Single(single.clone())); 586 587 // ok vlan header 588 from_x_slice_ip_variants(&test); 589 590 // len error 591 { 592 let data = test.to_vec(&[]); 593 for len in 0..single.header_len() { 594 let base_len = test.len(&[]) - single.header_len(); 595 596 let err = LenError { 597 required_len: single.header_len(), 598 len, 599 len_source: LenSource::Slice, 600 layer: Layer::VlanHeader, 601 layer_start_offset: base_len, 602 }; 603 assert_test_result( 604 &test, 605 &[], 606 &data[..base_len + len], 607 None, 608 Some((SliceError::Len(err.clone()), Layer::VlanHeader)), 609 ); 610 } 611 } 612 } 613 } 614 615 // double vlan header 616 for outer_vlan_ether_type in VLAN_ETHER_TYPES { 617 for inner_vlan_ether_type in VLAN_ETHER_TYPES { 618 let double = DoubleVlanHeader { 619 outer: SingleVlanHeader { 620 pcp: 1.try_into().unwrap(), 621 drop_eligible_indicator: false, 622 vlan_id: 2.try_into().unwrap(), 623 ether_type: inner_vlan_ether_type, 624 }, 625 inner: SingleVlanHeader { 626 pcp: 1.try_into().unwrap(), 627 drop_eligible_indicator: false, 628 vlan_id: 2.try_into().unwrap(), 629 ether_type: 3.into(), 630 }, 631 }; 632 let mut test = base.clone(); 633 test.set_ether_type(outer_vlan_ether_type); 634 test.vlan = Some(VlanHeader::Double(double.clone())); 635 636 // ok double vlan header 637 from_x_slice_ip_variants(&test); 638 639 // len error 640 { 641 let data = test.to_vec(&[]); 642 for len in 0..SingleVlanHeader::LEN { 643 let base_len = test.len(&[]) - SingleVlanHeader::LEN; 644 645 let err = LenError { 646 required_len: SingleVlanHeader::LEN, 647 len, 648 len_source: LenSource::Slice, 649 layer: Layer::VlanHeader, 650 layer_start_offset: base_len, 651 }; 652 assert_test_result( 653 &test, 654 &[], 655 &data[..base_len + len], 656 None, 657 Some((SliceError::Len(err.clone()), Layer::VlanHeader)), 658 ); 659 } 660 } 661 } 662 } 663 } 664 from_x_slice_ip_variants(base: &TestPacket)665 fn from_x_slice_ip_variants(base: &TestPacket) { 666 // none 667 from_x_slice_transport_variants(base); 668 669 // ipv4 670 for fragmented in [false, true] { 671 let ipv4 = { 672 let mut ipv4 = 673 Ipv4Header::new(0, 1, 2.into(), [3, 4, 5, 6], [7, 8, 9, 10]).unwrap(); 674 ipv4.more_fragments = fragmented; 675 ipv4 676 }; 677 678 { 679 let mut test = base.clone(); 680 test.set_ether_type(ether_type::IPV4); 681 test.net = Some(NetHeaders::Ipv4(ipv4.clone(), Default::default())); 682 test.set_payload_len(0); 683 684 // ok ipv4 685 from_x_slice_transport_variants(&test); 686 687 // ipv4 len error 688 { 689 let data = test.to_vec(&[]); 690 for len in 0..ipv4.header_len() { 691 let base_len = test.len(&[]) - ipv4.header_len(); 692 693 let err = LenError { 694 required_len: if len < 1 { 1 } else { ipv4.header_len() }, 695 len, 696 len_source: LenSource::Slice, 697 layer: if len < 1 { 698 Layer::IpHeader 699 } else { 700 Layer::Ipv4Header 701 }, 702 layer_start_offset: base_len, 703 }; 704 705 assert_test_result( 706 &test, 707 &[], 708 &data[..base_len + len], 709 Some(err::ip::LaxHeaderSliceError::Len(err.clone())), 710 Some((SliceError::Len(err.clone()), Layer::IpHeader)), 711 ); 712 } 713 } 714 715 // ipv4 content error (ihl length too small) 716 { 717 use err::ip::HeaderError::*; 718 719 let mut data = test.to_vec(&[]); 720 let ipv4_offset = data.len() - ipv4.header_len(); 721 722 // set the ihl to 0 to trigger a content error 723 data[ipv4_offset] = 0b1111_0000 & data[ipv4_offset]; 724 725 assert_test_result( 726 &test, 727 &[], 728 &data, 729 Some(err::ip::LaxHeaderSliceError::Content( 730 Ipv4HeaderLengthSmallerThanHeader { ihl: 0 }, 731 )), 732 Some(( 733 SliceError::Ip(Ipv4HeaderLengthSmallerThanHeader { ihl: 0 }), 734 Layer::IpHeader, 735 )), 736 ); 737 } 738 739 // ipv 4total length too small (does not change the output) 740 { 741 let mut data = test.to_vec(&[]); 742 let ipv4_offset = data.len() - ipv4.header_len(); 743 744 // set the total length to 0 to trigger a content error 745 data[ipv4_offset + 2] = 0; 746 data[ipv4_offset + 3] = 0; 747 748 let mut mod_test = test.clone(); 749 mod_test.net = Some({ 750 let (h, e) = test.net.as_ref().map(|v| v.ipv4_ref()).flatten().unwrap(); 751 let mut ipv4 = h.clone(); 752 ipv4.total_len = 0; 753 NetHeaders::Ipv4(ipv4, e.clone()) 754 }); 755 756 assert_test_result(&mod_test, &[], &data, None, None); 757 } 758 } 759 760 // ipv4 extension content error 761 { 762 let auth = IpAuthHeader::new(0.into(), 1, 2, &[]).unwrap(); 763 764 let mut test = base.clone(); 765 test.set_ether_type(ether_type::IPV4); 766 test.net = Some(NetHeaders::Ipv4( 767 { 768 let mut ipv4 = ipv4.clone(); 769 ipv4.protocol = ip_number::AUTH; 770 ipv4 771 }, 772 Ipv4Extensions { 773 auth: Some(auth.clone()), 774 }, 775 )); 776 test.set_payload_len(0); 777 778 // ok ipv4 & extension 779 from_x_slice_transport_variants(&test); 780 781 // ipv4 extension len error 782 for len in 0..auth.header_len() { 783 // set payload length 784 let mut test = test.clone(); 785 test.set_payload_le_from_ip_on( 786 -1 * (auth.header_len() as isize) + (len as isize), 787 ); 788 789 let data = test.to_vec(&[]); 790 let base_len = test.len(&[]) - auth.header_len(); 791 792 let err = LenError { 793 required_len: auth.header_len(), 794 len, 795 len_source: LenSource::Ipv4HeaderTotalLen, 796 layer: Layer::IpAuthHeader, 797 layer_start_offset: base_len, 798 }; 799 800 assert_test_result( 801 &test, 802 &[], 803 &data, 804 None, 805 Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)), 806 ); 807 } 808 809 // ipv4 extension content error 810 { 811 let mut data = test.to_vec(&[]); 812 let auth_offset = data.len() - auth.header_len(); 813 814 // set the icv len too smaller then allowed 815 data[auth_offset + 1] = 0; 816 817 // expect an error 818 assert_test_result( 819 &test, 820 &[], 821 &data, 822 None, 823 Some(( 824 SliceError::Ipv4Exts(err::ip_auth::HeaderError::ZeroPayloadLen), 825 Layer::IpAuthHeader, 826 )), 827 ); 828 } 829 } 830 } 831 832 // ipv6 833 { 834 let ipv6 = Ipv6Header { 835 traffic_class: 0, 836 flow_label: 1.try_into().unwrap(), 837 payload_length: 2, 838 next_header: 3.into(), 839 hop_limit: 4, 840 source: [0; 16], 841 destination: [0; 16], 842 }; 843 844 // ipv6 header only 845 { 846 let mut test = base.clone(); 847 test.set_ether_type(ether_type::IPV6); 848 test.net = Some(NetHeaders::Ipv6(ipv6.clone(), Default::default())); 849 test.set_payload_len(0); 850 851 // ok ipv6 852 from_x_slice_transport_variants(&test); 853 854 // header len ipv6 855 { 856 let data = test.to_vec(&[]); 857 for len in 0..ipv6.header_len() { 858 let base_len = test.len(&[]) - ipv6.header_len(); 859 860 let err = err::LenError { 861 required_len: if len < 1 { 1 } else { ipv6.header_len() }, 862 len, 863 len_source: LenSource::Slice, 864 layer: if len < 1 { 865 Layer::IpHeader 866 } else { 867 Layer::Ipv6Header 868 }, 869 layer_start_offset: base_len, 870 }; 871 872 assert_test_result( 873 &test, 874 &[], 875 &data[..base_len + len], 876 Some(err::ip::LaxHeaderSliceError::Len(err.clone())), 877 Some(( 878 SliceError::Len({ 879 if len < 1 { 880 let mut err = err.clone(); 881 err.required_len = 1; 882 err.layer = Layer::IpHeader; 883 err 884 } else { 885 err.clone() 886 } 887 }), 888 Layer::IpHeader, 889 )), 890 ); 891 } 892 } 893 894 // content error ipv6 895 { 896 use err::ip::{HeaderError::*, LaxHeaderSliceError::Content}; 897 898 let mut data = test.to_vec(&[]); 899 900 // inject an invalid ip version 901 let base_len = data.len() - ipv6.header_len(); 902 data[base_len] = data[base_len] & 0b0000_1111; 903 904 assert_test_result( 905 &test, 906 &[], 907 &data, 908 Some(Content(UnsupportedIpVersion { version_number: 0 })), 909 Some(( 910 SliceError::Ip(UnsupportedIpVersion { version_number: 0 }), 911 Layer::IpHeader, 912 )), 913 ); 914 } 915 } 916 917 // ipv6 + extension 918 for fragment in [false, true] { 919 let auth = IpAuthHeader::new(ip_number::GGP, 1, 2, &[]).unwrap(); 920 let frag = Ipv6FragmentHeader { 921 next_header: ip_number::AUTH, 922 fragment_offset: 0.try_into().unwrap(), 923 more_fragments: fragment, 924 identification: 3, 925 }; 926 927 let mut test = base.clone(); 928 test.set_ether_type(ether_type::IPV6); 929 test.net = Some(NetHeaders::Ipv6( 930 { 931 let mut ipv6 = ipv6.clone(); 932 ipv6.next_header = ip_number::IPV6_FRAG; 933 ipv6 934 }, 935 { 936 let mut exts: Ipv6Extensions = Default::default(); 937 exts.fragment = Some(frag.clone()); 938 exts.auth = Some(auth.clone()); 939 exts 940 }, 941 )); 942 test.set_payload_len(0); 943 944 // ok ipv6 & extensions 945 from_x_slice_transport_variants(&test); 946 947 // ipv6 extension len error 948 for len in 0..auth.header_len() { 949 // set payload length 950 let mut test = test.clone(); 951 test.set_payload_le_from_ip_on( 952 -1 * (auth.header_len() as isize) + (len as isize), 953 ); 954 955 let data = test.to_vec(&[]); 956 let base_len = test.len(&[]) - auth.header_len(); 957 958 let err = LenError { 959 required_len: auth.header_len(), 960 len, 961 len_source: LenSource::Ipv6HeaderPayloadLen, 962 layer: Layer::IpAuthHeader, 963 layer_start_offset: base_len, 964 }; 965 assert_test_result( 966 &test, 967 &[], 968 &data[..base_len + len], 969 None, 970 Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)), 971 ); 972 } 973 974 // ipv6 extension content error (auth) 975 { 976 let mut data = test.to_vec(&[]); 977 let auth_offset = data.len() - auth.header_len(); 978 // set the icv len too smaller then allowed 979 data[auth_offset + 1] = 0; 980 981 assert_test_result( 982 &test, 983 &[], 984 &data, 985 None, 986 Some(( 987 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::IpAuth( 988 err::ip_auth::HeaderError::ZeroPayloadLen, 989 )), 990 Layer::IpAuthHeader, 991 )), 992 ); 993 } 994 995 // ipv6 extension content error (hop by hop not at start) 996 { 997 let mut data = test.to_vec(&[]); 998 let auth_offset = data.len() - auth.header_len(); 999 1000 // set the next header to be a hop-by-hop header to trigger a "not at start error" 1001 data[auth_offset] = 0; 1002 1003 assert_test_result( 1004 &test, 1005 &[], 1006 &data, 1007 None, 1008 Some(( 1009 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::HopByHopNotAtStart), 1010 Layer::Ipv6HopByHopHeader, 1011 )), 1012 ); 1013 } 1014 } 1015 } 1016 } 1017 from_x_slice_transport_variants(base: &TestPacket)1018 fn from_x_slice_transport_variants(base: &TestPacket) { 1019 // none 1020 from_x_slice_assert_ok(base); 1021 1022 // transport can only be set if ip is present 1023 if let Some(ip) = &base.net { 1024 // udp 1025 { 1026 let udp = UdpHeader { 1027 source_port: 1, 1028 destination_port: 2, 1029 length: 3, 1030 checksum: 4, 1031 }; 1032 let mut test = base.clone(); 1033 test.net = Some({ 1034 let mut ip = match ip { 1035 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1036 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1037 }; 1038 ip.set_next_headers(ip_number::UDP); 1039 ip.into() 1040 }); 1041 test.transport = Some(TransportHeader::Udp(udp.clone())); 1042 test.set_payload_len(0); 1043 1044 // ok decode 1045 from_x_slice_assert_ok(&test); 1046 1047 // length error 1048 if false == test.is_ip_payload_fragmented() { 1049 for len in 0..udp.header_len() { 1050 // build new test packet 1051 let mut test = test.clone(); 1052 1053 // set payload length 1054 test.set_payload_le_from_ip_on(len as isize); 1055 1056 // generate data 1057 let data = test.to_vec(&[]); 1058 1059 let base_len = test.len(&[]) - udp.header_len(); 1060 let err = LenError { 1061 required_len: udp.header_len(), 1062 len, 1063 len_source: match test.net.as_ref().unwrap() { 1064 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1065 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1066 }, 1067 layer: Layer::UdpHeader, 1068 layer_start_offset: base_len, 1069 }; 1070 assert_test_result( 1071 &test, 1072 &[], 1073 &data[..base_len + len], 1074 None, 1075 Some((SliceError::Len(err.clone()), Layer::UdpHeader)), 1076 ); 1077 } 1078 } 1079 } 1080 1081 // tcp 1082 { 1083 let tcp = TcpHeader::new(1, 2, 3, 4); 1084 let mut test = base.clone(); 1085 test.net = Some({ 1086 let mut ip = match ip { 1087 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1088 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1089 }; 1090 ip.set_next_headers(ip_number::TCP); 1091 ip.into() 1092 }); 1093 test.transport = Some(TransportHeader::Tcp(tcp.clone())); 1094 test.set_payload_len(0); 1095 1096 // ok decode 1097 from_x_slice_assert_ok(&test); 1098 1099 // error can only occur if ip does not fragment the packet 1100 if false == test.is_ip_payload_fragmented() { 1101 // length error 1102 { 1103 for len in 0..(tcp.header_len() as usize) { 1104 // set payload length 1105 let mut test = test.clone(); 1106 test.set_payload_le_from_ip_on(len as isize); 1107 1108 let data = test.to_vec(&[]); 1109 let base_len = test.len(&[]) - (tcp.header_len() as usize); 1110 1111 let err = LenError { 1112 required_len: tcp.header_len() as usize, 1113 len, 1114 len_source: match test.net.as_ref().unwrap() { 1115 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1116 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1117 }, 1118 layer: Layer::TcpHeader, 1119 layer_start_offset: base_len, 1120 }; 1121 assert_test_result( 1122 &test, 1123 &[], 1124 &data[..base_len + len], 1125 None, 1126 Some((SliceError::Len(err.clone()), Layer::TcpHeader)), 1127 ); 1128 } 1129 } 1130 1131 // content error 1132 { 1133 let mut data = test.to_vec(&[]); 1134 let base_len = test.len(&[]) - (tcp.header_len() as usize); 1135 1136 // set data offset to 0 to trigger an error 1137 data[base_len + 12] = data[base_len + 12] & 0b0000_1111; 1138 1139 let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 0 }; 1140 assert_test_result( 1141 &test, 1142 &[], 1143 &data, 1144 None, 1145 Some((SliceError::Tcp(err.clone()), Layer::TcpHeader)), 1146 ); 1147 } 1148 } 1149 } 1150 1151 // icmpv4 1152 { 1153 let icmpv4 = 1154 Icmpv4Header::new(Icmpv4Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 })); 1155 let mut test = base.clone(); 1156 test.net = Some({ 1157 let mut ip = match ip { 1158 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1159 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1160 }; 1161 ip.set_next_headers(ip_number::ICMP); 1162 ip.into() 1163 }); 1164 test.transport = Some(TransportHeader::Icmpv4(icmpv4.clone())); 1165 test.set_payload_len(0); 1166 1167 // ok decode 1168 from_x_slice_assert_ok(&test); 1169 1170 // length error 1171 if false == test.is_ip_payload_fragmented() { 1172 for len in 0..icmpv4.header_len() { 1173 // set payload length 1174 let mut test = test.clone(); 1175 test.set_payload_le_from_ip_on(len as isize); 1176 1177 let data = test.to_vec(&[]); 1178 let base_len = test.len(&[]) - icmpv4.header_len(); 1179 1180 let err = LenError { 1181 required_len: icmpv4.header_len(), 1182 len, 1183 len_source: match test.net.as_ref().unwrap() { 1184 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1185 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1186 }, 1187 layer: Layer::Icmpv4, 1188 layer_start_offset: base_len, 1189 }; 1190 assert_test_result( 1191 &test, 1192 &[], 1193 &data[..base_len + len], 1194 None, 1195 Some((SliceError::Len(err.clone()), Layer::Icmpv4)), 1196 ); 1197 } 1198 } 1199 } 1200 1201 // icmpv6 1202 { 1203 let icmpv6 = 1204 Icmpv6Header::new(Icmpv6Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 })); 1205 let mut test = base.clone(); 1206 test.net = Some({ 1207 let mut ip = match ip { 1208 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1209 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1210 }; 1211 ip.set_next_headers(ip_number::IPV6_ICMP); 1212 ip.into() 1213 }); 1214 test.transport = Some(TransportHeader::Icmpv6(icmpv6.clone())); 1215 test.set_payload_len(0); 1216 1217 // ok decode 1218 from_x_slice_assert_ok(&test); 1219 1220 // length error 1221 if false == test.is_ip_payload_fragmented() { 1222 for len in 0..icmpv6.header_len() { 1223 // set payload length 1224 let mut test = test.clone(); 1225 test.set_payload_le_from_ip_on(len as isize); 1226 1227 let data = test.to_vec(&[]); 1228 let base_len = test.len(&[]) - icmpv6.header_len(); 1229 1230 let err = LenError { 1231 required_len: icmpv6.header_len(), 1232 len, 1233 len_source: match test.net.as_ref().unwrap() { 1234 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1235 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1236 }, 1237 layer: Layer::Icmpv6, 1238 layer_start_offset: base_len, 1239 }; 1240 assert_test_result( 1241 &test, 1242 &[], 1243 &data[..base_len + len], 1244 None, 1245 Some((SliceError::Len(err.clone()), Layer::Icmpv6)), 1246 ); 1247 } 1248 } 1249 } 1250 } 1251 } 1252 from_x_slice_assert_ok(test_base: &TestPacket)1253 fn from_x_slice_assert_ok(test_base: &TestPacket) { 1254 // setup payload 1255 let payload = [1, 2, 3, 4]; 1256 1257 // set length fields in ip headers 1258 let test = { 1259 let mut test = test_base.clone(); 1260 test.set_payload_len(payload.len()); 1261 test 1262 }; 1263 1264 // write data 1265 let data = test.to_vec(&payload); 1266 assert_test_result(&test, &payload, &data, None, None); 1267 } 1268 1269 /// Check that the given output & errors (if present) are generated based on the given 1270 /// input. assert_test_result( test: &TestPacket, expected_payload: &[u8], data: &[u8], expected_ip_err: Option<err::ip::LaxHeaderSliceError>, expected_stop_err: Option<(SliceError, Layer)>, )1271 fn assert_test_result( 1272 test: &TestPacket, 1273 expected_payload: &[u8], 1274 data: &[u8], 1275 expected_ip_err: Option<err::ip::LaxHeaderSliceError>, 1276 expected_stop_err: Option<(SliceError, Layer)>, 1277 ) { 1278 fn compare_vlan(test: &TestPacket, data: &[u8], actual: &LaxSlicedPacket) { 1279 let vlan_offset = if let Some(e) = test.link.as_ref() { 1280 e.header_len() 1281 } else { 1282 0 1283 }; 1284 match test.vlan.as_ref() { 1285 Some(VlanHeader::Double(d)) => { 1286 if data.len() >= vlan_offset + DoubleVlanHeader::LEN { 1287 assert_eq!(test.vlan, actual.vlan.as_ref().map(|v| v.to_header())); 1288 } else if data.len() >= vlan_offset + SingleVlanHeader::LEN { 1289 assert_eq!( 1290 Some(VlanHeader::Single(d.outer.clone())), 1291 actual.vlan.as_ref().map(|v| v.to_header()) 1292 ); 1293 } else { 1294 assert_eq!(None, actual.vlan); 1295 } 1296 } 1297 Some(VlanHeader::Single(s)) => { 1298 if data.len() >= vlan_offset + SingleVlanHeader::LEN { 1299 assert_eq!( 1300 Some(VlanHeader::Single(s.clone())), 1301 actual.vlan.as_ref().map(|v| v.to_header()) 1302 ); 1303 } else { 1304 assert_eq!(None, actual.vlan); 1305 } 1306 } 1307 None => { 1308 assert_eq!(None, actual.vlan); 1309 } 1310 } 1311 } 1312 1313 fn compare_ip(test: &TestPacket, actual: &LaxSlicedPacket) { 1314 assert_eq!( 1315 test.net, 1316 actual.net.as_ref().map(|s| -> NetHeaders { 1317 match s { 1318 LaxNetSlice::Ipv4(ipv4) => NetHeaders::Ipv4( 1319 ipv4.header().to_header(), 1320 ipv4.extensions().to_header(), 1321 ), 1322 LaxNetSlice::Ipv6(ipv6) => NetHeaders::Ipv6( 1323 ipv6.header().to_header(), 1324 Ipv6Extensions::from_slice( 1325 ipv6.header().next_header(), 1326 ipv6.extensions().slice(), 1327 ) 1328 .unwrap() 1329 .0, 1330 ), 1331 } 1332 }) 1333 ); 1334 } 1335 1336 fn compare_ip_header_only(test: &TestPacket, actual: &LaxSlicedPacket) { 1337 assert_eq!( 1338 test.net.as_ref().map(|s| -> NetHeaders { 1339 match s { 1340 NetHeaders::Ipv4(h, _) => NetHeaders::Ipv4(h.clone(), Default::default()), 1341 NetHeaders::Ipv6(h, _) => NetHeaders::Ipv6(h.clone(), Default::default()), 1342 } 1343 }), 1344 actual.net.as_ref().map(|s| -> NetHeaders { 1345 match s { 1346 LaxNetSlice::Ipv4(ipv4) => { 1347 NetHeaders::Ipv4(ipv4.header().to_header(), Default::default()) 1348 } 1349 LaxNetSlice::Ipv6(ipv6) => { 1350 NetHeaders::Ipv6(ipv6.header().to_header(), Default::default()) 1351 } 1352 } 1353 }) 1354 ); 1355 } 1356 1357 fn compare_transport( 1358 test: &TestPacket, 1359 is_fragmented: bool, 1360 expected_payload: &[u8], 1361 actual: &LaxSlicedPacket, 1362 ) { 1363 if is_fragmented { 1364 assert_eq!(actual.transport, None); 1365 } else { 1366 use TransportHeader as H; 1367 use TransportSlice as S; 1368 match &actual.transport { 1369 Some(S::Icmpv4(icmpv4)) => { 1370 assert_eq!(&test.transport, &Some(H::Icmpv4(icmpv4.header()))); 1371 assert_eq!(icmpv4.payload(), expected_payload); 1372 } 1373 Some(S::Icmpv6(icmpv6)) => { 1374 assert_eq!(&test.transport, &Some(H::Icmpv6(icmpv6.header()))); 1375 assert_eq!(icmpv6.payload(), expected_payload); 1376 } 1377 Some(S::Udp(s)) => { 1378 assert_eq!(&test.transport, &Some(H::Udp(s.to_header()))); 1379 } 1380 Some(S::Tcp(s)) => { 1381 assert_eq!(&test.transport, &Some(H::Tcp(s.to_header()))); 1382 } 1383 None => { 1384 assert_eq!(&test.transport, &None); 1385 } 1386 } 1387 } 1388 } 1389 1390 // from_ethernet_slice 1391 if test.link.is_some() { 1392 if data.len() < Ethernet2Header::LEN { 1393 assert_eq!( 1394 LenError { 1395 required_len: Ethernet2Header::LEN, 1396 len: data.len(), 1397 len_source: LenSource::Slice, 1398 layer: Layer::Ethernet2Header, 1399 layer_start_offset: 0 1400 }, 1401 LaxSlicedPacket::from_ethernet(&data).unwrap_err() 1402 ); 1403 } else { 1404 let actual = LaxSlicedPacket::from_ethernet(&data).unwrap(); 1405 assert_eq!(actual.stop_err, expected_stop_err); 1406 match expected_stop_err.as_ref().map(|v| v.1) { 1407 None => { 1408 assert_eq!( 1409 test.link, 1410 actual.link.as_ref().map(|v| v.to_header()).flatten() 1411 ); 1412 compare_vlan(test, data, &actual); 1413 compare_ip(test, &actual); 1414 compare_transport( 1415 test, 1416 test.is_ip_payload_fragmented(), 1417 expected_payload, 1418 &actual, 1419 ); 1420 } 1421 Some(Layer::VlanHeader) => { 1422 assert_eq!( 1423 test.link, 1424 actual.link.as_ref().map(|v| v.to_header()).flatten() 1425 ); 1426 compare_vlan(test, data, &actual); 1427 assert_eq!(None, actual.net); 1428 assert_eq!(None, actual.transport); 1429 } 1430 Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => { 1431 assert_eq!( 1432 test.link, 1433 actual.link.as_ref().map(|v| v.to_header()).flatten() 1434 ); 1435 compare_vlan(test, data, &actual); 1436 assert_eq!(None, actual.net); 1437 assert_eq!(None, actual.transport); 1438 } 1439 Some(Layer::IpAuthHeader) 1440 | Some(Layer::Ipv6ExtHeader) 1441 | Some(Layer::Ipv6HopByHopHeader) 1442 | Some(Layer::Ipv6DestOptionsHeader) 1443 | Some(Layer::Ipv6RouteHeader) 1444 | Some(Layer::Ipv6FragHeader) => { 1445 assert_eq!( 1446 test.link, 1447 actual.link.as_ref().map(|v| v.to_header()).flatten() 1448 ); 1449 compare_vlan(test, data, &actual); 1450 compare_ip_header_only(test, &actual); 1451 assert_eq!(None, actual.transport); 1452 } 1453 Some(Layer::TcpHeader) 1454 | Some(Layer::UdpHeader) 1455 | Some(Layer::Icmpv4) 1456 | Some(Layer::Icmpv6) => { 1457 assert_eq!( 1458 test.link, 1459 actual.link.as_ref().map(|v| v.to_header()).flatten() 1460 ); 1461 compare_vlan(test, data, &actual); 1462 compare_ip(test, &actual); 1463 assert_eq!(None, actual.transport); 1464 } 1465 _ => unreachable!("error in an unexpected layer"), 1466 } 1467 } 1468 } 1469 // from_ether_type (vlan at start) 1470 if test.link.is_none() && test.vlan.is_some() { 1471 for ether_type in VLAN_ETHER_TYPES { 1472 let actual = LaxSlicedPacket::from_ether_type(ether_type, data); 1473 assert_eq!(actual.stop_err, expected_stop_err); 1474 assert_eq!( 1475 Some(LinkSlice::EtherPayload(EtherPayloadSlice { 1476 ether_type, 1477 payload: data 1478 })), 1479 actual.link 1480 ); 1481 compare_vlan(test, data, &actual); 1482 match expected_stop_err.as_ref().map(|v| v.1) { 1483 None => { 1484 compare_ip(test, &actual); 1485 compare_transport( 1486 test, 1487 test.is_ip_payload_fragmented(), 1488 expected_payload, 1489 &actual, 1490 ); 1491 } 1492 Some(Layer::VlanHeader) => { 1493 assert_eq!(None, actual.net); 1494 assert_eq!(None, actual.transport); 1495 } 1496 Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => { 1497 assert_eq!(None, actual.net); 1498 assert_eq!(None, actual.transport); 1499 } 1500 Some(Layer::IpAuthHeader) 1501 | Some(Layer::Ipv6ExtHeader) 1502 | Some(Layer::Ipv6HopByHopHeader) 1503 | Some(Layer::Ipv6DestOptionsHeader) 1504 | Some(Layer::Ipv6RouteHeader) 1505 | Some(Layer::Ipv6FragHeader) => { 1506 compare_ip_header_only(test, &actual); 1507 assert_eq!(None, actual.transport); 1508 } 1509 Some(Layer::TcpHeader) 1510 | Some(Layer::UdpHeader) 1511 | Some(Layer::Icmpv4) 1512 | Some(Layer::Icmpv6) => { 1513 compare_ip(test, &actual); 1514 assert_eq!(None, actual.transport); 1515 } 1516 _ => unreachable!("error in an unexpected layer"), 1517 } 1518 } 1519 } 1520 // from_ether_type (ip at start) 1521 if test.link.is_none() && test.vlan.is_none() { 1522 if let Some(ip) = &test.net { 1523 let ether_type = match ip { 1524 NetHeaders::Ipv4(_, _) => ether_type::IPV4, 1525 NetHeaders::Ipv6(_, _) => ether_type::IPV6, 1526 }; 1527 let actual = LaxSlicedPacket::from_ether_type(ether_type, &data); 1528 assert_eq!(actual.stop_err, expected_stop_err); 1529 assert_eq!( 1530 Some(LinkSlice::EtherPayload(EtherPayloadSlice { 1531 ether_type, 1532 payload: data 1533 })), 1534 actual.link 1535 ); 1536 assert_eq!(test.vlan, None); 1537 match expected_stop_err.as_ref().map(|v| v.1) { 1538 None => { 1539 compare_ip(test, &actual); 1540 compare_transport( 1541 test, 1542 test.is_ip_payload_fragmented(), 1543 expected_payload, 1544 &actual, 1545 ); 1546 } 1547 Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => { 1548 assert_eq!(None, actual.net); 1549 assert_eq!(None, actual.transport); 1550 } 1551 Some(Layer::IpAuthHeader) 1552 | Some(Layer::Ipv6ExtHeader) 1553 | Some(Layer::Ipv6HopByHopHeader) 1554 | Some(Layer::Ipv6DestOptionsHeader) 1555 | Some(Layer::Ipv6RouteHeader) 1556 | Some(Layer::Ipv6FragHeader) => { 1557 compare_ip_header_only(test, &actual); 1558 assert_eq!(None, actual.transport); 1559 } 1560 Some(Layer::TcpHeader) 1561 | Some(Layer::UdpHeader) 1562 | Some(Layer::Icmpv4) 1563 | Some(Layer::Icmpv6) => { 1564 compare_ip(test, &actual); 1565 assert_eq!(None, actual.transport); 1566 } 1567 _ => unreachable!("error in an unexpected layer"), 1568 } 1569 } 1570 } 1571 // from_ip_slice 1572 if test.link.is_none() && test.vlan.is_none() && test.net.is_some() { 1573 if let Some(err) = expected_ip_err { 1574 assert_eq!(err, LaxSlicedPacket::from_ip(&data).unwrap_err()); 1575 } else { 1576 let actual = LaxSlicedPacket::from_ip(&data).unwrap(); 1577 assert_eq!(actual.stop_err, expected_stop_err); 1578 assert_eq!(actual.link, None); 1579 assert_eq!(test.vlan, None); 1580 match expected_stop_err.as_ref().map(|v| v.1) { 1581 None => { 1582 compare_ip(test, &actual); 1583 compare_transport( 1584 test, 1585 test.is_ip_payload_fragmented(), 1586 expected_payload, 1587 &actual, 1588 ); 1589 } 1590 Some(Layer::IpAuthHeader) 1591 | Some(Layer::Ipv6ExtHeader) 1592 | Some(Layer::Ipv6HopByHopHeader) 1593 | Some(Layer::Ipv6DestOptionsHeader) 1594 | Some(Layer::Ipv6RouteHeader) 1595 | Some(Layer::Ipv6FragHeader) => { 1596 compare_ip_header_only(test, &actual); 1597 assert_eq!(None, actual.transport); 1598 } 1599 Some(Layer::TcpHeader) 1600 | Some(Layer::UdpHeader) 1601 | Some(Layer::Icmpv4) 1602 | Some(Layer::Icmpv6) => { 1603 compare_ip(test, &actual); 1604 assert_eq!(None, actual.transport); 1605 } 1606 _ => unreachable!("error in an unexpected layer"), 1607 } 1608 } 1609 } 1610 } 1611 } 1612