use crate::{
Buf, BufError, BufMut, BufResult, Codec, Cursor, ietf::igmp::Checksum, ietf::ipv4::Address,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Query {
pub unused: u8,
pub checksum: Checksum,
pub group_address: Address,
}
impl Query {
pub const TYPE_AND_VERSION: u8 = 0x11;
}
impl Codec for Query {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE_AND_VERSION.encode(writer, ())?;
self.unused.encode(writer, ())?;
self.checksum.encode(writer, ())?;
let addr_bytes: [u8; 4] = self.group_address.into();
addr_bytes.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let type_and_version = u8::decode(reader, ())?;
if type_and_version != Self::TYPE_AND_VERSION {
return Err(BufError::UnexpectedValue);
}
Ok(Self {
unused: u8::decode(reader, ())?,
checksum: Checksum::decode(reader, ())?,
group_address: Address::from(reader.read_array::<4>()?),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Report {
pub unused: u8,
pub checksum: Checksum,
pub group_address: Address,
}
impl Report {
pub const TYPE_AND_VERSION: u8 = 0x12;
}
impl Codec for Report {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE_AND_VERSION.encode(writer, ())?;
self.unused.encode(writer, ())?;
self.checksum.encode(writer, ())?;
let addr_bytes: [u8; 4] = self.group_address.into();
addr_bytes.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let type_and_version = u8::decode(reader, ())?;
if type_and_version != Self::TYPE_AND_VERSION {
return Err(BufError::UnexpectedValue);
}
Ok(Self {
unused: u8::decode(reader, ())?,
checksum: Checksum::decode(reader, ())?,
group_address: Address::from(reader.read_array::<4>()?),
})
}
}