use network_interface::{NetworkInterface, NetworkInterfaceConfig}; use socket2::{Domain, Protocol, SockAddr, Socket, Type}; use socket_pktinfo::PktInfoUdpSocket; use std::io; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; #[test] fn ipv4_test() -> io::Result<()> { let mut interfaces = NetworkInterface::show().unwrap(); interfaces.sort_by(|a, b| a.index.cmp(&b.index)); let interface = interfaces .into_iter() .find(|n| { !n.addr.iter().any(|a| a.ip().is_loopback()) && n.addr.iter().any(|a| a.ip().is_ipv4()) }) .expect("Can't run test without any IPv4 network interfaces"); let local_ip = match interface .addr .iter() .find(|a| a.ip().is_ipv4()) .unwrap() .ip() { IpAddr::V4(ip) => ip, IpAddr::V6(_) => unreachable!(), }; println!( "Testing using network interface index {}, ip {}", interface.index, local_ip ); let port = 8000; let multicast_addr = Ipv4Addr::new(238, 10, 20, 31); let local_addr: SockAddr = SocketAddr::new(IpAddr::V4(local_ip), port).into(); let broadcast_socket_addr: SockAddr = SocketAddr::new(Ipv4Addr::BROADCAST.into(), port).into(); let multicast_socket_addr: SockAddr = SocketAddr::new(multicast_addr.into(), port).into(); let mut buf = [0; 1024]; let socket = PktInfoUdpSocket::new(Domain::IPV4)?; socket.set_reuse_address(true)?; socket.set_multicast_if_v4(&local_ip)?; socket.join_multicast_v4(&multicast_addr, &local_ip)?; socket.set_multicast_loop_v4(true)?; socket.bind(&SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), port).into())?; { let output_socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?; let data = "Hello"; output_socket.send_to(data.as_bytes(), &local_addr)?; } let (_, info) = socket.recv(&mut buf)?; println!( "Unicast packet received on interface index {} from src {} with destination ip {}", info.if_index, info.addr_src, info.addr_dst, ); { let output_socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?; output_socket.set_broadcast(true)?; let data = "Hello"; output_socket.send_to(data.as_bytes(), &broadcast_socket_addr)?; } let (_, info) = socket.recv(&mut buf)?; println!( "Broadcast packet received on interface index {} from src {} with destination ip {}", info.if_index, info.addr_src, info.addr_dst, ); { let output_socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?; output_socket.set_multicast_if_v4(&local_ip)?; output_socket.set_multicast_loop_v4(true)?; let data = "Hello"; output_socket.send_to(data.as_bytes(), &multicast_socket_addr)?; } let (_, info) = socket.recv(&mut buf)?; println!( "Multicast packet received on interface index {} from src {} with destination ip {}", info.if_index, info.addr_src, info.addr_dst, ); Ok(()) }