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