2020-12-27 07:11:30 +08:00
#![ cfg_attr(not(any(test, feature = " std " )), no_std) ]
2017-12-24 21:28:59 +08:00
#![ deny(unsafe_code) ]
2021-06-27 15:31:59 +08:00
#![ cfg_attr(
all (
any ( feature = " proto-ipv4 " , feature = " proto-ipv6 " ) ,
feature = " medium-ethernet "
) ,
deny ( unused )
) ]
2016-12-10 17:23:40 +08:00
2016-12-31 18:26:59 +08:00
//! The _smoltcp_ library is built in a layered structure, with the layers corresponding
//! to the levels of API abstraction. Only the highest layers would be used by a typical
//! application; however, the goal of _smoltcp_ is not just to provide a simple interface
//! for writing applications but also to be a toolbox of networking primitives, so
//! every layer is fully exposed and documented.
//!
//! When discussing networking stacks and layering, often the [OSI model][osi] is invoked.
//! _smoltcp_ makes no effort to conform to the OSI model as it is not applicable to TCP/IP.
//!
//! # The socket layer
//! The socket layer APIs are provided in the module [socket](socket/index.html); currently,
2017-11-09 09:59:27 +08:00
//! raw, ICMP, TCP, and UDP sockets are provided. The socket API provides the usual primitives,
2017-10-30 08:19:34 +08:00
//! but necessarily differs in many from the [Berkeley socket API][berk], as the latter was
//! not designed to be used without heap allocation.
2016-12-31 18:26:59 +08:00
//!
//! The socket layer provides the buffering, packet construction and validation, and (for
//! stateful sockets) the state machines, but it is interface-agnostic. An application must
//! use sockets together with a network interface.
//!
//! # The interface layer
//! The interface layer APIs are provided in the module [iface](iface/index.html); currently,
//! Ethernet interface is provided.
//!
//! The interface layer handles the control messages, physical addressing and neighbor discovery.
2017-01-11 13:25:54 +08:00
//! It routes packets to and from sockets.
2016-12-31 18:26:59 +08:00
//!
//! # The physical layer
//! The physical layer APIs are provided in the module [phy](phy/index.html); currently,
2016-12-31 20:28:59 +08:00
//! raw socket and TAP interface are provided. In addition, two _middleware_ interfaces
2016-12-31 18:26:59 +08:00
//! are provided: the _tracer device_, which prints a human-readable representation of packets,
//! and the _fault injector device_, which randomly introduces errors into the transmitted
//! and received packet sequences.
//!
//! The physical layer handles interaction with a platform-specific network device.
//!
//! # The wire layers
//! Unlike the higher layers, the wire layer APIs will not be used by a typical application.
//! They however are the bedrock of _smoltcp_, and everything else is built on top of them.
//!
//! The wire layer APIs are designed by the principle "make illegal states irrepresentable".
//! If a wire layer object can be constructed, then it can also be parsed from or emitted to
//! a lower level.
//!
//! The wire layer APIs also provide _tcpdump_-like pretty printing.
//!
//! ## The representation layer
2018-02-12 09:53:54 +08:00
//! The representation layer APIs are provided in the module [wire].
2016-12-31 18:26:59 +08:00
//!
//! The representation layer exists to reduce the state space of raw packets. Raw packets
//! may be nonsensical in a multitude of ways: invalid checksums, impossible combinations of flags,
//! pointers to fields out of bounds, meaningless options... Representations shed all that,
//! as well as any features not supported by _smoltcp_.
//!
//! ## The packet layer
2018-02-12 09:53:54 +08:00
//! The packet layer APIs are also provided in the module [wire].
2016-12-31 18:26:59 +08:00
//!
//! The packet layer exists to provide a more structured way to work with packets than
//! treating them as sequences of octets. It makes no judgement as to content of the packets,
//! except where necessary to provide safe access to fields, and strives to implement every
//! feature ever defined, to ensure that, when the representation layer is unable to make sense
//! of a packet, it is still logged correctly and in full.
2018-01-06 03:38:23 +08:00
//!
2021-04-01 08:15:35 +08:00
//! # Minimum Supported Rust Version (MSRV)
//!
2021-08-18 21:17:13 +08:00
//! This crate is guaranteed to compile on stable Rust 1.46 and up with any valid set of features.
2021-04-01 08:15:35 +08:00
//! It *might* compile on older versions but that may change in any new patch release.
//!
//! The exception is when using the `defmt` feature, in which case `defmt`'s MSRV applies, which
2021-08-18 21:17:13 +08:00
//! is higher than 1.46.
2021-04-01 08:15:35 +08:00
//!
2018-02-12 09:53:54 +08:00
//! [wire]: wire/index.html
2018-01-06 03:38:23 +08:00
//! [osi]: https://en.wikipedia.org/wiki/OSI_model
//! [berk]: https://en.wikipedia.org/wiki/Berkeley_sockets
2016-12-11 07:15:26 +08:00
2017-09-25 08:46:53 +08:00
/* XXX compiler bug
2017-11-06 17:51:03 +08:00
#![ cfg(not(any(feature = " socket-raw " ,
feature = " socket-udp " ,
feature = " socket-tcp " ) ) ) ]
2017-09-25 08:46:53 +08:00
compile_error! ( " at least one socket needs to be enabled " ) ; * /
2020-12-28 06:28:31 +08:00
#![ allow(clippy::match_like_matches_macro) ]
2020-12-28 03:19:56 +08:00
#![ allow(clippy::redundant_field_names) ]
2020-12-29 13:09:07 +08:00
#![ allow(clippy::identity_op) ]
2020-12-29 13:09:33 +08:00
#![ allow(clippy::option_map_unit_fn) ]
2020-12-26 15:56:39 +08:00
#![ allow(clippy::unit_arg) ]
2018-06-18 10:39:19 +08:00
2021-06-15 06:16:15 +08:00
#[ cfg(any(feature = " std " , feature = " alloc " )) ]
2016-12-28 07:49:37 +08:00
extern crate alloc ;
2016-12-23 15:59:38 +08:00
2021-04-29 18:04:46 +08:00
#[ cfg(not(any(
feature = " proto-ipv4 " ,
feature = " proto-ipv6 " ,
feature = " proto-sixlowpan "
) ) ) ]
compile_error! ( " You must enable at least one of the following features: proto-ipv4, proto-ipv6, proto-sixlowpan " ) ;
2021-03-24 07:49:08 +08:00
#[ cfg(all(
feature = " socket " ,
not ( any (
feature = " socket-raw " ,
feature = " socket-udp " ,
feature = " socket-tcp " ,
feature = " socket-icmp " ,
) )
) ) ]
compile_error! ( " If you enable the socket feature, you must enable at least one of the following features: socket-raw, socket-udp, socket-tcp, socket-icmp " ) ;
2021-06-17 09:22:02 +08:00
#[ cfg(all(
feature = " socket " ,
2021-04-29 18:04:46 +08:00
not ( any (
feature = " medium-ethernet " ,
feature = " medium-ip " ,
feature = " medium-ieee802154 " ,
) )
2021-06-17 09:22:02 +08:00
) ) ]
2021-04-29 18:04:46 +08:00
compile_error! ( " If you enable the socket feature, you must enable at least one of the following features: medium-ip, medium-ethernet, medium-ieee802154 " ) ;
2021-06-17 09:22:02 +08:00
2021-04-01 07:30:47 +08:00
#[ cfg(all(feature = " defmt " , feature = " log " )) ]
compile_error! ( " You must enable at most one of the following features: defmt, log " ) ;
2016-12-12 15:19:53 +08:00
use core ::fmt ;
2017-07-23 15:54:36 +08:00
#[ macro_use ]
mod macros ;
2017-09-21 04:18:50 +08:00
mod parsers ;
2017-07-23 15:54:36 +08:00
2021-10-12 02:19:23 +08:00
mod rand ;
#[ cfg(feature = " rand-custom-impl " ) ]
pub use crate ::rand ::Rand ;
2016-12-12 10:39:46 +08:00
pub mod iface ;
2021-06-27 15:31:59 +08:00
pub mod phy ;
2021-02-01 23:45:32 +08:00
#[ cfg(feature = " socket " ) ]
2016-12-15 01:39:44 +08:00
pub mod socket ;
2021-06-27 15:31:59 +08:00
pub mod storage ;
2018-01-13 22:51:21 +08:00
pub mod time ;
2021-06-27 15:31:59 +08:00
pub mod wire ;
2016-12-12 15:19:53 +08:00
/// The error type for the networking stack.
2017-07-27 19:58:31 +08:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2021-01-09 07:55:28 +08:00
#[ non_exhaustive ]
2021-04-01 07:30:47 +08:00
#[ cfg_attr(feature = " defmt " , derive(defmt::Format)) ]
2016-12-12 15:19:53 +08:00
pub enum Error {
2017-07-27 19:58:31 +08:00
/// An operation cannot proceed because a buffer is empty or full.
Exhausted ,
2017-07-27 20:27:33 +08:00
/// An operation is not permitted in the current state.
Illegal ,
2017-07-27 19:58:31 +08:00
/// An endpoint or address of a remote host could not be translated to a lower level address.
/// E.g. there was no an Ethernet address corresponding to an IPv4 address in the ARP cache,
/// or a TCP connection attempt was made to an unspecified endpoint.
Unaddressable ,
2020-06-12 03:17:41 +08:00
/// The operation is finished.
/// E.g. when reading from a TCP socket, there's no more data to read because the remote
/// has closed the connection.
Finished ,
2017-07-27 19:58:31 +08:00
/// An incoming packet could not be parsed because some of its fields were out of bounds
/// of the received data.
2016-12-12 15:19:53 +08:00
Truncated ,
2016-12-13 01:26:06 +08:00
/// An incoming packet had an incorrect checksum and was dropped.
Checksum ,
2017-07-27 19:58:31 +08:00
/// An incoming packet could not be recognized and was dropped.
/// E.g. an Ethernet packet with an unknown EtherType.
Unrecognized ,
/// An incoming IP packet has been split into several IP fragments and was dropped,
/// since IP reassembly is not supported.
2016-12-13 04:01:38 +08:00
Fragmented ,
2017-07-27 19:58:31 +08:00
/// An incoming packet was recognized but was self-contradictory.
/// E.g. a TCP packet with both SYN and FIN flags set.
Malformed ,
/// An incoming packet was recognized but contradicted internal state.
/// E.g. a TCP packet addressed to a socket that doesn't exist.
2017-01-17 00:58:45 +08:00
Dropped ,
2021-04-29 18:04:46 +08:00
/// An incoming packet was recognized but some parts are not supported by smoltcp.
/// E.g. some bit configuration in a packet header is not supported, but is defined in an RFC.
NotSupported ,
2016-12-12 15:19:53 +08:00
}
2021-06-08 14:34:38 +08:00
#[ cfg(feature = " std " ) ]
impl std ::error ::Error for Error { }
2017-07-27 21:51:02 +08:00
/// The result type for the networking stack.
pub type Result < T > = core ::result ::Result < T , Error > ;
2016-12-12 15:19:53 +08:00
impl fmt ::Display for Error {
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
2020-12-26 16:28:05 +08:00
match * self {
2021-06-27 15:31:59 +08:00
Error ::Exhausted = > write! ( f , " buffer space exhausted " ) ,
Error ::Illegal = > write! ( f , " illegal operation " ) ,
2020-12-26 16:28:05 +08:00
Error ::Unaddressable = > write! ( f , " unaddressable destination " ) ,
2021-06-27 15:31:59 +08:00
Error ::Finished = > write! ( f , " operation finished " ) ,
Error ::Truncated = > write! ( f , " truncated packet " ) ,
Error ::Checksum = > write! ( f , " checksum error " ) ,
Error ::Unrecognized = > write! ( f , " unrecognized packet " ) ,
Error ::Fragmented = > write! ( f , " fragmented packet " ) ,
Error ::Malformed = > write! ( f , " malformed packet " ) ,
Error ::Dropped = > write! ( f , " dropped by socket " ) ,
2021-04-29 18:04:46 +08:00
Error ::NotSupported = > write! ( f , " not supported by smoltcp " ) ,
2016-12-12 15:19:53 +08:00
}
}
}