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