1 use crate::err::*; 2 3 /// "Catch all" error for all `from_slice` or `read` errors (supports automatic conversion from all 4 /// other slice errors). 5 /// 6 /// This type aggregates all errors that can be caused by decoding from a slice or reading 7 /// from an io stream. 8 /// 9 /// This type can be used as a "catch all" type for errors caused by `from_slice` or 10 /// `read` functions as all errors from these functions can be converted into this type. 11 #[derive(Debug)] 12 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 13 pub enum ReadError { 14 /// IO error was encountered while reading header or expected packet contents. 15 Io(std::io::Error), 16 17 /// Error when parsing had to be aborted because of a length error (usually 18 /// not enough data being available). 19 Len(LenError), 20 21 /// Error while parsing a double vlan header. 22 DoubleVlan(double_vlan::HeaderError), 23 24 /// Error while parsing a IP header. 25 Ip(ip::HeaderError), 26 27 /// Error while parsing a IP authentication header. 28 IpAuth(ip_auth::HeaderError), 29 30 /// Error while parsing a IPv4 header. 31 Ipv4(ipv4::HeaderError), 32 33 /// Error while parsing a IPv6 header. 34 Ipv6(ipv6::HeaderError), 35 36 /// Error while parsing a IPv6 extension header. 37 Ipv6Exts(ipv6_exts::HeaderError), 38 39 /// Error while parsing a Linux Cooked Capture v1 (SLL) 40 LinuxSll(linux_sll::HeaderError), 41 42 /// Error while parsing a TCP extension header. 43 Tcp(tcp::HeaderError), 44 } 45 46 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 47 impl ReadError { io(&self) -> Option<&std::io::Error>48 pub fn io(&self) -> Option<&std::io::Error> { 49 match self { 50 ReadError::Io(err) => Some(err), 51 _ => None, 52 } 53 } len(&self) -> Option<&LenError>54 pub fn len(&self) -> Option<&LenError> { 55 match self { 56 ReadError::Len(err) => Some(err), 57 _ => None, 58 } 59 } double_vlan(&self) -> Option<&double_vlan::HeaderError>60 pub fn double_vlan(&self) -> Option<&double_vlan::HeaderError> { 61 match self { 62 ReadError::DoubleVlan(err) => Some(err), 63 _ => None, 64 } 65 } ip(&self) -> Option<&ip::HeaderError>66 pub fn ip(&self) -> Option<&ip::HeaderError> { 67 match self { 68 ReadError::Ip(err) => Some(err), 69 _ => None, 70 } 71 } ip_auth(&self) -> Option<&ip_auth::HeaderError>72 pub fn ip_auth(&self) -> Option<&ip_auth::HeaderError> { 73 match self { 74 ReadError::IpAuth(err) => Some(err), 75 _ => None, 76 } 77 } ipv4(&self) -> Option<&ipv4::HeaderError>78 pub fn ipv4(&self) -> Option<&ipv4::HeaderError> { 79 match self { 80 ReadError::Ipv4(err) => Some(err), 81 _ => None, 82 } 83 } ipv6(&self) -> Option<&ipv6::HeaderError>84 pub fn ipv6(&self) -> Option<&ipv6::HeaderError> { 85 match self { 86 ReadError::Ipv6(err) => Some(err), 87 _ => None, 88 } 89 } ipv6_exts(&self) -> Option<&ipv6_exts::HeaderError>90 pub fn ipv6_exts(&self) -> Option<&ipv6_exts::HeaderError> { 91 match self { 92 ReadError::Ipv6Exts(err) => Some(err), 93 _ => None, 94 } 95 } linux_sll(&self) -> Option<&linux_sll::HeaderError>96 pub fn linux_sll(&self) -> Option<&linux_sll::HeaderError> { 97 match self { 98 ReadError::LinuxSll(err) => Some(err), 99 _ => None, 100 } 101 } tcp(&self) -> Option<&tcp::HeaderError>102 pub fn tcp(&self) -> Option<&tcp::HeaderError> { 103 match self { 104 ReadError::Tcp(err) => Some(err), 105 _ => None, 106 } 107 } 108 } 109 110 impl core::fmt::Display for ReadError { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result111 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 112 use crate::err::ReadError::*; 113 match self { 114 Io(err) => err.fmt(f), 115 Len(err) => err.fmt(f), 116 DoubleVlan(err) => err.fmt(f), 117 Ip(err) => err.fmt(f), 118 IpAuth(err) => err.fmt(f), 119 Ipv4(err) => err.fmt(f), 120 Ipv6(err) => err.fmt(f), 121 Ipv6Exts(err) => err.fmt(f), 122 LinuxSll(err) => err.fmt(f), 123 Tcp(err) => err.fmt(f), 124 } 125 } 126 } 127 128 #[cfg(feature = "std")] 129 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 130 impl std::error::Error for ReadError { source(&self) -> Option<&(dyn std::error::Error + 'static)>131 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 132 match self { 133 ReadError::Io(err) => Some(err), 134 ReadError::Len(err) => Some(err), 135 ReadError::DoubleVlan(err) => Some(err), 136 ReadError::Ip(err) => Some(err), 137 ReadError::IpAuth(err) => Some(err), 138 ReadError::Ipv4(err) => Some(err), 139 ReadError::Ipv6(err) => Some(err), 140 ReadError::Ipv6Exts(err) => Some(err), 141 ReadError::LinuxSll(err) => Some(err), 142 ReadError::Tcp(err) => Some(err), 143 } 144 } 145 } 146 147 // io & len error conversions 148 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 149 impl From<std::io::Error> for ReadError { from(value: std::io::Error) -> Self150 fn from(value: std::io::Error) -> Self { 151 ReadError::Io(value) 152 } 153 } 154 155 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 156 impl From<LenError> for ReadError { from(value: LenError) -> Self157 fn from(value: LenError) -> Self { 158 ReadError::Len(value) 159 } 160 } 161 162 // double vlan error conversions 163 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 164 impl From<double_vlan::HeaderError> for ReadError { from(value: double_vlan::HeaderError) -> Self165 fn from(value: double_vlan::HeaderError) -> Self { 166 ReadError::DoubleVlan(value) 167 } 168 } 169 170 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 171 impl From<double_vlan::HeaderReadError> for ReadError { from(value: double_vlan::HeaderReadError) -> Self172 fn from(value: double_vlan::HeaderReadError) -> Self { 173 use double_vlan::HeaderReadError::*; 174 match value { 175 Io(err) => ReadError::Io(err), 176 Content(err) => ReadError::DoubleVlan(err), 177 } 178 } 179 } 180 181 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 182 impl From<double_vlan::HeaderSliceError> for ReadError { from(value: double_vlan::HeaderSliceError) -> Self183 fn from(value: double_vlan::HeaderSliceError) -> Self { 184 use double_vlan::HeaderSliceError::*; 185 match value { 186 Len(err) => ReadError::Len(err), 187 Content(err) => ReadError::DoubleVlan(err), 188 } 189 } 190 } 191 192 // ip error conversions 193 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 194 impl From<ip::HeaderError> for ReadError { from(value: ip::HeaderError) -> Self195 fn from(value: ip::HeaderError) -> Self { 196 ReadError::Ip(value) 197 } 198 } 199 200 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 201 impl From<ip::HeadersError> for ReadError { from(value: ip::HeadersError) -> Self202 fn from(value: ip::HeadersError) -> Self { 203 match value { 204 ip::HeadersError::Ip(err) => ReadError::Ip(err), 205 ip::HeadersError::Ipv4Ext(err) => ReadError::IpAuth(err), 206 ip::HeadersError::Ipv6Ext(err) => ReadError::Ipv6Exts(err), 207 } 208 } 209 } 210 211 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 212 impl From<ip::HeaderReadError> for ReadError { from(value: ip::HeaderReadError) -> Self213 fn from(value: ip::HeaderReadError) -> Self { 214 use ip::HeaderReadError::*; 215 match value { 216 Io(err) => ReadError::Io(err), 217 Len(err) => ReadError::Len(err), 218 Content(err) => err.into(), 219 } 220 } 221 } 222 223 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 224 impl From<ip::HeadersSliceError> for ReadError { from(value: ip::HeadersSliceError) -> Self225 fn from(value: ip::HeadersSliceError) -> Self { 226 use ip::HeadersSliceError::*; 227 match value { 228 Len(err) => ReadError::Len(err), 229 Content(err) => err.into(), 230 } 231 } 232 } 233 234 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 235 impl From<ip::SliceError> for ReadError { from(value: ip::SliceError) -> Self236 fn from(value: ip::SliceError) -> Self { 237 use ip::SliceError::*; 238 match value { 239 Len(err) => ReadError::Len(err), 240 IpHeaders(err) => err.into(), 241 } 242 } 243 } 244 245 // ip auth error conversions 246 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 247 impl From<ip_auth::HeaderError> for ReadError { from(value: ip_auth::HeaderError) -> Self248 fn from(value: ip_auth::HeaderError) -> Self { 249 ReadError::IpAuth(value) 250 } 251 } 252 253 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 254 impl From<ip_auth::HeaderReadError> for ReadError { from(value: ip_auth::HeaderReadError) -> Self255 fn from(value: ip_auth::HeaderReadError) -> Self { 256 use ip_auth::HeaderReadError::*; 257 match value { 258 Io(err) => ReadError::Io(err), 259 Content(err) => ReadError::IpAuth(err), 260 } 261 } 262 } 263 264 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 265 impl From<ip_auth::HeaderSliceError> for ReadError { from(value: ip_auth::HeaderSliceError) -> Self266 fn from(value: ip_auth::HeaderSliceError) -> Self { 267 use ip_auth::HeaderSliceError::*; 268 match value { 269 Len(err) => ReadError::Len(err), 270 Content(err) => ReadError::IpAuth(err), 271 } 272 } 273 } 274 275 // ipv4 error conversions 276 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 277 impl From<ipv4::HeaderError> for ReadError { from(value: ipv4::HeaderError) -> Self278 fn from(value: ipv4::HeaderError) -> Self { 279 ReadError::Ipv4(value) 280 } 281 } 282 283 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 284 impl From<ipv4::HeaderReadError> for ReadError { from(value: ipv4::HeaderReadError) -> Self285 fn from(value: ipv4::HeaderReadError) -> Self { 286 use ipv4::HeaderReadError::*; 287 match value { 288 Io(err) => ReadError::Io(err), 289 Content(err) => ReadError::Ipv4(err), 290 } 291 } 292 } 293 294 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 295 impl From<ipv4::HeaderSliceError> for ReadError { from(value: ipv4::HeaderSliceError) -> Self296 fn from(value: ipv4::HeaderSliceError) -> Self { 297 use ipv4::HeaderSliceError::*; 298 match value { 299 Len(err) => ReadError::Len(err), 300 Content(err) => ReadError::Ipv4(err), 301 } 302 } 303 } 304 305 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 306 impl From<ipv4::SliceError> for ReadError { from(value: ipv4::SliceError) -> Self307 fn from(value: ipv4::SliceError) -> Self { 308 use ipv4::SliceError::*; 309 match value { 310 Len(err) => ReadError::Len(err), 311 Header(err) => ReadError::Ipv4(err), 312 Exts(err) => ReadError::IpAuth(err), 313 } 314 } 315 } 316 317 // ipv6 error conversions 318 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 319 impl From<ipv6::HeaderError> for ReadError { from(value: ipv6::HeaderError) -> Self320 fn from(value: ipv6::HeaderError) -> Self { 321 ReadError::Ipv6(value) 322 } 323 } 324 325 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 326 impl From<ipv6::HeaderReadError> for ReadError { from(value: ipv6::HeaderReadError) -> Self327 fn from(value: ipv6::HeaderReadError) -> Self { 328 use ipv6::HeaderReadError::*; 329 match value { 330 Io(err) => ReadError::Io(err), 331 Content(err) => ReadError::Ipv6(err), 332 } 333 } 334 } 335 336 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 337 impl From<ipv6::HeaderSliceError> for ReadError { from(value: ipv6::HeaderSliceError) -> Self338 fn from(value: ipv6::HeaderSliceError) -> Self { 339 use ipv6::HeaderSliceError::*; 340 match value { 341 Len(err) => ReadError::Len(err), 342 Content(err) => ReadError::Ipv6(err), 343 } 344 } 345 } 346 347 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 348 impl From<ipv6::SliceError> for ReadError { from(value: ipv6::SliceError) -> Self349 fn from(value: ipv6::SliceError) -> Self { 350 use ipv6::SliceError::*; 351 match value { 352 Len(err) => ReadError::Len(err), 353 Header(err) => ReadError::Ipv6(err), 354 Exts(err) => ReadError::Ipv6Exts(err), 355 } 356 } 357 } 358 359 // ipv6 exts error conversions 360 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 361 impl From<ipv6_exts::HeaderError> for ReadError { from(value: ipv6_exts::HeaderError) -> Self362 fn from(value: ipv6_exts::HeaderError) -> Self { 363 ReadError::Ipv6Exts(value) 364 } 365 } 366 367 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 368 impl From<ipv6_exts::HeaderReadError> for ReadError { from(value: ipv6_exts::HeaderReadError) -> Self369 fn from(value: ipv6_exts::HeaderReadError) -> Self { 370 use ipv6_exts::HeaderReadError::*; 371 match value { 372 Io(err) => ReadError::Io(err), 373 Content(err) => ReadError::Ipv6Exts(err), 374 } 375 } 376 } 377 378 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 379 impl From<ipv6_exts::HeaderSliceError> for ReadError { from(value: ipv6_exts::HeaderSliceError) -> Self380 fn from(value: ipv6_exts::HeaderSliceError) -> Self { 381 use ipv6_exts::HeaderSliceError::*; 382 match value { 383 Len(err) => ReadError::Len(err), 384 Content(err) => ReadError::Ipv6Exts(err), 385 } 386 } 387 } 388 389 // linux sll error conversions 390 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 391 impl From<linux_sll::HeaderError> for ReadError { from(value: linux_sll::HeaderError) -> Self392 fn from(value: linux_sll::HeaderError) -> Self { 393 ReadError::LinuxSll(value) 394 } 395 } 396 397 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 398 impl From<linux_sll::HeaderReadError> for ReadError { from(value: linux_sll::HeaderReadError) -> Self399 fn from(value: linux_sll::HeaderReadError) -> Self { 400 use linux_sll::HeaderReadError::*; 401 match value { 402 Io(err) => ReadError::Io(err), 403 Content(err) => ReadError::LinuxSll(err), 404 } 405 } 406 } 407 408 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 409 impl From<linux_sll::HeaderSliceError> for ReadError { from(value: linux_sll::HeaderSliceError) -> Self410 fn from(value: linux_sll::HeaderSliceError) -> Self { 411 use linux_sll::HeaderSliceError::*; 412 match value { 413 Len(err) => ReadError::Len(err), 414 Content(err) => ReadError::LinuxSll(err), 415 } 416 } 417 } 418 419 // packet error conversions 420 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 421 impl From<packet::SliceError> for ReadError { from(value: packet::SliceError) -> Self422 fn from(value: packet::SliceError) -> Self { 423 use packet::SliceError::*; 424 match value { 425 Len(err) => ReadError::Len(err), 426 LinuxSll(err) => ReadError::LinuxSll(err), 427 Ip(err) => ReadError::Ip(err), 428 Ipv4(err) => ReadError::Ipv4(err), 429 Ipv6(err) => ReadError::Ipv6(err), 430 Ipv4Exts(err) => ReadError::IpAuth(err), 431 Ipv6Exts(err) => ReadError::Ipv6Exts(err), 432 Tcp(err) => ReadError::Tcp(err), 433 } 434 } 435 } 436 437 // tcp error conversions 438 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 439 impl From<tcp::HeaderError> for ReadError { from(value: tcp::HeaderError) -> Self440 fn from(value: tcp::HeaderError) -> Self { 441 ReadError::Tcp(value) 442 } 443 } 444 445 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 446 impl From<tcp::HeaderReadError> for ReadError { from(value: tcp::HeaderReadError) -> Self447 fn from(value: tcp::HeaderReadError) -> Self { 448 use tcp::HeaderReadError::*; 449 match value { 450 Io(err) => ReadError::Io(err), 451 Content(err) => ReadError::Tcp(err), 452 } 453 } 454 } 455 456 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 457 impl From<tcp::HeaderSliceError> for ReadError { from(value: tcp::HeaderSliceError) -> Self458 fn from(value: tcp::HeaderSliceError) -> Self { 459 use tcp::HeaderSliceError::*; 460 match value { 461 Len(err) => ReadError::Len(err), 462 Content(err) => ReadError::Tcp(err), 463 } 464 } 465 } 466 467 #[cfg(test)] 468 mod tests { 469 use crate::{ 470 err::{ReadError::*, *}, 471 LenSource, 472 }; 473 use crate::{ArpHardwareId, EtherType}; 474 use std::error::Error; 475 use std::format; 476 477 #[test] debug_source()478 fn debug_source() { 479 let test_values: [(&str, ReadError); 10] = [ 480 ( 481 "Len", 482 Len(LenError { 483 required_len: 0, 484 len: 0, 485 len_source: LenSource::Slice, 486 layer: Layer::Icmpv4, 487 layer_start_offset: 0, 488 }), 489 ), 490 ( 491 "LinuxSll", 492 LinuxSll(linux_sll::HeaderError::UnsupportedArpHardwareId { 493 arp_hardware_type: ArpHardwareId::ETHERNET, 494 }), 495 ), 496 ( 497 "DoubleVlan", 498 DoubleVlan(double_vlan::HeaderError::NonVlanEtherType { 499 unexpected_ether_type: EtherType(123), 500 }), 501 ), 502 ( 503 "Ip", 504 Ip(ip::HeaderError::UnsupportedIpVersion { 505 version_number: 123, 506 }), 507 ), 508 ("IpAuth", IpAuth(ip_auth::HeaderError::ZeroPayloadLen)), 509 ( 510 "Ipv4", 511 Ipv4(ipv4::HeaderError::UnexpectedVersion { version_number: 1 }), 512 ), 513 ( 514 "Ipv6", 515 Ipv6(ipv6::HeaderError::UnexpectedVersion { version_number: 1 }), 516 ), 517 ( 518 "Ipv6Exts", 519 Ipv6Exts(ipv6_exts::HeaderError::HopByHopNotAtStart), 520 ), 521 ( 522 "LinuxSll", 523 LinuxSll(linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 }), 524 ), 525 ( 526 "Tcp", 527 Tcp(tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }), 528 ), 529 ]; 530 for (prefix, value) in &test_values { 531 // display 532 assert_eq!( 533 format!("{:?}", value), 534 format!("{}({:?})", prefix, value.source().unwrap()) 535 ); 536 } 537 // io handled separately as source points to the underlying type 538 { 539 let io_error = || std::io::Error::new(std::io::ErrorKind::Other, "some error"); 540 assert_eq!( 541 format!("Io({:?})", io_error()), 542 format!("{:?}", Io(io_error())) 543 ); 544 } 545 } 546 547 #[test] display_source()548 fn display_source() { 549 let test_values: [ReadError; 10] = [ 550 Len(LenError { 551 required_len: 0, 552 len: 0, 553 len_source: LenSource::Slice, 554 layer: Layer::Icmpv4, 555 layer_start_offset: 0, 556 }), 557 LinuxSll(linux_sll::HeaderError::UnsupportedArpHardwareId { 558 arp_hardware_type: ArpHardwareId::ETHERNET, 559 }), 560 DoubleVlan(double_vlan::HeaderError::NonVlanEtherType { 561 unexpected_ether_type: EtherType(123), 562 }), 563 Ip(ip::HeaderError::UnsupportedIpVersion { 564 version_number: 123, 565 }), 566 IpAuth(ip_auth::HeaderError::ZeroPayloadLen), 567 Ipv4(ipv4::HeaderError::UnexpectedVersion { version_number: 1 }), 568 Ipv6(ipv6::HeaderError::UnexpectedVersion { version_number: 1 }), 569 Ipv6Exts(ipv6_exts::HeaderError::HopByHopNotAtStart), 570 LinuxSll(linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 }), 571 Tcp(tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }), 572 ]; 573 for value in &test_values { 574 // display 575 assert_eq!(format!("{}", value), format!("{}", value.source().unwrap())); 576 } 577 // io handled separately as source points to the underlying type 578 { 579 let io_error = || std::io::Error::new(std::io::ErrorKind::Other, "some error"); 580 assert_eq!(format!("{}", io_error()), format!("{}", Io(io_error()))); 581 assert!(Io(io_error()).source().is_some()); 582 } 583 } 584 585 #[test] accessors()586 fn accessors() { 587 use ReadError::*; 588 let io_error = || std::io::Error::new(std::io::ErrorKind::Other, "some error"); 589 let len_error = || LenError { 590 required_len: 0, 591 len: 0, 592 len_source: LenSource::Slice, 593 layer: Layer::Icmpv4, 594 layer_start_offset: 0, 595 }; 596 let double_vlan_error = || double_vlan::HeaderError::NonVlanEtherType { 597 unexpected_ether_type: EtherType(1), 598 }; 599 let ip_error = || ip::HeaderError::UnsupportedIpVersion { version_number: 0 }; 600 let ipv4_error = || ipv4::HeaderError::UnexpectedVersion { version_number: 1 }; 601 let ipv6_error = || ipv6::HeaderError::UnexpectedVersion { version_number: 1 }; 602 let ip_auth_error = || ip_auth::HeaderError::ZeroPayloadLen; 603 let ipv6_exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart; 604 let linux_sll_error = 605 || linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 }; 606 let tcp_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }; 607 608 // io 609 assert!(Io(io_error()).io().is_some()); 610 assert!(Ipv4(ipv4_error()).io().is_none()); 611 612 // len 613 assert_eq!(Len(len_error()).len(), Some(&len_error())); 614 assert_eq!(Ipv4(ipv4_error()).len(), None); 615 616 // linux sll 617 assert_eq!( 618 LinuxSll(linux_sll_error()).linux_sll(), 619 Some(&linux_sll_error()) 620 ); 621 assert_eq!(Ipv4(ipv4_error()).linux_sll(), None); 622 623 // double_vlan 624 assert_eq!( 625 DoubleVlan(double_vlan_error()).double_vlan(), 626 Some(&double_vlan_error()) 627 ); 628 assert_eq!(Ipv4(ipv4_error()).double_vlan(), None); 629 630 // ip 631 assert_eq!(Ip(ip_error()).ip(), Some(&ip_error())); 632 assert_eq!(Ipv4(ipv4_error()).ip(), None); 633 634 // ip_auth 635 assert_eq!(IpAuth(ip_auth_error()).ip_auth(), Some(&ip_auth_error())); 636 assert_eq!(Ipv4(ipv4_error()).ip_auth(), None); 637 638 // ipv4 639 assert_eq!(Ipv4(ipv4_error()).ipv4(), Some(&ipv4_error())); 640 assert_eq!(IpAuth(ip_auth_error()).ipv4(), None); 641 642 // ipv6 643 assert_eq!(Ipv6(ipv6_error()).ipv6(), Some(&ipv6_error())); 644 assert_eq!(IpAuth(ip_auth_error()).ipv6(), None); 645 646 // ipv6_exts 647 assert_eq!( 648 Ipv6Exts(ipv6_exts_error()).ipv6_exts(), 649 Some(&ipv6_exts_error()) 650 ); 651 assert_eq!(IpAuth(ip_auth_error()).ipv6_exts(), None); 652 653 // linux_sll 654 assert_eq!( 655 LinuxSll(linux_sll_error()).linux_sll(), 656 Some(&linux_sll_error()) 657 ); 658 assert_eq!(IpAuth(ip_auth_error()).linux_sll(), None); 659 660 // tcp 661 assert_eq!(Tcp(tcp_error()).tcp(), Some(&tcp_error())); 662 assert_eq!(IpAuth(ip_auth_error()).tcp(), None); 663 } 664 665 #[test] from()666 fn from() { 667 let io_error = 668 || -> std::io::Error { std::io::Error::new(std::io::ErrorKind::Other, "some error") }; 669 let len_error = || -> LenError { 670 LenError { 671 required_len: 0, 672 len: 0, 673 len_source: LenSource::Slice, 674 layer: Layer::Icmpv4, 675 layer_start_offset: 0, 676 } 677 }; 678 679 // io & len 680 assert!(ReadError::from(io_error()).io().is_some()); 681 assert_eq!(&len_error(), ReadError::from(len_error()).len().unwrap()); 682 683 // linux sll 684 { 685 let header_error = || linux_sll::HeaderError::UnsupportedArpHardwareId { 686 arp_hardware_type: ArpHardwareId::ETHERNET, 687 }; 688 assert_eq!( 689 &header_error(), 690 ReadError::from(header_error()).linux_sll().unwrap() 691 ); 692 assert_eq!( 693 &header_error(), 694 ReadError::from(linux_sll::HeaderReadError::Content(header_error())) 695 .linux_sll() 696 .unwrap() 697 ); 698 assert!(ReadError::from(linux_sll::HeaderReadError::Io(io_error())) 699 .io() 700 .is_some()); 701 assert_eq!( 702 &header_error(), 703 ReadError::from(linux_sll::HeaderSliceError::Content(header_error())) 704 .linux_sll() 705 .unwrap() 706 ); 707 assert_eq!( 708 &len_error(), 709 ReadError::from(linux_sll::HeaderSliceError::Len(len_error())) 710 .len() 711 .unwrap() 712 ); 713 assert_eq!( 714 &header_error(), 715 ReadError::from(linux_sll::HeaderSliceError::Content(header_error())) 716 .linux_sll() 717 .unwrap() 718 ); 719 } 720 721 // double vlan errors 722 { 723 let header_error = || double_vlan::HeaderError::NonVlanEtherType { 724 unexpected_ether_type: EtherType(123), 725 }; 726 assert_eq!( 727 &header_error(), 728 ReadError::from(header_error()).double_vlan().unwrap() 729 ); 730 assert_eq!( 731 &header_error(), 732 ReadError::from(double_vlan::HeaderReadError::Content(header_error())) 733 .double_vlan() 734 .unwrap() 735 ); 736 assert!( 737 ReadError::from(double_vlan::HeaderReadError::Io(io_error())) 738 .io() 739 .is_some() 740 ); 741 assert_eq!( 742 &header_error(), 743 ReadError::from(double_vlan::HeaderSliceError::Content(header_error())) 744 .double_vlan() 745 .unwrap() 746 ); 747 assert_eq!( 748 &len_error(), 749 ReadError::from(double_vlan::HeaderSliceError::Len(len_error())) 750 .len() 751 .unwrap() 752 ); 753 assert_eq!( 754 &header_error(), 755 ReadError::from(double_vlan::HeaderSliceError::Content(header_error())) 756 .double_vlan() 757 .unwrap() 758 ); 759 } 760 761 // ip errors 762 { 763 let header_error = || ip::HeaderError::UnsupportedIpVersion { 764 version_number: 123, 765 }; 766 assert_eq!( 767 &header_error(), 768 ReadError::from(header_error()).ip().unwrap() 769 ); 770 assert_eq!( 771 &header_error(), 772 ReadError::from(ip::HeaderReadError::Content(ip::HeadersError::Ip( 773 header_error() 774 ))) 775 .ip() 776 .unwrap() 777 ); 778 assert_eq!( 779 &len_error(), 780 ReadError::from(ip::HeaderReadError::Len(len_error())) 781 .len() 782 .unwrap() 783 ); 784 assert!(ReadError::from(ip::HeaderReadError::Io(io_error())) 785 .io() 786 .is_some()); 787 assert_eq!( 788 &header_error(), 789 ReadError::from(ip::HeadersSliceError::Content(ip::HeadersError::Ip( 790 header_error() 791 ))) 792 .ip() 793 .unwrap() 794 ); 795 assert_eq!( 796 &len_error(), 797 ReadError::from(ip::HeadersSliceError::Len(len_error())) 798 .len() 799 .unwrap() 800 ); 801 assert_eq!( 802 &header_error(), 803 ReadError::from(ip::HeadersSliceError::Content(ip::HeadersError::Ip( 804 header_error() 805 ))) 806 .ip() 807 .unwrap() 808 ); 809 assert_eq!( 810 &len_error(), 811 ReadError::from(ip::SliceError::Len(len_error())) 812 .len() 813 .unwrap() 814 ); 815 assert_eq!( 816 &header_error(), 817 ReadError::from(ip::SliceError::IpHeaders(ip::HeadersError::Ip( 818 header_error() 819 ))) 820 .ip() 821 .unwrap() 822 ); 823 } 824 825 // ip auth errors 826 { 827 let header_error = || ip_auth::HeaderError::ZeroPayloadLen; 828 assert_eq!( 829 &header_error(), 830 ReadError::from(header_error()).ip_auth().unwrap() 831 ); 832 assert_eq!( 833 &header_error(), 834 ReadError::from(ip_auth::HeaderReadError::Content(header_error())) 835 .ip_auth() 836 .unwrap() 837 ); 838 assert!(ReadError::from(ip_auth::HeaderReadError::Io(io_error())) 839 .io() 840 .is_some()); 841 assert_eq!( 842 &header_error(), 843 ReadError::from(ip_auth::HeaderSliceError::Content(header_error())) 844 .ip_auth() 845 .unwrap() 846 ); 847 assert_eq!( 848 &len_error(), 849 ReadError::from(ip_auth::HeaderSliceError::Len(len_error())) 850 .len() 851 .unwrap() 852 ); 853 assert_eq!( 854 &header_error(), 855 ReadError::from(ip_auth::HeaderSliceError::Content(header_error())) 856 .ip_auth() 857 .unwrap() 858 ); 859 } 860 861 // ipv4 errors 862 { 863 let header_error = || ipv4::HeaderError::UnexpectedVersion { 864 version_number: 123, 865 }; 866 let exts_error = || ip_auth::HeaderError::ZeroPayloadLen; 867 assert_eq!( 868 &header_error(), 869 ReadError::from(header_error()).ipv4().unwrap() 870 ); 871 assert_eq!( 872 &header_error(), 873 ReadError::from(ipv4::HeaderReadError::Content(header_error())) 874 .ipv4() 875 .unwrap() 876 ); 877 assert!(ReadError::from(ipv4::HeaderReadError::Io(io_error())) 878 .io() 879 .is_some()); 880 assert_eq!( 881 &header_error(), 882 ReadError::from(ipv4::HeaderSliceError::Content(header_error())) 883 .ipv4() 884 .unwrap() 885 ); 886 assert_eq!( 887 &len_error(), 888 ReadError::from(ipv4::HeaderSliceError::Len(len_error())) 889 .len() 890 .unwrap() 891 ); 892 assert_eq!( 893 &header_error(), 894 ReadError::from(ipv4::HeaderSliceError::Content(header_error())) 895 .ipv4() 896 .unwrap() 897 ); 898 assert_eq!( 899 &len_error(), 900 ReadError::from(ipv4::SliceError::Len(len_error())) 901 .len() 902 .unwrap() 903 ); 904 assert_eq!( 905 &header_error(), 906 ReadError::from(ipv4::SliceError::Header(header_error())) 907 .ipv4() 908 .unwrap() 909 ); 910 assert_eq!( 911 &exts_error(), 912 ReadError::from(ipv4::SliceError::Exts(exts_error())) 913 .ip_auth() 914 .unwrap() 915 ); 916 } 917 918 // ipv6 errors 919 { 920 let header_error = || ipv6::HeaderError::UnexpectedVersion { 921 version_number: 123, 922 }; 923 let exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart; 924 assert_eq!( 925 &header_error(), 926 ReadError::from(header_error()).ipv6().unwrap() 927 ); 928 assert_eq!( 929 &header_error(), 930 ReadError::from(ipv6::HeaderReadError::Content(header_error())) 931 .ipv6() 932 .unwrap() 933 ); 934 assert!(ReadError::from(ipv6::HeaderReadError::Io(io_error())) 935 .io() 936 .is_some()); 937 assert_eq!( 938 &header_error(), 939 ReadError::from(ipv6::HeaderSliceError::Content(header_error())) 940 .ipv6() 941 .unwrap() 942 ); 943 assert_eq!( 944 &len_error(), 945 ReadError::from(ipv6::HeaderSliceError::Len(len_error())) 946 .len() 947 .unwrap() 948 ); 949 assert_eq!( 950 &header_error(), 951 ReadError::from(ipv6::HeaderSliceError::Content(header_error())) 952 .ipv6() 953 .unwrap() 954 ); 955 assert_eq!( 956 &len_error(), 957 ReadError::from(ipv6::SliceError::Len(len_error())) 958 .len() 959 .unwrap() 960 ); 961 assert_eq!( 962 &header_error(), 963 ReadError::from(ipv6::SliceError::Header(header_error())) 964 .ipv6() 965 .unwrap() 966 ); 967 assert_eq!( 968 &exts_error(), 969 ReadError::from(ipv6::SliceError::Exts(exts_error())) 970 .ipv6_exts() 971 .unwrap() 972 ); 973 } 974 975 // ipv6 exts errors 976 { 977 let header_error = || ipv6_exts::HeaderError::HopByHopNotAtStart; 978 assert_eq!( 979 &header_error(), 980 ReadError::from(header_error()).ipv6_exts().unwrap() 981 ); 982 assert_eq!( 983 &header_error(), 984 ReadError::from(ipv6_exts::HeaderReadError::Content(header_error())) 985 .ipv6_exts() 986 .unwrap() 987 ); 988 assert!(ReadError::from(ipv6_exts::HeaderReadError::Io(io_error())) 989 .io() 990 .is_some()); 991 assert_eq!( 992 &header_error(), 993 ReadError::from(ipv6_exts::HeaderSliceError::Content(header_error())) 994 .ipv6_exts() 995 .unwrap() 996 ); 997 assert_eq!( 998 &len_error(), 999 ReadError::from(ipv6_exts::HeaderSliceError::Len(len_error())) 1000 .len() 1001 .unwrap() 1002 ); 1003 assert_eq!( 1004 &header_error(), 1005 ReadError::from(ipv6_exts::HeaderSliceError::Content(header_error())) 1006 .ipv6_exts() 1007 .unwrap() 1008 ); 1009 } 1010 1011 // linux_sll errors 1012 { 1013 let header_error = 1014 || linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 }; 1015 assert_eq!( 1016 &header_error(), 1017 ReadError::from(header_error()).linux_sll().unwrap() 1018 ); 1019 assert_eq!( 1020 &header_error(), 1021 ReadError::from(linux_sll::HeaderReadError::Content(header_error())) 1022 .linux_sll() 1023 .unwrap() 1024 ); 1025 assert!(ReadError::from(linux_sll::HeaderReadError::Io(io_error())) 1026 .io() 1027 .is_some()); 1028 assert_eq!( 1029 &header_error(), 1030 ReadError::from(linux_sll::HeaderSliceError::Content(header_error())) 1031 .linux_sll() 1032 .unwrap() 1033 ); 1034 assert_eq!( 1035 &len_error(), 1036 ReadError::from(linux_sll::HeaderSliceError::Len(len_error())) 1037 .len() 1038 .unwrap() 1039 ); 1040 assert_eq!( 1041 &header_error(), 1042 ReadError::from(linux_sll::HeaderSliceError::Content(header_error())) 1043 .linux_sll() 1044 .unwrap() 1045 ); 1046 } 1047 1048 // packet error 1049 { 1050 let ip_error = || ip::HeaderError::UnsupportedIpVersion { version_number: 0 }; 1051 let ipv4_error = || ipv4::HeaderError::UnexpectedVersion { version_number: 1 }; 1052 let ipv6_error = || ipv6::HeaderError::UnexpectedVersion { version_number: 1 }; 1053 let ip_auth_error = || ip_auth::HeaderError::ZeroPayloadLen; 1054 let ipv6_exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart; 1055 let tcp_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }; 1056 1057 // IpSliceError 1058 assert_eq!( 1059 &len_error(), 1060 ReadError::from(packet::SliceError::Len(len_error())) 1061 .len() 1062 .unwrap() 1063 ); 1064 assert_eq!( 1065 &ip_error(), 1066 ReadError::from(packet::SliceError::Ip(ip_error())) 1067 .ip() 1068 .unwrap() 1069 ); 1070 assert_eq!( 1071 &ipv4_error(), 1072 ReadError::from(packet::SliceError::Ipv4(ipv4_error())) 1073 .ipv4() 1074 .unwrap() 1075 ); 1076 assert_eq!( 1077 &ipv6_error(), 1078 ReadError::from(packet::SliceError::Ipv6(ipv6_error())) 1079 .ipv6() 1080 .unwrap() 1081 ); 1082 assert_eq!( 1083 &ip_auth_error(), 1084 ReadError::from(packet::SliceError::Ipv4Exts(ip_auth_error())) 1085 .ip_auth() 1086 .unwrap() 1087 ); 1088 assert_eq!( 1089 &ipv6_exts_error(), 1090 ReadError::from(packet::SliceError::Ipv6Exts(ipv6_exts_error())) 1091 .ipv6_exts() 1092 .unwrap() 1093 ); 1094 assert_eq!( 1095 &tcp_error(), 1096 ReadError::from(packet::SliceError::Tcp(tcp_error())) 1097 .tcp() 1098 .unwrap() 1099 ); 1100 } 1101 1102 // tcp errors 1103 { 1104 let header_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }; 1105 assert_eq!( 1106 &header_error(), 1107 ReadError::from(header_error()).tcp().unwrap() 1108 ); 1109 assert_eq!( 1110 &header_error(), 1111 ReadError::from(tcp::HeaderReadError::Content(header_error())) 1112 .tcp() 1113 .unwrap() 1114 ); 1115 assert!(ReadError::from(tcp::HeaderReadError::Io(io_error())) 1116 .io() 1117 .is_some()); 1118 assert_eq!( 1119 &header_error(), 1120 ReadError::from(tcp::HeaderSliceError::Content(header_error())) 1121 .tcp() 1122 .unwrap() 1123 ); 1124 assert_eq!( 1125 &len_error(), 1126 ReadError::from(tcp::HeaderSliceError::Len(len_error())) 1127 .len() 1128 .unwrap() 1129 ); 1130 assert_eq!( 1131 &header_error(), 1132 ReadError::from(tcp::HeaderSliceError::Content(header_error())) 1133 .tcp() 1134 .unwrap() 1135 ); 1136 } 1137 } 1138 } // mod tests 1139