1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
//! JNeT: japaric's network thingies //! //! There's no IO stuff in this crate. If you are looking for sockets and the like check out the //! [`smoltcp`] crate. //! //! [`smoltcp`]: https://crates.io/crates/smoltcp //! //! This crate mainly contains an API to work with frames and packets in `no_std` context. //! //! It doesn't provide you any real *parser* though; it simply provides an API to mutate or access //! the header and the payload of a frame / packet *in place*. This approach is the same as the one //! used in `smoltcp`. The difference is that the API of this crate uses type state to (a) avoid //! foot guns like sending an IPv4 packet with an invalid header checksum, and to (b) provide //! specialized APIs when the packet type, e.g. ICMP EchoRequest, is known. //! //! If type state is not your cup of tea check out `smoltcp`'s [wire module]; do note that, as of //! v0.4.0, `smoltcp` doesn't provide an API to work with CoAP messages whereas this crate does. //! //! [wire module]: https://docs.rs/smoltcp/0.4.0/smoltcp/wire/index.html //! //! # Examples //! //! - Parsing an ARP packet //! //! ``` //! use jnet::{arp, ether}; //! //! let bytes = &[ //! 255, 255, 255, 255, 255, 255, // eth: destination //! 120, 68, 118, 217, 106, 124, // eth: source //! 8, 6, // eth: type //! 0, 1, // arp: HTYPE = Ethernet //! 8, 0, // arp: PTYPE = IPv4 //! 6, // arp: HLEN //! 4, // arp: PLEN //! 0, 2, // arp: OPER = Reply //! 120, 68, 118, 217, 106, 124, // arp: SHA //! 192, 168, 1, 1, // arp: SPA //! 32, 24, 3, 1, 0, 0, // arp: THA //! 192, 168, 1, 33, // arp: TPA //! 0, 0, 0, 0, // eth: padding //! ]; //! //! let eth = ether::Frame::parse(&bytes[..]).unwrap(); //! let arp = arp::Packet::parse(eth.payload()).unwrap(); //! //! assert_eq!(arp.get_htype(), arp::HardwareType::Ethernet); //! assert_eq!(arp.get_ptype(), ether::Type::Ipv4); //! assert_eq!(arp.get_oper(), arp::Operation::Reply); //! ``` //! //! - Constructing a CoAP message //! //! The general principle to building frames / packets / messages is to start with an (slightly) //! oversized buffer and then proceed to shrink it to the right length. //! //! ``` //! use jnet::{coap, ether, ipv4, mac, udp}; //! //! const MAC_SRC: mac::Addr = mac::Addr([0x20, 0x18, 0x03, 0x01, 0x00, 0x00]); //! const MAC_DST: mac::Addr = mac::Addr([0x20, 0x18, 0x03, 0x13, 0x00, 0x00]); //! //! const IP_SRC: ipv4::Addr = ipv4::Addr([192, 168, 1, 11]); //! const IP_DST: ipv4::Addr = ipv4::Addr([192, 168, 1, 33]); //! //! let mut bytes = [0; 60]; //! let mut buf = &mut bytes[..]; //! //! // clean slate Ethernet frame with a total length of 60 bytes //! let mut eth = ether::Frame::new(buf); //! eth.set_destination(MAC_DST); //! eth.set_source(MAC_SRC); //! //! eth.ipv4(|ip| { //! ip.set_source(IP_SRC); //! ip.set_destination(IP_DST); //! ip.udp(|udp| { //! udp.set_destination(coap::PORT); //! udp.coap(0, |mut coap| { //! coap.set_type(coap::Type::Confirmable); //! coap.set_code(coap::Method::Put); //! coap.add_option(coap::OptionNumber::UriPath, b"led"); //! coap.set_payload(b"on") //! }) //! }); //! }); //! //! // At this point the Ethernet frame has shrunk to the size of its contents //! // The excess memory is inaccessible //! assert_eq!(eth.len(), 53); //! ``` #![deny(missing_docs)] #![deny(rust_2018_compatibility)] #![deny(rust_2018_idioms)] #![deny(warnings)] #![no_std] #[cfg(test)] #[macro_use] extern crate pretty_assertions; #[macro_use] mod macros; mod fmt; mod sealed; mod traits; // Medium Access Control layer pub mod ether; pub mod ieee802154; pub mod mac; pub mod arp; // Network layer pub mod ipv4; pub mod ipv6; pub mod sixlowpan; pub mod icmp; pub mod icmpv6; // Transport layer pub mod udp; // Application layer pub mod coap; /// [Type State] Unknown pub enum Unknown {} /// [Type State] Valid checksum pub enum Valid {} /// [Type State] Invalid checksum pub enum Invalid {}