Skip to content

Commit 651209f

Browse files
committed
Added Socket::set_multicast_if_v4_n to set interface by index (rust-lang#458)
1 parent 795e974 commit 651209f

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

src/socket.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,45 @@ impl Socket {
14611461
}
14621462
}
14631463

1464+
/// Set the value of the `IP_MULTICAST_IF` option for this socket.
1465+
///
1466+
/// Specifies the interface to use for routing multicast packets.
1467+
/// See [`InterfaceIndexOrAddress`].
1468+
#[cfg(any(
1469+
target_os = "freebsd",
1470+
target_os = "netbsd",
1471+
target_os = "linux",
1472+
target_os = "android",
1473+
))]
1474+
pub fn set_multicast_if_v4_n(&self, interface: &InterfaceIndexOrAddress) -> io::Result<()> {
1475+
#[cfg(any(target_os = "freebsd", target_os = "linux", target_os = "android",))]
1476+
{
1477+
// IP_MULTICAST_IF supports struct mreqn to set the interface
1478+
let mreqn = sys::to_mreqn(&Ipv4Addr::UNSPECIFIED, interface);
1479+
unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_IF, mreqn) }
1480+
}
1481+
1482+
#[cfg(target_os = "netbsd")]
1483+
{
1484+
// IP_MULTICAST_IF only supports struct in_addr to set the interface, but passing an
1485+
// address in the 0.0.0.0/8 range is interpreted as an interface index (in network
1486+
// byte order)
1487+
let addr = match interface {
1488+
InterfaceIndexOrAddress::Index(index) => {
1489+
if *index >= 0x0100_0000 {
1490+
return Err(io::Error::new(
1491+
io::ErrorKind::AddrNotAvailable,
1492+
"Interface index out of bounds",
1493+
));
1494+
}
1495+
Ipv4Addr::from_bits(*index)
1496+
}
1497+
InterfaceIndexOrAddress::Address(a) => *a,
1498+
};
1499+
unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_MULTICAST_IF, addr) }
1500+
}
1501+
}
1502+
14641503
/// Get the value of the `IP_MULTICAST_LOOP` option for this socket.
14651504
///
14661505
/// For more information about this option, see [`set_multicast_loop_v4`].

0 commit comments

Comments
 (0)