lib.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #![cfg_attr(not(any(test, feature = "std")), no_std)]
  2. #![deny(unsafe_code)]
  3. #![cfg_attr(all(any(feature = "proto-ipv4", feature = "proto-ipv6"), feature = "ethernet"), deny(unused))]
  4. //! The _smoltcp_ library is built in a layered structure, with the layers corresponding
  5. //! to the levels of API abstraction. Only the highest layers would be used by a typical
  6. //! application; however, the goal of _smoltcp_ is not just to provide a simple interface
  7. //! for writing applications but also to be a toolbox of networking primitives, so
  8. //! every layer is fully exposed and documented.
  9. //!
  10. //! When discussing networking stacks and layering, often the [OSI model][osi] is invoked.
  11. //! _smoltcp_ makes no effort to conform to the OSI model as it is not applicable to TCP/IP.
  12. //!
  13. //! # The socket layer
  14. //! The socket layer APIs are provided in the module [socket](socket/index.html); currently,
  15. //! raw, ICMP, TCP, and UDP sockets are provided. The socket API provides the usual primitives,
  16. //! but necessarily differs in many from the [Berkeley socket API][berk], as the latter was
  17. //! not designed to be used without heap allocation.
  18. //!
  19. //! The socket layer provides the buffering, packet construction and validation, and (for
  20. //! stateful sockets) the state machines, but it is interface-agnostic. An application must
  21. //! use sockets together with a network interface.
  22. //!
  23. //! # The interface layer
  24. //! The interface layer APIs are provided in the module [iface](iface/index.html); currently,
  25. //! Ethernet interface is provided.
  26. //!
  27. //! The interface layer handles the control messages, physical addressing and neighbor discovery.
  28. //! It routes packets to and from sockets.
  29. //!
  30. //! # The physical layer
  31. //! The physical layer APIs are provided in the module [phy](phy/index.html); currently,
  32. //! raw socket and TAP interface are provided. In addition, two _middleware_ interfaces
  33. //! are provided: the _tracer device_, which prints a human-readable representation of packets,
  34. //! and the _fault injector device_, which randomly introduces errors into the transmitted
  35. //! and received packet sequences.
  36. //!
  37. //! The physical layer handles interaction with a platform-specific network device.
  38. //!
  39. //! # The wire layers
  40. //! Unlike the higher layers, the wire layer APIs will not be used by a typical application.
  41. //! They however are the bedrock of _smoltcp_, and everything else is built on top of them.
  42. //!
  43. //! The wire layer APIs are designed by the principle "make illegal states irrepresentable".
  44. //! If a wire layer object can be constructed, then it can also be parsed from or emitted to
  45. //! a lower level.
  46. //!
  47. //! The wire layer APIs also provide _tcpdump_-like pretty printing.
  48. //!
  49. //! ## The representation layer
  50. //! The representation layer APIs are provided in the module [wire].
  51. //!
  52. //! The representation layer exists to reduce the state space of raw packets. Raw packets
  53. //! may be nonsensical in a multitude of ways: invalid checksums, impossible combinations of flags,
  54. //! pointers to fields out of bounds, meaningless options... Representations shed all that,
  55. //! as well as any features not supported by _smoltcp_.
  56. //!
  57. //! ## The packet layer
  58. //! The packet layer APIs are also provided in the module [wire].
  59. //!
  60. //! The packet layer exists to provide a more structured way to work with packets than
  61. //! treating them as sequences of octets. It makes no judgement as to content of the packets,
  62. //! except where necessary to provide safe access to fields, and strives to implement every
  63. //! feature ever defined, to ensure that, when the representation layer is unable to make sense
  64. //! of a packet, it is still logged correctly and in full.
  65. //!
  66. //! ## Packet and representation layer support
  67. //! | Protocol | Packet | Representation |
  68. //! |----------|--------|----------------|
  69. //! | Ethernet | Yes | Yes |
  70. //! | ARP | Yes | Yes |
  71. //! | IPv4 | Yes | Yes |
  72. //! | ICMPv4 | Yes | Yes |
  73. //! | IGMPv1/2 | Yes | Yes |
  74. //! | IPv6 | Yes | Yes |
  75. //! | ICMPv6 | Yes | Yes |
  76. //! | TCP | Yes | Yes |
  77. //! | UDP | Yes | Yes |
  78. //!
  79. //! [wire]: wire/index.html
  80. //! [osi]: https://en.wikipedia.org/wiki/OSI_model
  81. //! [berk]: https://en.wikipedia.org/wiki/Berkeley_sockets
  82. /* XXX compiler bug
  83. #![cfg(not(any(feature = "socket-raw",
  84. feature = "socket-udp",
  85. feature = "socket-tcp")))]
  86. compile_error!("at least one socket needs to be enabled"); */
  87. // FIXME(dlrobertson): clippy fails with this lint
  88. #![cfg_attr(feature = "cargo-clippy", allow(if_same_then_else))]
  89. #[cfg(feature = "alloc")]
  90. extern crate alloc;
  91. use core::fmt;
  92. #[macro_use]
  93. mod macros;
  94. mod parsers;
  95. pub mod storage;
  96. pub mod phy;
  97. pub mod wire;
  98. pub mod iface;
  99. pub mod socket;
  100. pub mod time;
  101. #[cfg(feature = "proto-dhcpv4")]
  102. pub mod dhcp;
  103. /// The error type for the networking stack.
  104. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  105. pub enum Error {
  106. /// An operation cannot proceed because a buffer is empty or full.
  107. Exhausted,
  108. /// An operation is not permitted in the current state.
  109. Illegal,
  110. /// An endpoint or address of a remote host could not be translated to a lower level address.
  111. /// E.g. there was no an Ethernet address corresponding to an IPv4 address in the ARP cache,
  112. /// or a TCP connection attempt was made to an unspecified endpoint.
  113. Unaddressable,
  114. /// The operation is finished.
  115. /// E.g. when reading from a TCP socket, there's no more data to read because the remote
  116. /// has closed the connection.
  117. Finished,
  118. /// An incoming packet could not be parsed because some of its fields were out of bounds
  119. /// of the received data.
  120. Truncated,
  121. /// An incoming packet had an incorrect checksum and was dropped.
  122. Checksum,
  123. /// An incoming packet could not be recognized and was dropped.
  124. /// E.g. an Ethernet packet with an unknown EtherType.
  125. Unrecognized,
  126. /// An incoming IP packet has been split into several IP fragments and was dropped,
  127. /// since IP reassembly is not supported.
  128. Fragmented,
  129. /// An incoming packet was recognized but was self-contradictory.
  130. /// E.g. a TCP packet with both SYN and FIN flags set.
  131. Malformed,
  132. /// An incoming packet was recognized but contradicted internal state.
  133. /// E.g. a TCP packet addressed to a socket that doesn't exist.
  134. Dropped,
  135. #[doc(hidden)]
  136. __Nonexhaustive
  137. }
  138. /// The result type for the networking stack.
  139. pub type Result<T> = core::result::Result<T, Error>;
  140. impl fmt::Display for Error {
  141. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  142. match *self {
  143. Error::Exhausted => write!(f, "buffer space exhausted"),
  144. Error::Illegal => write!(f, "illegal operation"),
  145. Error::Unaddressable => write!(f, "unaddressable destination"),
  146. Error::Finished => write!(f, "operation finished"),
  147. Error::Truncated => write!(f, "truncated packet"),
  148. Error::Checksum => write!(f, "checksum error"),
  149. Error::Unrecognized => write!(f, "unrecognized packet"),
  150. Error::Fragmented => write!(f, "fragmented packet"),
  151. Error::Malformed => write!(f, "malformed packet"),
  152. Error::Dropped => write!(f, "dropped by socket"),
  153. Error::__Nonexhaustive => unreachable!()
  154. }
  155. }
  156. }