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