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 Arp(_) => None, 268 } 269 } else { 270 None 271 } 272 } 273 } 274 275 #[cfg(test)] 276 mod test { 277 use super::*; 278 use crate::err::{packet::SliceError, LenError}; 279 use crate::test_packet::TestPacket; 280 281 const VLAN_ETHER_TYPES: [EtherType; 3] = [ 282 ether_type::VLAN_TAGGED_FRAME, 283 ether_type::PROVIDER_BRIDGING, 284 ether_type::VLAN_DOUBLE_TAGGED_FRAME, 285 ]; 286 287 #[test] clone_eq()288 fn clone_eq() { 289 let header = LaxSlicedPacket { 290 link: None, 291 vlan: None, 292 net: None, 293 transport: None, 294 stop_err: None, 295 }; 296 assert_eq!(header.clone(), header); 297 } 298 299 #[test] debug()300 fn debug() { 301 use alloc::format; 302 let header = LaxSlicedPacket { 303 link: None, 304 vlan: None, 305 net: None, 306 transport: None, 307 stop_err: None, 308 }; 309 assert_eq!( 310 format!("{:?}", header), 311 format!( 312 "LaxSlicedPacket {{ link: {:?}, vlan: {:?}, net: {:?}, transport: {:?}, stop_err: {:?} }}", 313 header.link, header.vlan, header.net, header.transport, header.stop_err 314 ) 315 ); 316 } 317 318 #[test] ether_payload()319 fn ether_payload() { 320 use alloc::vec::*; 321 322 // no content 323 assert_eq!( 324 LaxSlicedPacket { 325 link: None, 326 vlan: None, 327 net: None, 328 transport: None, 329 stop_err: None 330 } 331 .ether_payload(), 332 None 333 ); 334 335 // only ethernet header II 336 { 337 let payload = [1, 2, 3, 4]; 338 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + 4); 339 buf.extend_from_slice( 340 &Ethernet2Header { 341 ether_type: EtherType::WAKE_ON_LAN, 342 ..Default::default() 343 } 344 .to_bytes(), 345 ); 346 buf.extend_from_slice(&payload); 347 assert_eq!( 348 LaxSlicedPacket::from_ethernet(&buf) 349 .unwrap() 350 .ether_payload(), 351 Some(EtherPayloadSlice { 352 ether_type: EtherType::WAKE_ON_LAN, 353 payload: &payload 354 }) 355 ); 356 } 357 358 // ether type payload 359 { 360 let payload = [1, 2, 3, 4]; 361 assert_eq!( 362 LaxSlicedPacket { 363 link: Some(LinkSlice::EtherPayload(EtherPayloadSlice { 364 ether_type: EtherType::WAKE_ON_LAN, 365 payload: &payload 366 })), 367 vlan: None, 368 net: None, 369 transport: None, 370 stop_err: None, 371 } 372 .ether_payload(), 373 Some(EtherPayloadSlice { 374 ether_type: EtherType::WAKE_ON_LAN, 375 payload: &payload 376 }) 377 ); 378 } 379 380 // single vlan header 381 { 382 let payload = [1, 2, 3, 4]; 383 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN + 4); 384 buf.extend_from_slice( 385 &Ethernet2Header { 386 ether_type: EtherType::VLAN_TAGGED_FRAME, 387 ..Default::default() 388 } 389 .to_bytes(), 390 ); 391 buf.extend_from_slice( 392 &SingleVlanHeader { 393 ether_type: EtherType::WAKE_ON_LAN, 394 ..Default::default() 395 } 396 .to_bytes(), 397 ); 398 buf.extend_from_slice(&payload); 399 assert_eq!( 400 LaxSlicedPacket::from_ethernet(&buf) 401 .unwrap() 402 .ether_payload(), 403 Some(EtherPayloadSlice { 404 ether_type: EtherType::WAKE_ON_LAN, 405 payload: &payload 406 }) 407 ); 408 } 409 410 // double vlan header 411 { 412 let payload = [1, 2, 3, 4]; 413 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN * 2 + 4); 414 buf.extend_from_slice( 415 &Ethernet2Header { 416 ether_type: EtherType::VLAN_DOUBLE_TAGGED_FRAME, 417 ..Default::default() 418 } 419 .to_bytes(), 420 ); 421 buf.extend_from_slice( 422 &SingleVlanHeader { 423 ether_type: EtherType::VLAN_TAGGED_FRAME, 424 ..Default::default() 425 } 426 .to_bytes(), 427 ); 428 buf.extend_from_slice( 429 &SingleVlanHeader { 430 ether_type: EtherType::WAKE_ON_LAN, 431 ..Default::default() 432 } 433 .to_bytes(), 434 ); 435 buf.extend_from_slice(&payload); 436 assert_eq!( 437 LaxSlicedPacket::from_ethernet(&buf) 438 .unwrap() 439 .ether_payload(), 440 Some(EtherPayloadSlice { 441 ether_type: EtherType::WAKE_ON_LAN, 442 payload: &payload 443 }) 444 ); 445 } 446 } 447 448 #[test] ip_payload()449 fn ip_payload() { 450 use alloc::vec::*; 451 452 // no content 453 assert_eq!( 454 LaxSlicedPacket { 455 link: None, 456 vlan: None, 457 net: None, 458 transport: None, 459 stop_err: None, 460 } 461 .ip_payload(), 462 None 463 ); 464 465 // ipv4 466 { 467 let payload = [1, 2, 3, 4]; 468 let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4); 469 buf.extend_from_slice( 470 &Ipv4Header { 471 protocol: IpNumber::ARIS, 472 total_len: Ipv4Header::MIN_LEN_U16 + 4, 473 ..Default::default() 474 } 475 .to_bytes(), 476 ); 477 buf.extend_from_slice(&payload); 478 assert_eq!( 479 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(), 480 Some(&LaxIpPayloadSlice { 481 payload: &payload, 482 ip_number: IpNumber::ARIS, 483 fragmented: false, 484 len_source: LenSource::Ipv4HeaderTotalLen, 485 incomplete: false, 486 }) 487 ); 488 } 489 490 // ipv6 491 { 492 let payload = [1, 2, 3, 4]; 493 let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4); 494 buf.extend_from_slice( 495 &Ipv6Header { 496 payload_length: 4, 497 next_header: IpNumber::ARGUS, 498 ..Default::default() 499 } 500 .to_bytes(), 501 ); 502 buf.extend_from_slice(&payload); 503 assert_eq!( 504 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(), 505 Some(&LaxIpPayloadSlice { 506 payload: &payload, 507 ip_number: IpNumber::ARGUS, 508 fragmented: false, 509 len_source: LenSource::Ipv6HeaderPayloadLen, 510 incomplete: false, 511 }) 512 ); 513 } 514 } 515 516 #[test] from_x_slice()517 fn from_x_slice() { 518 // no eth 519 from_x_slice_vlan_variants(&TestPacket { 520 link: None, 521 vlan: None, 522 net: None, 523 transport: None, 524 }); 525 526 // eth 527 { 528 let eth = Ethernet2Header { 529 source: [1, 2, 3, 4, 5, 6], 530 destination: [1, 2, 3, 4, 5, 6], 531 ether_type: 0.into(), 532 }; 533 let test = TestPacket { 534 link: Some(LinkHeader::Ethernet2(eth.clone())), 535 vlan: None, 536 net: None, 537 transport: None, 538 }; 539 540 // ok ethernet header (with unknown next) 541 from_x_slice_vlan_variants(&test); 542 543 // eth len error 544 { 545 let data = test.to_vec(&[]); 546 for len in 0..data.len() { 547 assert_test_result(&test, &[], &data[..len], None, None); 548 } 549 } 550 } 551 552 // unknown ether_type 553 { 554 let payload = [1, 2, 3, 4]; 555 let actual = LaxSlicedPacket::from_ether_type(0.into(), &payload); 556 assert_eq!( 557 actual.link, 558 Some(LinkSlice::EtherPayload(EtherPayloadSlice { 559 ether_type: 0.into(), 560 payload: &payload 561 })) 562 ); 563 assert_eq!(None, actual.vlan); 564 assert_eq!(None, actual.net); 565 assert_eq!(None, actual.transport); 566 assert_eq!(None, actual.stop_err); 567 } 568 } 569 from_x_slice_vlan_variants(base: &TestPacket)570 fn from_x_slice_vlan_variants(base: &TestPacket) { 571 // none 572 from_x_slice_ip_variants(base); 573 574 // single vlan header 575 { 576 let single = SingleVlanHeader { 577 pcp: 1.try_into().unwrap(), 578 drop_eligible_indicator: false, 579 vlan_id: 2.try_into().unwrap(), 580 ether_type: 3.into(), 581 }; 582 583 for vlan_ether_type in VLAN_ETHER_TYPES { 584 let mut test = base.clone(); 585 test.set_ether_type(vlan_ether_type); 586 test.vlan = Some(VlanHeader::Single(single.clone())); 587 588 // ok vlan header 589 from_x_slice_ip_variants(&test); 590 591 // len error 592 { 593 let data = test.to_vec(&[]); 594 for len in 0..single.header_len() { 595 let base_len = test.len(&[]) - single.header_len(); 596 597 let err = LenError { 598 required_len: single.header_len(), 599 len, 600 len_source: LenSource::Slice, 601 layer: Layer::VlanHeader, 602 layer_start_offset: base_len, 603 }; 604 assert_test_result( 605 &test, 606 &[], 607 &data[..base_len + len], 608 None, 609 Some((SliceError::Len(err.clone()), Layer::VlanHeader)), 610 ); 611 } 612 } 613 } 614 } 615 616 // double vlan header 617 for outer_vlan_ether_type in VLAN_ETHER_TYPES { 618 for inner_vlan_ether_type in VLAN_ETHER_TYPES { 619 let double = DoubleVlanHeader { 620 outer: SingleVlanHeader { 621 pcp: 1.try_into().unwrap(), 622 drop_eligible_indicator: false, 623 vlan_id: 2.try_into().unwrap(), 624 ether_type: inner_vlan_ether_type, 625 }, 626 inner: SingleVlanHeader { 627 pcp: 1.try_into().unwrap(), 628 drop_eligible_indicator: false, 629 vlan_id: 2.try_into().unwrap(), 630 ether_type: 3.into(), 631 }, 632 }; 633 let mut test = base.clone(); 634 test.set_ether_type(outer_vlan_ether_type); 635 test.vlan = Some(VlanHeader::Double(double.clone())); 636 637 // ok double vlan header 638 from_x_slice_ip_variants(&test); 639 640 // len error 641 { 642 let data = test.to_vec(&[]); 643 for len in 0..SingleVlanHeader::LEN { 644 let base_len = test.len(&[]) - SingleVlanHeader::LEN; 645 646 let err = LenError { 647 required_len: SingleVlanHeader::LEN, 648 len, 649 len_source: LenSource::Slice, 650 layer: Layer::VlanHeader, 651 layer_start_offset: base_len, 652 }; 653 assert_test_result( 654 &test, 655 &[], 656 &data[..base_len + len], 657 None, 658 Some((SliceError::Len(err.clone()), Layer::VlanHeader)), 659 ); 660 } 661 } 662 } 663 } 664 } 665 from_x_slice_ip_variants(base: &TestPacket)666 fn from_x_slice_ip_variants(base: &TestPacket) { 667 // none 668 from_x_slice_transport_variants(base); 669 670 // ipv4 671 for fragmented in [false, true] { 672 let ipv4 = { 673 let mut ipv4 = 674 Ipv4Header::new(0, 1, 2.into(), [3, 4, 5, 6], [7, 8, 9, 10]).unwrap(); 675 ipv4.more_fragments = fragmented; 676 ipv4 677 }; 678 679 { 680 let mut test = base.clone(); 681 test.set_ether_type(ether_type::IPV4); 682 test.net = Some(NetHeaders::Ipv4(ipv4.clone(), Default::default())); 683 test.set_payload_len(0); 684 685 // ok ipv4 686 from_x_slice_transport_variants(&test); 687 688 // ipv4 len error 689 { 690 let data = test.to_vec(&[]); 691 for len in 0..ipv4.header_len() { 692 let base_len = test.len(&[]) - ipv4.header_len(); 693 694 let err = LenError { 695 required_len: if len < 1 { 1 } else { ipv4.header_len() }, 696 len, 697 len_source: LenSource::Slice, 698 layer: if len < 1 { 699 Layer::IpHeader 700 } else { 701 Layer::Ipv4Header 702 }, 703 layer_start_offset: base_len, 704 }; 705 706 assert_test_result( 707 &test, 708 &[], 709 &data[..base_len + len], 710 Some(err::ip::LaxHeaderSliceError::Len(err.clone())), 711 Some((SliceError::Len(err.clone()), Layer::IpHeader)), 712 ); 713 } 714 } 715 716 // ipv4 content error (ihl length too small) 717 { 718 use err::ip::HeaderError::*; 719 720 let mut data = test.to_vec(&[]); 721 let ipv4_offset = data.len() - ipv4.header_len(); 722 723 // set the ihl to 0 to trigger a content error 724 data[ipv4_offset] = 0b1111_0000 & data[ipv4_offset]; 725 726 assert_test_result( 727 &test, 728 &[], 729 &data, 730 Some(err::ip::LaxHeaderSliceError::Content( 731 Ipv4HeaderLengthSmallerThanHeader { ihl: 0 }, 732 )), 733 Some(( 734 SliceError::Ip(Ipv4HeaderLengthSmallerThanHeader { ihl: 0 }), 735 Layer::IpHeader, 736 )), 737 ); 738 } 739 740 // ipv 4total length too small (does not change the output) 741 { 742 let mut data = test.to_vec(&[]); 743 let ipv4_offset = data.len() - ipv4.header_len(); 744 745 // set the total length to 0 to trigger a content error 746 data[ipv4_offset + 2] = 0; 747 data[ipv4_offset + 3] = 0; 748 749 let mut mod_test = test.clone(); 750 mod_test.net = Some({ 751 let (h, e) = test.net.as_ref().map(|v| v.ipv4_ref()).flatten().unwrap(); 752 let mut ipv4 = h.clone(); 753 ipv4.total_len = 0; 754 NetHeaders::Ipv4(ipv4, e.clone()) 755 }); 756 757 assert_test_result(&mod_test, &[], &data, None, None); 758 } 759 } 760 761 // ipv4 extension content error 762 { 763 let auth = IpAuthHeader::new(0.into(), 1, 2, &[]).unwrap(); 764 765 let mut test = base.clone(); 766 test.set_ether_type(ether_type::IPV4); 767 test.net = Some(NetHeaders::Ipv4( 768 { 769 let mut ipv4 = ipv4.clone(); 770 ipv4.protocol = ip_number::AUTH; 771 ipv4 772 }, 773 Ipv4Extensions { 774 auth: Some(auth.clone()), 775 }, 776 )); 777 test.set_payload_len(0); 778 779 // ok ipv4 & extension 780 from_x_slice_transport_variants(&test); 781 782 // ipv4 extension len error 783 for len in 0..auth.header_len() { 784 // set payload length 785 let mut test = test.clone(); 786 test.set_payload_le_from_ip_on( 787 -1 * (auth.header_len() as isize) + (len as isize), 788 ); 789 790 let data = test.to_vec(&[]); 791 let base_len = test.len(&[]) - auth.header_len(); 792 793 let err = LenError { 794 required_len: auth.header_len(), 795 len, 796 len_source: LenSource::Ipv4HeaderTotalLen, 797 layer: Layer::IpAuthHeader, 798 layer_start_offset: base_len, 799 }; 800 801 assert_test_result( 802 &test, 803 &[], 804 &data, 805 None, 806 Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)), 807 ); 808 } 809 810 // ipv4 extension content error 811 { 812 let mut data = test.to_vec(&[]); 813 let auth_offset = data.len() - auth.header_len(); 814 815 // set the icv len too smaller then allowed 816 data[auth_offset + 1] = 0; 817 818 // expect an error 819 assert_test_result( 820 &test, 821 &[], 822 &data, 823 None, 824 Some(( 825 SliceError::Ipv4Exts(err::ip_auth::HeaderError::ZeroPayloadLen), 826 Layer::IpAuthHeader, 827 )), 828 ); 829 } 830 } 831 } 832 833 // ipv6 834 { 835 let ipv6 = Ipv6Header { 836 traffic_class: 0, 837 flow_label: 1.try_into().unwrap(), 838 payload_length: 2, 839 next_header: 3.into(), 840 hop_limit: 4, 841 source: [0; 16], 842 destination: [0; 16], 843 }; 844 845 // ipv6 header only 846 { 847 let mut test = base.clone(); 848 test.set_ether_type(ether_type::IPV6); 849 test.net = Some(NetHeaders::Ipv6(ipv6.clone(), Default::default())); 850 test.set_payload_len(0); 851 852 // ok ipv6 853 from_x_slice_transport_variants(&test); 854 855 // header len ipv6 856 { 857 let data = test.to_vec(&[]); 858 for len in 0..ipv6.header_len() { 859 let base_len = test.len(&[]) - ipv6.header_len(); 860 861 let err = err::LenError { 862 required_len: if len < 1 { 1 } else { ipv6.header_len() }, 863 len, 864 len_source: LenSource::Slice, 865 layer: if len < 1 { 866 Layer::IpHeader 867 } else { 868 Layer::Ipv6Header 869 }, 870 layer_start_offset: base_len, 871 }; 872 873 assert_test_result( 874 &test, 875 &[], 876 &data[..base_len + len], 877 Some(err::ip::LaxHeaderSliceError::Len(err.clone())), 878 Some(( 879 SliceError::Len({ 880 if len < 1 { 881 let mut err = err.clone(); 882 err.required_len = 1; 883 err.layer = Layer::IpHeader; 884 err 885 } else { 886 err.clone() 887 } 888 }), 889 Layer::IpHeader, 890 )), 891 ); 892 } 893 } 894 895 // content error ipv6 896 { 897 use err::ip::{HeaderError::*, LaxHeaderSliceError::Content}; 898 899 let mut data = test.to_vec(&[]); 900 901 // inject an invalid ip version 902 let base_len = data.len() - ipv6.header_len(); 903 data[base_len] = data[base_len] & 0b0000_1111; 904 905 assert_test_result( 906 &test, 907 &[], 908 &data, 909 Some(Content(UnsupportedIpVersion { version_number: 0 })), 910 Some(( 911 SliceError::Ip(UnsupportedIpVersion { version_number: 0 }), 912 Layer::IpHeader, 913 )), 914 ); 915 } 916 } 917 918 // ipv6 + extension 919 for fragment in [false, true] { 920 let auth = IpAuthHeader::new(ip_number::GGP, 1, 2, &[]).unwrap(); 921 let frag = Ipv6FragmentHeader { 922 next_header: ip_number::AUTH, 923 fragment_offset: 0.try_into().unwrap(), 924 more_fragments: fragment, 925 identification: 3, 926 }; 927 928 let mut test = base.clone(); 929 test.set_ether_type(ether_type::IPV6); 930 test.net = Some(NetHeaders::Ipv6( 931 { 932 let mut ipv6 = ipv6.clone(); 933 ipv6.next_header = ip_number::IPV6_FRAG; 934 ipv6 935 }, 936 { 937 let mut exts: Ipv6Extensions = Default::default(); 938 exts.fragment = Some(frag.clone()); 939 exts.auth = Some(auth.clone()); 940 exts 941 }, 942 )); 943 test.set_payload_len(0); 944 945 // ok ipv6 & extensions 946 from_x_slice_transport_variants(&test); 947 948 // ipv6 extension len error 949 for len in 0..auth.header_len() { 950 // set payload length 951 let mut test = test.clone(); 952 test.set_payload_le_from_ip_on( 953 -1 * (auth.header_len() as isize) + (len as isize), 954 ); 955 956 let data = test.to_vec(&[]); 957 let base_len = test.len(&[]) - auth.header_len(); 958 959 let err = LenError { 960 required_len: auth.header_len(), 961 len, 962 len_source: LenSource::Ipv6HeaderPayloadLen, 963 layer: Layer::IpAuthHeader, 964 layer_start_offset: base_len, 965 }; 966 assert_test_result( 967 &test, 968 &[], 969 &data[..base_len + len], 970 None, 971 Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)), 972 ); 973 } 974 975 // ipv6 extension content error (auth) 976 { 977 let mut data = test.to_vec(&[]); 978 let auth_offset = data.len() - auth.header_len(); 979 // set the icv len too smaller then allowed 980 data[auth_offset + 1] = 0; 981 982 assert_test_result( 983 &test, 984 &[], 985 &data, 986 None, 987 Some(( 988 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::IpAuth( 989 err::ip_auth::HeaderError::ZeroPayloadLen, 990 )), 991 Layer::IpAuthHeader, 992 )), 993 ); 994 } 995 996 // ipv6 extension content error (hop by hop not at start) 997 { 998 let mut data = test.to_vec(&[]); 999 let auth_offset = data.len() - auth.header_len(); 1000 1001 // set the next header to be a hop-by-hop header to trigger a "not at start error" 1002 data[auth_offset] = 0; 1003 1004 assert_test_result( 1005 &test, 1006 &[], 1007 &data, 1008 None, 1009 Some(( 1010 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::HopByHopNotAtStart), 1011 Layer::Ipv6HopByHopHeader, 1012 )), 1013 ); 1014 } 1015 } 1016 } 1017 } 1018 from_x_slice_transport_variants(base: &TestPacket)1019 fn from_x_slice_transport_variants(base: &TestPacket) { 1020 // none 1021 from_x_slice_assert_ok(base); 1022 1023 // transport can only be set if ip is present 1024 if let Some(ip) = &base.net { 1025 // udp 1026 { 1027 let udp = UdpHeader { 1028 source_port: 1, 1029 destination_port: 2, 1030 length: 3, 1031 checksum: 4, 1032 }; 1033 let mut test = base.clone(); 1034 test.net = Some({ 1035 let mut ip = match ip { 1036 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1037 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1038 NetHeaders::Arp(_) => unreachable!(), 1039 }; 1040 ip.set_next_headers(ip_number::UDP); 1041 ip.into() 1042 }); 1043 test.transport = Some(TransportHeader::Udp(udp.clone())); 1044 test.set_payload_len(0); 1045 1046 // ok decode 1047 from_x_slice_assert_ok(&test); 1048 1049 // length error 1050 if false == test.is_ip_payload_fragmented() { 1051 for len in 0..udp.header_len() { 1052 // build new test packet 1053 let mut test = test.clone(); 1054 1055 // set payload length 1056 test.set_payload_le_from_ip_on(len as isize); 1057 1058 // generate data 1059 let data = test.to_vec(&[]); 1060 1061 let base_len = test.len(&[]) - udp.header_len(); 1062 let err = LenError { 1063 required_len: udp.header_len(), 1064 len, 1065 len_source: match test.net.as_ref().unwrap() { 1066 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1067 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1068 NetHeaders::Arp(_) => unreachable!(), 1069 }, 1070 layer: Layer::UdpHeader, 1071 layer_start_offset: base_len, 1072 }; 1073 assert_test_result( 1074 &test, 1075 &[], 1076 &data[..base_len + len], 1077 None, 1078 Some((SliceError::Len(err.clone()), Layer::UdpHeader)), 1079 ); 1080 } 1081 } 1082 } 1083 1084 // tcp 1085 { 1086 let tcp = TcpHeader::new(1, 2, 3, 4); 1087 let mut test = base.clone(); 1088 test.net = Some({ 1089 let mut ip = match ip { 1090 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1091 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1092 NetHeaders::Arp(_) => unreachable!(), 1093 }; 1094 ip.set_next_headers(ip_number::TCP); 1095 ip.into() 1096 }); 1097 test.transport = Some(TransportHeader::Tcp(tcp.clone())); 1098 test.set_payload_len(0); 1099 1100 // ok decode 1101 from_x_slice_assert_ok(&test); 1102 1103 // error can only occur if ip does not fragment the packet 1104 if false == test.is_ip_payload_fragmented() { 1105 // length error 1106 { 1107 for len in 0..(tcp.header_len() as usize) { 1108 // set payload length 1109 let mut test = test.clone(); 1110 test.set_payload_le_from_ip_on(len as isize); 1111 1112 let data = test.to_vec(&[]); 1113 let base_len = test.len(&[]) - (tcp.header_len() as usize); 1114 1115 let err = LenError { 1116 required_len: tcp.header_len() as usize, 1117 len, 1118 len_source: match test.net.as_ref().unwrap() { 1119 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1120 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1121 NetHeaders::Arp(_) => unreachable!(), 1122 }, 1123 layer: Layer::TcpHeader, 1124 layer_start_offset: base_len, 1125 }; 1126 assert_test_result( 1127 &test, 1128 &[], 1129 &data[..base_len + len], 1130 None, 1131 Some((SliceError::Len(err.clone()), Layer::TcpHeader)), 1132 ); 1133 } 1134 } 1135 1136 // content error 1137 { 1138 let mut data = test.to_vec(&[]); 1139 let base_len = test.len(&[]) - (tcp.header_len() as usize); 1140 1141 // set data offset to 0 to trigger an error 1142 data[base_len + 12] = data[base_len + 12] & 0b0000_1111; 1143 1144 let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 0 }; 1145 assert_test_result( 1146 &test, 1147 &[], 1148 &data, 1149 None, 1150 Some((SliceError::Tcp(err.clone()), Layer::TcpHeader)), 1151 ); 1152 } 1153 } 1154 } 1155 1156 // icmpv4 1157 { 1158 let icmpv4 = 1159 Icmpv4Header::new(Icmpv4Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 })); 1160 let mut test = base.clone(); 1161 test.net = Some({ 1162 let mut ip = match ip { 1163 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1164 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1165 NetHeaders::Arp(_) => unreachable!(), 1166 }; 1167 ip.set_next_headers(ip_number::ICMP); 1168 ip.into() 1169 }); 1170 test.transport = Some(TransportHeader::Icmpv4(icmpv4.clone())); 1171 test.set_payload_len(0); 1172 1173 // ok decode 1174 from_x_slice_assert_ok(&test); 1175 1176 // length error 1177 if false == test.is_ip_payload_fragmented() { 1178 for len in 0..icmpv4.header_len() { 1179 // set payload length 1180 let mut test = test.clone(); 1181 test.set_payload_le_from_ip_on(len as isize); 1182 1183 let data = test.to_vec(&[]); 1184 let base_len = test.len(&[]) - icmpv4.header_len(); 1185 1186 let err = LenError { 1187 required_len: icmpv4.header_len(), 1188 len, 1189 len_source: match test.net.as_ref().unwrap() { 1190 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1191 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1192 NetHeaders::Arp(_) => unreachable!(), 1193 }, 1194 layer: Layer::Icmpv4, 1195 layer_start_offset: base_len, 1196 }; 1197 assert_test_result( 1198 &test, 1199 &[], 1200 &data[..base_len + len], 1201 None, 1202 Some((SliceError::Len(err.clone()), Layer::Icmpv4)), 1203 ); 1204 } 1205 } 1206 } 1207 1208 // icmpv6 1209 { 1210 let icmpv6 = 1211 Icmpv6Header::new(Icmpv6Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 })); 1212 let mut test = base.clone(); 1213 test.net = Some({ 1214 let mut ip = match ip { 1215 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()), 1216 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()), 1217 NetHeaders::Arp(_) => unreachable!(), 1218 }; 1219 ip.set_next_headers(ip_number::IPV6_ICMP); 1220 ip.into() 1221 }); 1222 test.transport = Some(TransportHeader::Icmpv6(icmpv6.clone())); 1223 test.set_payload_len(0); 1224 1225 // ok decode 1226 from_x_slice_assert_ok(&test); 1227 1228 // length error 1229 if false == test.is_ip_payload_fragmented() { 1230 for len in 0..icmpv6.header_len() { 1231 // set payload length 1232 let mut test = test.clone(); 1233 test.set_payload_le_from_ip_on(len as isize); 1234 1235 let data = test.to_vec(&[]); 1236 let base_len = test.len(&[]) - icmpv6.header_len(); 1237 1238 let err = LenError { 1239 required_len: icmpv6.header_len(), 1240 len, 1241 len_source: match test.net.as_ref().unwrap() { 1242 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen, 1243 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen, 1244 NetHeaders::Arp(_) => unreachable!(), 1245 }, 1246 layer: Layer::Icmpv6, 1247 layer_start_offset: base_len, 1248 }; 1249 assert_test_result( 1250 &test, 1251 &[], 1252 &data[..base_len + len], 1253 None, 1254 Some((SliceError::Len(err.clone()), Layer::Icmpv6)), 1255 ); 1256 } 1257 } 1258 } 1259 } 1260 } 1261 from_x_slice_assert_ok(test_base: &TestPacket)1262 fn from_x_slice_assert_ok(test_base: &TestPacket) { 1263 // setup payload 1264 let payload = [1, 2, 3, 4]; 1265 1266 // set length fields in ip headers 1267 let test = { 1268 let mut test = test_base.clone(); 1269 test.set_payload_len(payload.len()); 1270 test 1271 }; 1272 1273 // write data 1274 let data = test.to_vec(&payload); 1275 assert_test_result(&test, &payload, &data, None, None); 1276 } 1277 1278 /// Check that the given output & errors (if present) are generated based on the given 1279 /// input. assert_test_result( test: &TestPacket, expected_payload: &[u8], data: &[u8], expected_ip_err: Option<err::ip::LaxHeaderSliceError>, expected_stop_err: Option<(SliceError, Layer)>, )1280 fn assert_test_result( 1281 test: &TestPacket, 1282 expected_payload: &[u8], 1283 data: &[u8], 1284 expected_ip_err: Option<err::ip::LaxHeaderSliceError>, 1285 expected_stop_err: Option<(SliceError, Layer)>, 1286 ) { 1287 fn compare_vlan(test: &TestPacket, data: &[u8], actual: &LaxSlicedPacket) { 1288 let vlan_offset = if let Some(e) = test.link.as_ref() { 1289 e.header_len() 1290 } else { 1291 0 1292 }; 1293 match test.vlan.as_ref() { 1294 Some(VlanHeader::Double(d)) => { 1295 if data.len() >= vlan_offset + DoubleVlanHeader::LEN { 1296 assert_eq!(test.vlan, actual.vlan.as_ref().map(|v| v.to_header())); 1297 } else if data.len() >= vlan_offset + SingleVlanHeader::LEN { 1298 assert_eq!( 1299 Some(VlanHeader::Single(d.outer.clone())), 1300 actual.vlan.as_ref().map(|v| v.to_header()) 1301 ); 1302 } else { 1303 assert_eq!(None, actual.vlan); 1304 } 1305 } 1306 Some(VlanHeader::Single(s)) => { 1307 if data.len() >= vlan_offset + SingleVlanHeader::LEN { 1308 assert_eq!( 1309 Some(VlanHeader::Single(s.clone())), 1310 actual.vlan.as_ref().map(|v| v.to_header()) 1311 ); 1312 } else { 1313 assert_eq!(None, actual.vlan); 1314 } 1315 } 1316 None => { 1317 assert_eq!(None, actual.vlan); 1318 } 1319 } 1320 } 1321 1322 fn compare_ip(test: &TestPacket, actual: &LaxSlicedPacket) { 1323 assert_eq!( 1324 test.net, 1325 actual.net.as_ref().map(|s| -> NetHeaders { 1326 match s { 1327 LaxNetSlice::Ipv4(ipv4) => NetHeaders::Ipv4( 1328 ipv4.header().to_header(), 1329 ipv4.extensions().to_header(), 1330 ), 1331 LaxNetSlice::Ipv6(ipv6) => NetHeaders::Ipv6( 1332 ipv6.header().to_header(), 1333 Ipv6Extensions::from_slice( 1334 ipv6.header().next_header(), 1335 ipv6.extensions().slice(), 1336 ) 1337 .unwrap() 1338 .0, 1339 ), 1340 LaxNetSlice::Arp(arp) => NetHeaders::Arp(arp.to_packet()), 1341 } 1342 }) 1343 ); 1344 } 1345 1346 fn compare_ip_header_only(test: &TestPacket, actual: &LaxSlicedPacket) { 1347 assert_eq!( 1348 test.net.as_ref().map(|s| -> NetHeaders { 1349 match s { 1350 NetHeaders::Ipv4(h, _) => NetHeaders::Ipv4(h.clone(), Default::default()), 1351 NetHeaders::Ipv6(h, _) => NetHeaders::Ipv6(h.clone(), Default::default()), 1352 NetHeaders::Arp(_) => unreachable!(), 1353 } 1354 }), 1355 actual.net.as_ref().map(|s| -> NetHeaders { 1356 match s { 1357 LaxNetSlice::Ipv4(ipv4) => { 1358 NetHeaders::Ipv4(ipv4.header().to_header(), Default::default()) 1359 } 1360 LaxNetSlice::Ipv6(ipv6) => { 1361 NetHeaders::Ipv6(ipv6.header().to_header(), Default::default()) 1362 } 1363 LaxNetSlice::Arp(arp) => NetHeaders::Arp(arp.to_packet()), 1364 } 1365 }) 1366 ); 1367 } 1368 1369 fn compare_transport( 1370 test: &TestPacket, 1371 is_fragmented: bool, 1372 expected_payload: &[u8], 1373 actual: &LaxSlicedPacket, 1374 ) { 1375 if is_fragmented { 1376 assert_eq!(actual.transport, None); 1377 } else { 1378 use TransportHeader as H; 1379 use TransportSlice as S; 1380 match &actual.transport { 1381 Some(S::Icmpv4(icmpv4)) => { 1382 assert_eq!(&test.transport, &Some(H::Icmpv4(icmpv4.header()))); 1383 assert_eq!(icmpv4.payload(), expected_payload); 1384 } 1385 Some(S::Icmpv6(icmpv6)) => { 1386 assert_eq!(&test.transport, &Some(H::Icmpv6(icmpv6.header()))); 1387 assert_eq!(icmpv6.payload(), expected_payload); 1388 } 1389 Some(S::Udp(s)) => { 1390 assert_eq!(&test.transport, &Some(H::Udp(s.to_header()))); 1391 } 1392 Some(S::Tcp(s)) => { 1393 assert_eq!(&test.transport, &Some(H::Tcp(s.to_header()))); 1394 } 1395 None => { 1396 assert_eq!(&test.transport, &None); 1397 } 1398 } 1399 } 1400 } 1401 1402 // from_ethernet_slice 1403 if test.link.is_some() { 1404 if data.len() < Ethernet2Header::LEN { 1405 assert_eq!( 1406 LenError { 1407 required_len: Ethernet2Header::LEN, 1408 len: data.len(), 1409 len_source: LenSource::Slice, 1410 layer: Layer::Ethernet2Header, 1411 layer_start_offset: 0 1412 }, 1413 LaxSlicedPacket::from_ethernet(&data).unwrap_err() 1414 ); 1415 } else { 1416 let actual = LaxSlicedPacket::from_ethernet(&data).unwrap(); 1417 assert_eq!(actual.stop_err, expected_stop_err); 1418 match expected_stop_err.as_ref().map(|v| v.1) { 1419 None => { 1420 assert_eq!( 1421 test.link, 1422 actual.link.as_ref().map(|v| v.to_header()).flatten() 1423 ); 1424 compare_vlan(test, data, &actual); 1425 compare_ip(test, &actual); 1426 compare_transport( 1427 test, 1428 test.is_ip_payload_fragmented(), 1429 expected_payload, 1430 &actual, 1431 ); 1432 } 1433 Some(Layer::VlanHeader) => { 1434 assert_eq!( 1435 test.link, 1436 actual.link.as_ref().map(|v| v.to_header()).flatten() 1437 ); 1438 compare_vlan(test, data, &actual); 1439 assert_eq!(None, actual.net); 1440 assert_eq!(None, actual.transport); 1441 } 1442 Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => { 1443 assert_eq!( 1444 test.link, 1445 actual.link.as_ref().map(|v| v.to_header()).flatten() 1446 ); 1447 compare_vlan(test, data, &actual); 1448 assert_eq!(None, actual.net); 1449 assert_eq!(None, actual.transport); 1450 } 1451 Some(Layer::IpAuthHeader) 1452 | Some(Layer::Ipv6ExtHeader) 1453 | Some(Layer::Ipv6HopByHopHeader) 1454 | Some(Layer::Ipv6DestOptionsHeader) 1455 | Some(Layer::Ipv6RouteHeader) 1456 | Some(Layer::Ipv6FragHeader) => { 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_header_only(test, &actual); 1463 assert_eq!(None, actual.transport); 1464 } 1465 Some(Layer::TcpHeader) 1466 | Some(Layer::UdpHeader) 1467 | Some(Layer::Icmpv4) 1468 | Some(Layer::Icmpv6) => { 1469 assert_eq!( 1470 test.link, 1471 actual.link.as_ref().map(|v| v.to_header()).flatten() 1472 ); 1473 compare_vlan(test, data, &actual); 1474 compare_ip(test, &actual); 1475 assert_eq!(None, actual.transport); 1476 } 1477 _ => unreachable!("error in an unexpected layer"), 1478 } 1479 } 1480 } 1481 // from_ether_type (vlan at start) 1482 if test.link.is_none() && test.vlan.is_some() { 1483 for ether_type in VLAN_ETHER_TYPES { 1484 let actual = LaxSlicedPacket::from_ether_type(ether_type, data); 1485 assert_eq!(actual.stop_err, expected_stop_err); 1486 assert_eq!( 1487 Some(LinkSlice::EtherPayload(EtherPayloadSlice { 1488 ether_type, 1489 payload: data 1490 })), 1491 actual.link 1492 ); 1493 compare_vlan(test, data, &actual); 1494 match expected_stop_err.as_ref().map(|v| v.1) { 1495 None => { 1496 compare_ip(test, &actual); 1497 compare_transport( 1498 test, 1499 test.is_ip_payload_fragmented(), 1500 expected_payload, 1501 &actual, 1502 ); 1503 } 1504 Some(Layer::VlanHeader) => { 1505 assert_eq!(None, actual.net); 1506 assert_eq!(None, actual.transport); 1507 } 1508 Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => { 1509 assert_eq!(None, actual.net); 1510 assert_eq!(None, actual.transport); 1511 } 1512 Some(Layer::IpAuthHeader) 1513 | Some(Layer::Ipv6ExtHeader) 1514 | Some(Layer::Ipv6HopByHopHeader) 1515 | Some(Layer::Ipv6DestOptionsHeader) 1516 | Some(Layer::Ipv6RouteHeader) 1517 | Some(Layer::Ipv6FragHeader) => { 1518 compare_ip_header_only(test, &actual); 1519 assert_eq!(None, actual.transport); 1520 } 1521 Some(Layer::TcpHeader) 1522 | Some(Layer::UdpHeader) 1523 | Some(Layer::Icmpv4) 1524 | Some(Layer::Icmpv6) => { 1525 compare_ip(test, &actual); 1526 assert_eq!(None, actual.transport); 1527 } 1528 _ => unreachable!("error in an unexpected layer"), 1529 } 1530 } 1531 } 1532 // from_ether_type (ip at start) 1533 if test.link.is_none() && test.vlan.is_none() { 1534 if let Some(ip) = &test.net { 1535 let ether_type = match ip { 1536 NetHeaders::Ipv4(_, _) => ether_type::IPV4, 1537 NetHeaders::Ipv6(_, _) => ether_type::IPV6, 1538 NetHeaders::Arp(_) => unreachable!(), 1539 }; 1540 let actual = LaxSlicedPacket::from_ether_type(ether_type, &data); 1541 assert_eq!(actual.stop_err, expected_stop_err); 1542 assert_eq!( 1543 Some(LinkSlice::EtherPayload(EtherPayloadSlice { 1544 ether_type, 1545 payload: data 1546 })), 1547 actual.link 1548 ); 1549 assert_eq!(test.vlan, None); 1550 match expected_stop_err.as_ref().map(|v| v.1) { 1551 None => { 1552 compare_ip(test, &actual); 1553 compare_transport( 1554 test, 1555 test.is_ip_payload_fragmented(), 1556 expected_payload, 1557 &actual, 1558 ); 1559 } 1560 Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => { 1561 assert_eq!(None, actual.net); 1562 assert_eq!(None, actual.transport); 1563 } 1564 Some(Layer::IpAuthHeader) 1565 | Some(Layer::Ipv6ExtHeader) 1566 | Some(Layer::Ipv6HopByHopHeader) 1567 | Some(Layer::Ipv6DestOptionsHeader) 1568 | Some(Layer::Ipv6RouteHeader) 1569 | Some(Layer::Ipv6FragHeader) => { 1570 compare_ip_header_only(test, &actual); 1571 assert_eq!(None, actual.transport); 1572 } 1573 Some(Layer::TcpHeader) 1574 | Some(Layer::UdpHeader) 1575 | Some(Layer::Icmpv4) 1576 | Some(Layer::Icmpv6) => { 1577 compare_ip(test, &actual); 1578 assert_eq!(None, actual.transport); 1579 } 1580 _ => unreachable!("error in an unexpected layer"), 1581 } 1582 } 1583 } 1584 // from_ip_slice 1585 if test.link.is_none() && test.vlan.is_none() && test.net.is_some() { 1586 if let Some(err) = expected_ip_err { 1587 assert_eq!(err, LaxSlicedPacket::from_ip(&data).unwrap_err()); 1588 } else { 1589 let actual = LaxSlicedPacket::from_ip(&data).unwrap(); 1590 assert_eq!(actual.stop_err, expected_stop_err); 1591 assert_eq!(actual.link, None); 1592 assert_eq!(test.vlan, None); 1593 match expected_stop_err.as_ref().map(|v| v.1) { 1594 None => { 1595 compare_ip(test, &actual); 1596 compare_transport( 1597 test, 1598 test.is_ip_payload_fragmented(), 1599 expected_payload, 1600 &actual, 1601 ); 1602 } 1603 Some(Layer::IpAuthHeader) 1604 | Some(Layer::Ipv6ExtHeader) 1605 | Some(Layer::Ipv6HopByHopHeader) 1606 | Some(Layer::Ipv6DestOptionsHeader) 1607 | Some(Layer::Ipv6RouteHeader) 1608 | Some(Layer::Ipv6FragHeader) => { 1609 compare_ip_header_only(test, &actual); 1610 assert_eq!(None, actual.transport); 1611 } 1612 Some(Layer::TcpHeader) 1613 | Some(Layer::UdpHeader) 1614 | Some(Layer::Icmpv4) 1615 | Some(Layer::Icmpv6) => { 1616 compare_ip(test, &actual); 1617 assert_eq!(None, actual.transport); 1618 } 1619 _ => unreachable!("error in an unexpected layer"), 1620 } 1621 } 1622 } 1623 } 1624 } 1625