mod.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*! Low-level packet access and construction.
  2. The `wire` module deals with the packet *representation*. It provides two levels
  3. of functionality.
  4. * First, it provides functions to extract fields from sequences of octets,
  5. and to insert fields into sequences of octets. This happens `Packet` family of
  6. structures, e.g. [EthernetFrame] or [Ipv4Packet].
  7. * Second, in cases where the space of valid field values is much smaller than the space
  8. of possible field values, it provides a compact, high-level representation
  9. of packet data that can be parsed from and emitted into a sequence of octets.
  10. This happens through the `Repr` family of structs and enums, e.g. [ArpRepr] or [Ipv4Repr].
  11. [EthernetFrame]: struct.EthernetFrame.html
  12. [Ipv4Packet]: struct.Ipv4Packet.html
  13. [ArpRepr]: enum.ArpRepr.html
  14. [Ipv4Repr]: struct.Ipv4Repr.html
  15. The functions in the `wire` module are designed for use together with `-Cpanic=abort`.
  16. The `Packet` family of data structures guarantees that, if the `Packet::check_len()` method
  17. returned `Ok(())`, then no accessor or setter method will panic; however, the guarantee
  18. provided by `Packet::check_len()` may no longer hold after changing certain fields,
  19. which are listed in the documentation for the specific packet.
  20. The `Packet::new_checked` method is a shorthand for a combination of `Packet::new` and
  21. `Packet::check_len`.
  22. When parsing untrusted input, it is *necessary* to use `Packet::new_checked()`;
  23. so long as the buffer is not modified, no accessor will fail.
  24. When emitting output, though, it is *incorrect* to use `Packet::new_checked()`;
  25. the length check is likely to succeed on a zeroed buffer, but fail on a buffer
  26. filled with data from a previous packet, such as when reusing buffers, resulting
  27. in nondeterministic panics with some network devices but not others.
  28. The buffer length for emission is not calculated by the `Packet` layer.
  29. In the `Repr` family of data structures, the `Repr::parse()` method never panics
  30. as long as `Packet::new_checked()` (or `Packet::check_len()`) has succeeded, and
  31. the `Repr::emit()` method never panics as long as the underlying buffer is exactly
  32. `Repr::buffer_len()` octets long.
  33. # Examples
  34. To emit an IP packet header into an octet buffer, and then parse it back:
  35. ```rust
  36. # #[cfg(feature = "proto-ipv4")]
  37. # {
  38. use smoltcp::phy::ChecksumCapabilities;
  39. use smoltcp::wire::*;
  40. let repr = Ipv4Repr {
  41. src_addr: Ipv4Address::new(10, 0, 0, 1),
  42. dst_addr: Ipv4Address::new(10, 0, 0, 2),
  43. protocol: IpProtocol::Tcp,
  44. payload_len: 10,
  45. hop_limit: 64
  46. };
  47. let mut buffer = vec![0; repr.buffer_len() + repr.payload_len];
  48. { // emission
  49. let mut packet = Ipv4Packet::new(&mut buffer);
  50. repr.emit(&mut packet, &ChecksumCapabilities::default());
  51. }
  52. { // parsing
  53. let packet = Ipv4Packet::new_checked(&buffer)
  54. .expect("truncated packet");
  55. let parsed = Ipv4Repr::parse(&packet, &ChecksumCapabilities::default())
  56. .expect("malformed packet");
  57. assert_eq!(repr, parsed);
  58. }
  59. # }
  60. ```
  61. */
  62. mod field {
  63. pub type Field = ::core::ops::Range<usize>;
  64. pub type Rest = ::core::ops::RangeFrom<usize>;
  65. }
  66. pub mod pretty_print;
  67. mod ethernet;
  68. #[cfg(feature = "proto-ipv4")]
  69. mod arp;
  70. pub(crate) mod ip;
  71. #[cfg(feature = "proto-ipv4")]
  72. mod ipv4;
  73. #[cfg(feature = "proto-ipv6")]
  74. mod ipv6;
  75. #[cfg(feature = "proto-ipv4")]
  76. mod icmpv4;
  77. #[cfg(feature = "proto-ipv6")]
  78. mod icmpv6;
  79. mod udp;
  80. mod tcp;
  81. pub use self::pretty_print::PrettyPrinter;
  82. pub use self::ethernet::{EtherType as EthernetProtocol,
  83. Address as EthernetAddress,
  84. Frame as EthernetFrame};
  85. #[cfg(feature = "proto-ipv4")]
  86. pub use self::arp::{Hardware as ArpHardware,
  87. Operation as ArpOperation,
  88. Packet as ArpPacket,
  89. Repr as ArpRepr};
  90. pub use self::ip::{Version as IpVersion,
  91. Protocol as IpProtocol,
  92. Address as IpAddress,
  93. Endpoint as IpEndpoint,
  94. Repr as IpRepr,
  95. Cidr as IpCidr};
  96. #[cfg(feature = "proto-ipv4")]
  97. pub use self::ipv4::{Address as Ipv4Address,
  98. Packet as Ipv4Packet,
  99. Repr as Ipv4Repr,
  100. Cidr as Ipv4Cidr,
  101. MIN_MTU as IPV4_MIN_MTU};
  102. #[cfg(feature = "proto-ipv6")]
  103. pub use self::ipv6::{Address as Ipv6Address,
  104. Packet as Ipv6Packet,
  105. Repr as Ipv6Repr,
  106. Cidr as Ipv6Cidr,
  107. MIN_MTU as IPV6_MIN_MTU};
  108. #[cfg(feature = "proto-ipv4")]
  109. pub use self::icmpv4::{Message as Icmpv4Message,
  110. DstUnreachable as Icmpv4DstUnreachable,
  111. Redirect as Icmpv4Redirect,
  112. TimeExceeded as Icmpv4TimeExceeded,
  113. ParamProblem as Icmpv4ParamProblem,
  114. Packet as Icmpv4Packet,
  115. Repr as Icmpv4Repr};
  116. #[cfg(feature = "proto-ipv6")]
  117. pub use self::icmpv6::{Message as Icmpv6Message,
  118. DstUnreachable as Icmpv6DstUnreachable,
  119. Packet as Icmpv6Packet,
  120. Repr as Icmpv6Repr};
  121. pub use self::udp::{Packet as UdpPacket,
  122. Repr as UdpRepr};
  123. pub use self::tcp::{SeqNumber as TcpSeqNumber,
  124. Packet as TcpPacket,
  125. TcpOption,
  126. Repr as TcpRepr,
  127. Control as TcpControl};