renet/src/lib.rs

147 lines
6.4 KiB
Rust
Raw Normal View History

#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))]
2016-12-10 17:23:40 +08:00
#![no_std]
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.
//! [osi]: https://en.wikipedia.org/wiki/OSI_model
//!
//! # The socket layer
//! The socket layer APIs are provided in the module [socket](socket/index.html); currently,
//! TCP and UDP sockets are provided. The socket API provides the usual primitives, but
//! necessarily differs in many from the [Berkeley socket API][berk], as the latter was not
//! designed to be used without heap allocation.
//! [berk]: https://en.wikipedia.org/wiki/Berkeley_sockets
//!
//! 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
//! The representation layer APIs are provided in the module [wire](wire/index.html); currently,
//! Ethernet, ARP, generic IP, IPv4, ICMPv4, TCP and UDP packet representations are provided.
//!
//! 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
//! The packet layer APIs are also provided in the module [wire](wire/index.html); currently,
//! Ethernet, ARP, IPv4, ICMPv4, TCP and UDP packet representations are provided.
//!
//! 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.
2016-12-11 07:15:26 +08:00
2016-12-31 18:26:59 +08:00
extern crate byteorder;
2017-01-10 19:04:00 +08:00
extern crate managed;
#[cfg(any(test, feature = "std"))]
2016-12-10 17:23:40 +08:00
#[macro_use]
extern crate std;
#[cfg(any(feature = "raw_socket", feature="tap_interface"))]
2016-12-11 07:15:26 +08:00
extern crate libc;
#[cfg(feature = "alloc")]
2016-12-28 07:49:37 +08:00
extern crate alloc;
#[allow(deprecated)]
#[cfg(feature = "collections")]
extern crate collections;
#[cfg(any(test, feature = "log"))]
#[macro_use(trace, log, log_enabled)]
2016-12-23 15:59:38 +08:00
extern crate log;
2016-12-12 15:19:53 +08:00
use core::fmt;
#[macro_use]
mod macros;
mod parsing;
2017-06-18 18:11:21 +08:00
pub mod storage;
2016-12-11 02:33:19 +08:00
pub mod phy;
pub mod wire;
2016-12-12 10:39:46 +08:00
pub mod iface;
2016-12-15 01:39:44 +08:00
pub mod socket;
2016-12-12 15:19:53 +08:00
/// The error type for the networking stack.
2016-12-16 01:07:56 +08:00
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
2016-12-12 15:19:53 +08:00
pub enum Error {
/// An incoming packet could not be parsed.
2016-12-12 15:19:53 +08:00
Truncated,
2016-12-13 01:26:06 +08:00
/// An incoming packet could not be recognized and was dropped.
/// E.g. a packet with an unknown EtherType.
2016-12-12 15:19:53 +08:00
Unrecognized,
/// An incoming packet was recognized but contained invalid control information.
/// E.g. a packet with IPv4 EtherType but containing a value other than 4
/// in the version field.
Malformed,
2016-12-13 01:26:06 +08:00
/// An incoming packet had an incorrect checksum and was dropped.
Checksum,
/// An incoming packet has been fragmented and was dropped.
Fragmented,
2016-12-13 07:22:59 +08:00
/// An outgoing packet could not be sent because a protocol address could not be mapped
/// to hardware address. E.g. an IPv4 packet did not have an Ethernet address
/// corresponding to its IPv4 destination address.
Unaddressable,
2016-12-15 01:39:44 +08:00
/// A buffer for incoming packets is empty, or a buffer for outgoing packets is full.
Exhausted,
/// An incoming packet does not match the socket endpoint.
Rejected,
/// An incoming packet was recognized by a stateful socket and contained invalid control
/// information that caused the socket to drop it.
Dropped,
2016-12-12 15:19:53 +08:00
#[doc(hidden)]
__Nonexhaustive
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
2016-12-13 07:22:59 +08:00
&Error::Truncated => write!(f, "truncated packet"),
&Error::Unrecognized => write!(f, "unrecognized packet"),
&Error::Malformed => write!(f, "malformed packet"),
&Error::Checksum => write!(f, "checksum error"),
&Error::Fragmented => write!(f, "fragmented packet"),
&Error::Unaddressable => write!(f, "unaddressable destination"),
2016-12-15 01:39:44 +08:00
&Error::Exhausted => write!(f, "buffer space exhausted"),
&Error::Rejected => write!(f, "rejected by socket"),
&Error::Dropped => write!(f, "dropped by socket"),
2016-12-12 15:19:53 +08:00
&Error::__Nonexhaustive => unreachable!()
}
}
}