1 #![cfg_attr(not(any(test, feature = "std")), no_std)]
2 #![deny(unsafe_code)]
3 
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 ir-representable".
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 //! # Minimum Supported Rust Version (MSRV)
67 //!
68 //! This crate is guaranteed to compile on stable Rust 1.65 and up with any valid set of features.
69 //! It *might* compile on older versions but that may change in any new patch release.
70 //!
71 //! The exception is when using the `defmt` feature, in which case `defmt`'s MSRV applies, which
72 //! is higher.
73 //!
74 //! [wire]: wire/index.html
75 //! [osi]: https://en.wikipedia.org/wiki/OSI_model
76 //! [berk]: https://en.wikipedia.org/wiki/Berkeley_sockets
77 
78 /* XXX compiler bug
79 #![cfg(not(any(feature = "socket-raw",
80                feature = "socket-udp",
81                feature = "socket-tcp")))]
82 compile_error!("at least one socket needs to be enabled"); */
83 
84 #![allow(clippy::match_like_matches_macro)]
85 #![allow(clippy::redundant_field_names)]
86 #![allow(clippy::identity_op)]
87 #![allow(clippy::option_map_unit_fn)]
88 #![allow(clippy::unit_arg)]
89 #![allow(clippy::new_without_default)]
90 
91 #[cfg(feature = "alloc")]
92 extern crate alloc;
93 
94 #[cfg(not(any(
95     feature = "proto-ipv4",
96     feature = "proto-ipv6",
97     feature = "proto-sixlowpan"
98 )))]
99 compile_error!("You must enable at least one of the following features: proto-ipv4, proto-ipv6, proto-sixlowpan");
100 
101 #[cfg(all(
102     feature = "socket",
103     not(any(
104         feature = "socket-raw",
105         feature = "socket-udp",
106         feature = "socket-tcp",
107         feature = "socket-icmp",
108         feature = "socket-dhcpv4",
109         feature = "socket-dns",
110     ))
111 ))]
112 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, socket-dhcpv4, socket-dns");
113 
114 #[cfg(all(
115     feature = "socket",
116     not(any(
117         feature = "medium-ethernet",
118         feature = "medium-ip",
119         feature = "medium-ieee802154",
120     ))
121 ))]
122 compile_error!("If you enable the socket feature, you must enable at least one of the following features: medium-ip, medium-ethernet, medium-ieee802154");
123 
124 #[cfg(all(feature = "defmt", feature = "log"))]
125 compile_error!("You must enable at most one of the following features: defmt, log");
126 
127 #[macro_use]
128 mod macros;
129 mod parsers;
130 mod rand;
131 
132 #[cfg(test)]
133 mod config {
134     #![allow(unused)]
135     pub const ASSEMBLER_MAX_SEGMENT_COUNT: usize = 4;
136     pub const DNS_MAX_NAME_SIZE: usize = 255;
137     pub const DNS_MAX_RESULT_COUNT: usize = 1;
138     pub const DNS_MAX_SERVER_COUNT: usize = 1;
139     pub const FRAGMENTATION_BUFFER_SIZE: usize = 1500;
140     pub const IFACE_MAX_ADDR_COUNT: usize = 8;
141     pub const IFACE_MAX_MULTICAST_GROUP_COUNT: usize = 4;
142     pub const IFACE_MAX_ROUTE_COUNT: usize = 4;
143     pub const IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT: usize = 4;
144     pub const IFACE_NEIGHBOR_CACHE_COUNT: usize = 3;
145     pub const REASSEMBLY_BUFFER_COUNT: usize = 4;
146     pub const REASSEMBLY_BUFFER_SIZE: usize = 1500;
147 }
148 
149 #[cfg(not(test))]
150 mod config {
151     #![allow(unused)]
152     include!(concat!(env!("OUT_DIR"), "/config.rs"));
153 }
154 
155 #[cfg(any(
156     feature = "medium-ethernet",
157     feature = "medium-ip",
158     feature = "medium-ieee802154"
159 ))]
160 pub mod iface;
161 
162 pub mod phy;
163 #[cfg(feature = "socket")]
164 pub mod socket;
165 pub mod storage;
166 pub mod time;
167 pub mod wire;
168