use socket2::{Domain, Protocol, Socket, Type}; use std::io::{Error, ErrorKind}; use std::mem::MaybeUninit; use std::net::Ipv4Addr; use vrrpd::vrrpv2::{self, VRRPv2, VRRPv2Error}; fn main() -> std::io::Result<()> { let sock = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(112)))?; sock.join_multicast_v4( &Ipv4Addr::new(224, 0, 0, 18), &Ipv4Addr::UNSPECIFIED, )?; let vrrp = recv_vrrp(sock).map_err(|err| { Error::new(ErrorKind::InvalidData, format!("recv_vrrp(): {err}")) })?; eprintln!("vrrp: {vrrp:?}"); Ok(()) } fn recv_vrrp(sock: Socket) -> Result { let mut buf = [MaybeUninit::::uninit(); 512]; let (nbytes, _) = sock.recv_from(&mut buf)?; let bytes = unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const u8, nbytes) }; let ttl: u8 = bytes[8]; if ttl != 255 { return Err(VRRPv2Error::InvalidTTL); } let ihl = bytes[0] & 0xF; let data_offset = (ihl * 4) as usize; vrrpv2::from_bytes(&bytes[data_offset..]) }