Crate catnip

Source
Expand description

A no-std, panic-never, heapless, minimally-featured UDP/IP stack for bare-metal. Intended for fixed-time data acquisition and controls on LAN.

This crate currently relies on the nightly channel, and as a result, may break regularly until the required features stabilize.

Makes use of const generic expressions to provide flexibility in, and guaranteed correctness of, lengths of headers and data segments without an allocator.

This library is under active development; major functionality is yet to be implemented and I’m sure some bugs are yet to be found.

use catnip::*;

// Some made-up data with two 32-bit words' worth of bytes and some arbitrary addresses
let data: ByteArray<8> = ByteArray([0, 1, 2, 3, 4, 5, 6, 7]);

// Build frame
let mut frame = EthernetFrame::<IpV4Frame<UdpFrame<ByteArray<8>>>> {
    header: EthernetHeader {
        dst_macaddr: MacAddr::BROADCAST,
        src_macaddr: MacAddr::new([0x02, 0xAF, 0xFF, 0x1A, 0xE5, 0x3C]),
        ethertype: EtherType::IpV4,
    },
    data: IpV4Frame::<UdpFrame<ByteArray<8>>> {
        header: IpV4Header {
            version_and_header_length: VersionAndHeaderLength::new().with_version(4).with_header_length((IpV4Header::BYTE_LEN / 4) as u8),
            dscp: DSCP::Standard,
            total_length: IpV4Frame::<UdpFrame<ByteArray<8>>>::BYTE_LEN as u16,
            identification: 0,
            fragmentation: Fragmentation::default(),
            time_to_live: 10,
            protocol: Protocol::Udp,
            checksum: 0,
            src_ipaddr: IpV4Addr::new([10, 0, 0, 120]),
            dst_ipaddr: IpV4Addr::new([10, 0, 0, 121]),
        },
        data: UdpFrame::<ByteArray<8>> {
            header: UdpHeader {
                src_port: 8123,
                dst_port: 8125,
                length: UdpFrame::<ByteArray<8>>::BYTE_LEN as u16,
                checksum: 0,
            },
            data: data,
        },
    },
    checksum: 0_u32,
};

// Calculate IP and UDP checksums
frame.data.data.header.checksum = calc_udp_checksum(&frame.data);
frame.data.header.checksum = calc_ip_checksum(&frame.data.header.to_be_bytes());

// Reduce to bytes
let bytes = frame.to_be_bytes();

// Parse from bytes
let frame_parsed = EthernetFrame::<IpV4Frame<UdpFrame<ByteArray<8>>>>::read_bytes(&bytes);
assert_eq!(frame_parsed, frame);

Re-exports§

pub use modular_bitfield;
pub use arp::*;
pub use dhcp::*;
pub use enet::*;
pub use ip::*;
pub use udp::*;

Modules§

arp
Address Resolution Protocol implementation for IPV4.
dhcp
Dynamic Host Configuration Protocol for IPV4.
enet
Link layer: Ethernet II protocol. See https://en.wikipedia.org/wiki/Ethernet_frame#Ethernet_II.
ip
Internet layer: Internet Protocol message header construction
udp
Transport layer: User Datagram Protocol

Macros§

enum_with_unknown
Derive To/From with an added “Unknown” variant catch-all for converting from numerical values that do not match a valid variant in order to avoid either panicking or cumbersome error handling.

Structs§

ByteArray
Newtype for [u8; N] in order to be able to implement traits.

Enums§

DSCP
Type-of-Service for networks with differentiated services. See https://en.wikipedia.org/wiki/Differentiated_services.
Protocol
Common choices of transport-layer protocols and their IP header values. There are many more protocols not listed here. See https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers.

Traits§

ByteStruct
A data structure that can be packed into or unpacked from raw bytes.
ByteStructLen
A type that can be packed into or unpacked from fixed-size bytes, but the method is unknown yet.
uDebug
Just like core::fmt::Debug
uDisplay
Just like core::fmt::Display
uWrite
A collection of methods that are required / used to format a message into a stream.

Functions§

calc_ip_checksum
Calculate IP checksum per IETF-RFC-768 following implementation guide in IETF-RFC-1071 section 4.1 . See https://datatracker.ietf.org/doc/html/rfc1071#section-4 . This function is provided for convenience and is not used directly.
calc_ip_checksum_finalize
Finalize an IP checksum by folding the accumulator from an i32 to a u16 and taking the one’s complement
calc_ip_checksum_incomplete
Calculate an IP checksum on incomplete data returning the unfolded accumulator as i32

Type Aliases§

IpV4Addr
IPV4 address as bytes
MacAddr
Standard 6-byte MAC address. Split 24/24 format, Block ID | Device ID . Locally-administered addresses are [0x02, …], [0x06, …], [0x0A, …], [0x0E, …]

Derive Macros§

ByteStruct
Derives trait ByteStruct for a data structure.
uDebug
Automatically derive the uDebug trait for a struct or enum