ferranet 0.2.0

A modern, async-first, zero-copy datalink-layer (L2) networking library
Documentation
//! Property-based tests (privilege-free) for ferranet's pure parsing/validation surfaces.
//!
//! These complement the fuzz target in `fuzz/`: proptest checks *correctness* invariants over
//! structured random inputs and runs in ordinary `cargo test`, while the fuzzer hammers the same
//! block parser with coverage-guided garbage for *robustness*.

use ferranet::MacAddr;
use proptest::prelude::*;

proptest! {
    /// A MAC formatted and re-parsed round-trips exactly.
    #[test]
    fn mac_addr_roundtrips(octets in any::<[u8; 6]>()) {
        let mac = MacAddr(octets);
        let parsed: MacAddr = mac.to_string().parse().expect("formatted MAC must parse");
        prop_assert_eq!(parsed.octets(), octets);
    }

    /// Parsing arbitrary strings as a MAC never panics (returns Err on malformed input).
    #[test]
    fn mac_addr_parse_never_panics(s in ".{0,40}") {
        let _ = s.parse::<MacAddr>();
    }
}

// The TPACKET_V3 block parser is the crate's main untrusted-input surface; exercise it through the
// (hidden) bench_support entry point.
#[cfg(target_os = "linux")]
mod block_parser {
    use ferranet::bench_support::{parse_v3_block, synth_v3_block};
    use proptest::prelude::*;

    proptest! {
        /// Parsing an arbitrary byte buffer with arbitrary offset/count never panics or reads out
        /// of bounds (it returns; UB/OOB would abort the test process).
        #[test]
        fn parse_arbitrary_block_is_safe(
            data in proptest::collection::vec(any::<u8>(), 0..8192),
            first_off in 0usize..16384,
            num_pkts in 0u32..4096,
        ) {
            let (frames, bytes) = parse_v3_block(&data, first_off, num_pkts);
            // Whatever it returns, it cannot have produced more frames than were requested, nor
            // more captured bytes than the buffer holds.
            prop_assert!(frames <= num_pkts as usize);
            prop_assert!(bytes <= data.len());
        }

        /// A well-formed synthetic block parses back to exactly the frames it was built with.
        #[test]
        fn synthetic_block_round_trips(num_frames in 1u32..64, payload in 6usize..1500) {
            let (buf, first, pkts) = synth_v3_block(num_frames, payload);
            let (frames, bytes) = parse_v3_block(&buf, first, pkts);
            prop_assert_eq!(frames, num_frames as usize);
            prop_assert_eq!(bytes, num_frames as usize * payload);
        }
    }
}