@@ -24,6 +24,8 @@ use std::net::{Ipv4Addr, Ipv6Addr};
2424 target_os = "watchos" ,
2525 target_os = "illumos" ,
2626 target_os = "solaris" ,
27+ target_os = "linux" ,
28+ target_os = "android" ,
2729 )
2830) ) ]
2931use std:: num:: NonZeroU32 ;
@@ -1876,7 +1878,7 @@ impl crate::Socket {
18761878 . map ( |_| ( ) )
18771879 }
18781880
1879- /// Sets the value for `IP_BOUND_IF` option on this socket.
1881+ /// Sets the value for `IP_BOUND_IF` or `SO_BINDTOIFINDEX` option on this socket.
18801882 ///
18811883 /// If a socket is bound to an interface, only packets received from that
18821884 /// particular interface are processed by the socket.
@@ -1896,14 +1898,38 @@ impl crate::Socket {
18961898 target_os = "watchos" ,
18971899 target_os = "illumos" ,
18981900 target_os = "solaris" ,
1901+ target_os = "linux" ,
1902+ target_os = "android" ,
18991903 )
19001904 ) ) ]
19011905 pub fn bind_device_by_index_v4 ( & self , interface : Option < NonZeroU32 > ) -> io:: Result < ( ) > {
19021906 let index = interface. map_or ( 0 , NonZeroU32 :: get) ;
1903- unsafe { setsockopt ( self . as_raw ( ) , IPPROTO_IP , libc:: IP_BOUND_IF , index) }
1907+
1908+ #[ cfg( any(
1909+ target_os = "ios" ,
1910+ target_os = "visionos" ,
1911+ target_os = "macos" ,
1912+ target_os = "tvos" ,
1913+ target_os = "watchos" ,
1914+ target_os = "illumos" ,
1915+ target_os = "solaris" ,
1916+ ) ) ]
1917+ unsafe {
1918+ setsockopt ( self . as_raw ( ) , IPPROTO_IP , libc:: IP_BOUND_IF , index)
1919+ }
1920+
1921+ #[ cfg( any( target_os = "linux" , target_os = "android" , ) ) ]
1922+ unsafe {
1923+ setsockopt (
1924+ self . as_raw ( ) ,
1925+ libc:: SOL_SOCKET ,
1926+ libc:: SO_BINDTOIFINDEX ,
1927+ index,
1928+ )
1929+ }
19041930 }
19051931
1906- /// Sets the value for `IPV6_BOUND_IF` option on this socket.
1932+ /// Sets the value for `IPV6_BOUND_IF` or `SO_BINDTOIFINDEX` option on this socket.
19071933 ///
19081934 /// If a socket is bound to an interface, only packets received from that
19091935 /// particular interface are processed by the socket.
@@ -1923,15 +1949,39 @@ impl crate::Socket {
19231949 target_os = "watchos" ,
19241950 target_os = "illumos" ,
19251951 target_os = "solaris" ,
1952+ target_os = "linux" ,
1953+ target_os = "android" ,
19261954 )
19271955 ) ) ]
19281956 pub fn bind_device_by_index_v6 ( & self , interface : Option < NonZeroU32 > ) -> io:: Result < ( ) > {
19291957 let index = interface. map_or ( 0 , NonZeroU32 :: get) ;
1930- unsafe { setsockopt ( self . as_raw ( ) , IPPROTO_IPV6 , libc:: IPV6_BOUND_IF , index) }
1958+
1959+ #[ cfg( any(
1960+ target_os = "ios" ,
1961+ target_os = "visionos" ,
1962+ target_os = "macos" ,
1963+ target_os = "tvos" ,
1964+ target_os = "watchos" ,
1965+ target_os = "illumos" ,
1966+ target_os = "solaris" ,
1967+ ) ) ]
1968+ unsafe {
1969+ setsockopt ( self . as_raw ( ) , IPPROTO_IPV6 , libc:: IPV6_BOUND_IF , index)
1970+ }
1971+
1972+ #[ cfg( any( target_os = "linux" , target_os = "android" , ) ) ]
1973+ unsafe {
1974+ setsockopt (
1975+ self . as_raw ( ) ,
1976+ libc:: SOL_SOCKET ,
1977+ libc:: SO_BINDTOIFINDEX ,
1978+ index,
1979+ )
1980+ }
19311981 }
19321982
1933- /// Gets the value for `IP_BOUND_IF` option on this socket, i.e. the index
1934- /// for the interface to which the socket is bound.
1983+ /// Gets the value for `IP_BOUND_IF` or `SO_BINDTOIFINDEX` option on this
1984+ /// socket, i.e. the index for the interface to which the socket is bound.
19351985 ///
19361986 /// Returns `None` if the socket is not bound to any interface, otherwise
19371987 /// returns an interface index.
@@ -1945,16 +1995,33 @@ impl crate::Socket {
19451995 target_os = "watchos" ,
19461996 target_os = "illumos" ,
19471997 target_os = "solaris" ,
1998+ target_os = "linux" ,
1999+ target_os = "android" ,
19482000 )
19492001 ) ) ]
19502002 pub fn device_index_v4 ( & self ) -> io:: Result < Option < NonZeroU32 > > {
2003+ #[ cfg( any(
2004+ target_os = "ios" ,
2005+ target_os = "visionos" ,
2006+ target_os = "macos" ,
2007+ target_os = "tvos" ,
2008+ target_os = "watchos" ,
2009+ target_os = "illumos" ,
2010+ target_os = "solaris" ,
2011+ ) ) ]
19512012 let index =
19522013 unsafe { getsockopt :: < libc:: c_uint > ( self . as_raw ( ) , IPPROTO_IP , libc:: IP_BOUND_IF ) ? } ;
2014+
2015+ #[ cfg( any( target_os = "linux" , target_os = "android" , ) ) ]
2016+ let index = unsafe {
2017+ getsockopt :: < libc:: c_uint > ( self . as_raw ( ) , libc:: SOL_SOCKET , libc:: SO_BINDTOIFINDEX ) ?
2018+ } ;
2019+
19532020 Ok ( NonZeroU32 :: new ( index) )
19542021 }
19552022
1956- /// Gets the value for `IPV6_BOUND_IF` option on this socket, i.e. the index
1957- /// for the interface to which the socket is bound.
2023+ /// Gets the value for `IPV6_BOUND_IF` or `SO_BINDTOIFINDEX` option on this
2024+ /// socket, i.e. the index for the interface to which the socket is bound.
19582025 ///
19592026 /// Returns `None` if the socket is not bound to any interface, otherwise
19602027 /// returns an interface index.
@@ -1968,12 +2035,29 @@ impl crate::Socket {
19682035 target_os = "watchos" ,
19692036 target_os = "illumos" ,
19702037 target_os = "solaris" ,
2038+ target_os = "linux" ,
2039+ target_os = "android" ,
19712040 )
19722041 ) ) ]
19732042 pub fn device_index_v6 ( & self ) -> io:: Result < Option < NonZeroU32 > > {
2043+ #[ cfg( any(
2044+ target_os = "ios" ,
2045+ target_os = "visionos" ,
2046+ target_os = "macos" ,
2047+ target_os = "tvos" ,
2048+ target_os = "watchos" ,
2049+ target_os = "illumos" ,
2050+ target_os = "solaris" ,
2051+ ) ) ]
19742052 let index = unsafe {
19752053 getsockopt :: < libc:: c_uint > ( self . as_raw ( ) , IPPROTO_IPV6 , libc:: IPV6_BOUND_IF ) ?
19762054 } ;
2055+
2056+ #[ cfg( any( target_os = "linux" , target_os = "android" , ) ) ]
2057+ let index = unsafe {
2058+ getsockopt :: < libc:: c_uint > ( self . as_raw ( ) , libc:: SOL_SOCKET , libc:: SO_BINDTOIFINDEX ) ?
2059+ } ;
2060+
19772061 Ok ( NonZeroU32 :: new ( index) )
19782062 }
19792063
0 commit comments