@@ -845,7 +845,6 @@ fn set_common_accept_flags(socket: Socket) -> io::Result<Socket> {
845845#[ cfg( not( any(
846846 target_os = "haiku" ,
847847 target_os = "illumos" ,
848- target_os = "netbsd" ,
849848 target_os = "redox" ,
850849 target_os = "solaris" ,
851850) ) ) ]
@@ -1520,6 +1519,66 @@ impl Socket {
15201519 }
15211520 }
15221521
1522+ /// Set the value of the `IP_MULTICAST_IF` option for this socket.
1523+ ///
1524+ /// Specifies the interface to use for routing multicast packets.
1525+ /// See [`InterfaceIndexOrAddress`].
1526+ #[ cfg( all(
1527+ feature = "all" ,
1528+ any(
1529+ target_os = "freebsd" ,
1530+ target_os = "netbsd" ,
1531+ target_os = "linux" ,
1532+ target_os = "android" ,
1533+ target_os = "fuchsia" ,
1534+ )
1535+ ) ) ]
1536+ pub fn set_multicast_if_v4_n ( & self , interface : & InterfaceIndexOrAddress ) -> io:: Result < ( ) > {
1537+ #[ cfg( any(
1538+ target_os = "freebsd" ,
1539+ target_os = "linux" ,
1540+ target_os = "android" ,
1541+ target_os = "fuchsia"
1542+ ) ) ]
1543+ {
1544+ // IP_MULTICAST_IF supports struct mreqn to set the interface
1545+ let mreqn = sys:: to_mreqn ( & Ipv4Addr :: UNSPECIFIED , interface) ;
1546+ unsafe { setsockopt ( self . as_raw ( ) , sys:: IPPROTO_IP , sys:: IP_MULTICAST_IF , mreqn) }
1547+ }
1548+
1549+ #[ cfg( target_os = "netbsd" ) ]
1550+ {
1551+ // IP_MULTICAST_IF only supports struct in_addr to set the interface, but passing an
1552+ // address in the 0.0.0.0/8 range is interpreted as an interface index (in network
1553+ // byte order), see ip_multicast_if() in
1554+ // https://github.com/NetBSD/src/blob/trunk/sys/netinet/ip_output.c; alternatively, as
1555+ // shown in the example code in https://man.netbsd.org/NetBSD-7.0/ip.4, the interface
1556+ // index can be passed as uint32_t in network byte order
1557+ match interface {
1558+ InterfaceIndexOrAddress :: Index ( index) => {
1559+ if * index >= 0x0100_0000 {
1560+ return Err ( io:: Error :: new (
1561+ io:: ErrorKind :: AddrNotAvailable ,
1562+ "Interface index out of bounds" ,
1563+ ) ) ;
1564+ }
1565+ let index_be = ( * index as u32 ) . to_be ( ) ;
1566+ unsafe {
1567+ setsockopt (
1568+ self . as_raw ( ) ,
1569+ sys:: IPPROTO_IP ,
1570+ sys:: IP_MULTICAST_IF ,
1571+ index_be,
1572+ )
1573+ }
1574+ }
1575+ InterfaceIndexOrAddress :: Address ( a) => unsafe {
1576+ setsockopt ( self . as_raw ( ) , sys:: IPPROTO_IP , sys:: IP_MULTICAST_IF , * a)
1577+ } ,
1578+ }
1579+ }
1580+ }
1581+
15231582 /// Get the value of the `IP_MULTICAST_LOOP` option for this socket.
15241583 ///
15251584 /// For more information about this option, see [`set_multicast_loop_v4`].
0 commit comments