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