Skip to content

Commit 940165e

Browse files
committed
Added Socket::set_multicast_if_v4_n to set interface by index (#458)
1 parent 795e974 commit 940165e

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ pub use sockref::SockRef;
192192
#[cfg(not(any(
193193
target_os = "haiku",
194194
target_os = "illumos",
195-
target_os = "netbsd",
196195
target_os = "redox",
197196
target_os = "solaris",
198197
)))]

src/socket.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,6 @@ fn set_common_flags(socket: Socket) -> io::Result<Socket> {
821821
#[cfg(not(any(
822822
target_os = "haiku",
823823
target_os = "illumos",
824-
target_os = "netbsd",
825824
target_os = "redox",
826825
target_os = "solaris",
827826
)))]
@@ -1461,6 +1460,45 @@ impl Socket {
14611460
}
14621461
}
14631462

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

0 commit comments

Comments
 (0)