internet 0.1.0

Network library for rust
Documentation
//! IP invariants encoding.

use crate::{Buf, BufError, BufMut, BufResult, Codec, Cursor};

/// An Internet Protocol version number.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Version {
    /// IPv4
    Ip = 4,
    /// IPv6
    Ipv6 = 6,
}

impl Codec for Version {
    fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
        let original_byte = writer.peek_u8().unwrap_or(0);
        let packed_byte = ((*self as u8) << 4) | (original_byte & 0x0F);
        writer.poke_u8(packed_byte)
    }

    fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
        let byte = reader.peek_u8()? >> 4;
        match byte {
            4 => Ok(Self::Ip),
            6 => Ok(Self::Ipv6),
            _ => Err(BufError::UnexpectedValue),
        }
    }
}

/// A Protocol number.
///
/// Defined in [IANA ASSIGNMENTS PROTOCOL-NUMBERS]
///
/// [IANA ASSIGNMENTS PROTOCOL-NUMBERS]: https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Protocol(pub u8);

impl Protocol {
    ///
    pub const HOPOPT: Self = Self(0);
    ///
    pub const ICMP: Self = Self(1);
    ///
    pub const IGMP: Self = Self(2);
    ///
    pub const GGP: Self = Self(3);
    ///
    pub const IPV4: Self = Self(4);
    ///
    pub const ST: Self = Self(5);
    ///
    pub const TCP: Self = Self(6);
    ///
    pub const CBT: Self = Self(7);
    ///
    pub const EGP: Self = Self(8);
    ///
    pub const IGP: Self = Self(9);
    ///
    pub const BBN_RCC_MON: Self = Self(10);
    ///
    pub const NVP_II: Self = Self(11);
    ///
    pub const PUP: Self = Self(12);
    ///
    pub const ARGUS: Self = Self(13);
    ///
    pub const EMCON: Self = Self(14);
    ///
    pub const XNET: Self = Self(15);
    ///
    pub const CHAOS: Self = Self(16);
    ///
    pub const UDP: Self = Self(17);
    ///
    pub const MUX: Self = Self(18);
    ///
    pub const DCN_MEAS: Self = Self(19);
    ///
    pub const HMP: Self = Self(20);
    ///
    pub const PRM: Self = Self(21);
    ///
    pub const XNS_IDP: Self = Self(22);
    ///
    pub const TRUNK_1: Self = Self(23);
    ///
    pub const TRUNK_2: Self = Self(24);
    ///
    pub const LEAF_1: Self = Self(25);
    ///
    pub const LEAF_2: Self = Self(26);
    ///
    pub const RDP: Self = Self(27);
    ///
    pub const IRTP: Self = Self(28);
    ///
    pub const ISO_TP4: Self = Self(29);
    ///
    pub const NETBLT: Self = Self(30);
    ///
    pub const MFE_NSP: Self = Self(31);
    ///
    pub const MERIT_INP: Self = Self(32);
    ///
    pub const DCCP: Self = Self(33);
    ///
    pub const THREEPC: Self = Self(34);
    ///
    pub const IDPR: Self = Self(35);
    ///
    pub const XTP: Self = Self(36);
    ///
    pub const DDP: Self = Self(37);
    ///
    pub const IDPR_CMTP: Self = Self(38);
    ///
    pub const TP_PLUS_PLUS: Self = Self(39);
    ///
    pub const IL: Self = Self(40);
    ///
    pub const IPV6: Self = Self(41);
    ///
    pub const SDRP: Self = Self(42);
    ///
    pub const IPV6_ROUTE: Self = Self(43);
    ///
    pub const IPV6_FRAG: Self = Self(44);
    ///
    pub const IDRP: Self = Self(45);
    ///
    pub const RSVP: Self = Self(46);
    ///
    pub const GRE: Self = Self(47);
    ///
    pub const DSR: Self = Self(48);
    ///
    pub const BNA: Self = Self(49);
    ///
    pub const ESP: Self = Self(50);
    ///
    pub const AH: Self = Self(51);
    ///
    pub const I_NLSP: Self = Self(52);
    ///
    pub const SWIPE: Self = Self(53);
    ///
    pub const NARP: Self = Self(54);
    ///
    pub const MOBILE: Self = Self(55);
    ///
    pub const TLSP: Self = Self(56);
    ///
    pub const SKIP: Self = Self(57);
    ///
    pub const IPV6_ICMP: Self = Self(58);
    ///
    pub const IPV6_NO_NXT: Self = Self(59);
    ///
    pub const IPV6_OPTS: Self = Self(60);
    ///
    pub const HOST_NET: Self = Self(61);
    ///
    pub const CFTP: Self = Self(62);
    ///
    pub const LOCAL_NET: Self = Self(63);
    ///
    pub const SAT_EXPAK: Self = Self(64);
    ///
    pub const KRYPTOLAN: Self = Self(65);
    ///
    pub const RVD: Self = Self(66);
    ///
    pub const IPPC: Self = Self(67);
    ///
    pub const DISTRIBUTED_FS: Self = Self(68);
    ///
    pub const SAT_MON: Self = Self(69);
    ///
    pub const VISA: Self = Self(70);
    ///
    pub const IPCV: Self = Self(71);
    ///
    pub const CPNX: Self = Self(72);
    ///
    pub const CPHB: Self = Self(73);
    ///
    pub const WSN: Self = Self(74);
    ///
    pub const PVP: Self = Self(75);
    ///
    pub const BR_SAT_MON: Self = Self(76);
    ///
    pub const SUN_ND: Self = Self(77);
    ///
    pub const WB_MON: Self = Self(78);
    ///
    pub const WB_EXPAK: Self = Self(79);
    ///
    pub const ISO_IP: Self = Self(80);
    ///
    pub const VMTP: Self = Self(81);
    ///
    pub const SECURE_VMTP: Self = Self(82);
    ///
    pub const VINES: Self = Self(83);
    ///
    pub const IPTM: Self = Self(84);
    ///
    pub const NSFNET_IGP: Self = Self(85);
    ///
    pub const DGP: Self = Self(86);
    ///
    pub const TCF: Self = Self(87);
    ///
    pub const EIGRP: Self = Self(88);
    ///
    pub const OSPFIGP: Self = Self(89);
    ///
    pub const SPRITE_RPC: Self = Self(90);
    ///
    pub const LARP: Self = Self(91);
    ///
    pub const MTP: Self = Self(92);
    ///
    pub const AX_25: Self = Self(93);
    ///
    pub const IPIP: Self = Self(94);
    ///
    pub const MICP: Self = Self(95);
    ///
    pub const SCC_SP: Self = Self(96);
    ///
    pub const ETHERIP: Self = Self(97);
    ///
    pub const ENCAP: Self = Self(98);
    ///
    pub const PRIVATE_ENCAP: Self = Self(99);
    ///
    pub const GMTP: Self = Self(100);
    ///
    pub const IFMP: Self = Self(101);
    ///
    pub const PNNI: Self = Self(102);
    ///
    pub const PIM: Self = Self(103);
    ///
    pub const ARIS: Self = Self(104);
    ///
    pub const SCPS: Self = Self(105);
    ///
    pub const QNX: Self = Self(106);
    ///
    pub const A_N: Self = Self(107);
    ///
    pub const IPCOMP: Self = Self(108);
    ///
    pub const SNP: Self = Self(109);
    ///
    pub const COMPAQ_PEER: Self = Self(110);
    ///
    pub const IPX_IN_IP: Self = Self(111);
    ///
    pub const VRRP: Self = Self(112);
    ///
    pub const PGM: Self = Self(113);
    ///
    pub const ANY_0_HOP_PROTOCOL: Self = Self(114);
    ///
    pub const L2TP: Self = Self(115);
    ///
    pub const DDX: Self = Self(116);
    ///
    pub const IATP: Self = Self(117);
    ///
    pub const STP: Self = Self(118);
    ///
    pub const SRP: Self = Self(119);
    ///
    pub const UTI: Self = Self(120);
    ///
    pub const SMP: Self = Self(121);
    ///
    pub const SM: Self = Self(122);
    ///
    pub const PTP: Self = Self(123);
    ///
    pub const IS_IS_OVER_IPV4: Self = Self(124);
    ///
    pub const FIRE: Self = Self(125);
    ///
    pub const CRTP: Self = Self(126);
    ///
    pub const CRUDP: Self = Self(127);
    ///
    pub const SSCOPMCE: Self = Self(128);
    ///
    pub const IPLT: Self = Self(129);
    ///
    pub const SPS: Self = Self(130);
    ///
    pub const PIPE: Self = Self(131);
    ///
    pub const SCTP: Self = Self(132);
    ///
    pub const FC: Self = Self(133);
    ///
    pub const RSVP_E2E_IGNORE: Self = Self(134);
    ///
    pub const MOBILITY_HEADER: Self = Self(135);
    ///
    pub const UDPLITE: Self = Self(136);
    ///
    pub const MPLS_IN_IP: Self = Self(137);
    ///
    pub const MANET: Self = Self(138);
    ///
    pub const HIP: Self = Self(139);
    ///
    pub const SHIM6: Self = Self(140);
    ///
    pub const WESP: Self = Self(141);
    ///
    pub const ROHC: Self = Self(142);
    ///
    pub const ETHERNET: Self = Self(143);
    ///
    pub const AGGFRAG: Self = Self(144);
    ///
    pub const NSH: Self = Self(145);
    ///
    pub const HOMA: Self = Self(146);
    ///
    pub const BIT_EMU: Self = Self(147);
}

impl From<u8> for Protocol {
    fn from(value: u8) -> Self {
        Self(value)
    }
}

impl From<Protocol> for u8 {
    fn from(ether_type: Protocol) -> Self {
        ether_type.0
    }
}

impl Codec for Protocol {
    fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
        self.0.encode(writer, ())
    }

    fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
        Ok(Self(u8::decode(reader, ())?))
    }
}