internet 0.0.5

Network library for rust
Documentation
//! Internet Group Management Protocol (IGMP) version-independent definitions.

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

/// The Internet Checksum following [RFC 1071].
///
/// Used in all IGMP versions to verify the integrity of the message.
///
/// [RFC 1071]: https://datatracker.ietf.org/doc/html/rfc1071
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Checksum(pub u16);

impl Checksum {
    /// Calculates the Internet Checksum over the given data.
    pub fn calculate(data: &[u8]) -> Self {
        let mut sum: u32 = 0;
        let mut i = 0;

        while i + 1 < data.len() {
            sum += u16::from_be_bytes([data[i], data[i + 1]]) as u32;
            i += 2;
        }

        if i < data.len() {
            sum += (data[i] as u32) << 8;
        }

        while sum >> 16 != 0 {
            sum = (sum & 0xFFFF) + (sum >> 16);
        }

        Checksum(!(sum as u16))
    }
}

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

    fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
        u16::decode(reader, ()).map(Checksum)
    }
}