@@ -17,8 +17,10 @@ use std::net::{Ipv4Addr, Ipv6Addr};
17
17
#[ cfg( all(
18
18
feature = "all" ,
19
19
any(
20
+ target_os = "android" ,
20
21
target_os = "ios" ,
21
22
target_os = "visionos" ,
23
+ target_os = "linux" ,
22
24
target_os = "macos" ,
23
25
target_os = "tvos" ,
24
26
target_os = "watchos" ,
@@ -1805,6 +1807,38 @@ impl crate::Socket {
1805
1807
. map ( |_| ( ) )
1806
1808
}
1807
1809
1810
+ /// Gets the value for the `SO_BINDTOIFINDEX` option on this socket.
1811
+ ///
1812
+ /// This value gets the socket binded device's interface index.
1813
+ #[ cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) ]
1814
+ pub fn device_index ( & self ) -> io:: Result < Option < NonZeroU32 > > {
1815
+ let index_raw = unsafe {
1816
+ getsockopt :: < libc:: c_uint > ( self . as_raw ( ) , libc:: SOL_SOCKET , libc:: SO_BINDTOIFINDEX ) ?
1817
+ } ;
1818
+ Ok ( NonZeroU32 :: new ( index_raw) )
1819
+ }
1820
+
1821
+ /// Sets the value for `SO_BINDTOIFINDEX` option on this socket.
1822
+ ///
1823
+ /// If a socket is bound to an interface, only packets received from that
1824
+ /// particular interface are processed by the socket. Note that this only
1825
+ /// works for some socket types, particularly `AF_INET` sockets.
1826
+ ///
1827
+ /// If `interface` is `None`, the binding is removed. If the `interface`
1828
+ /// index is not valid, an error is returned.
1829
+ #[ cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) ]
1830
+ pub fn bind_device_by_index ( & self , interface : Option < NonZeroU32 > ) -> io:: Result < ( ) > {
1831
+ let index = interface. map_or ( 0 , NonZeroU32 :: get) ;
1832
+ unsafe {
1833
+ setsockopt (
1834
+ self . as_raw ( ) ,
1835
+ libc:: SOL_SOCKET ,
1836
+ libc:: SO_BINDTOIFINDEX ,
1837
+ index as c_int ,
1838
+ )
1839
+ }
1840
+ }
1841
+
1808
1842
/// Sets the value for the `SO_SETFIB` option on this socket.
1809
1843
///
1810
1844
/// Bind socket to the specified forwarding table (VRF) on a FreeBSD.
0 commit comments