@@ -17,8 +17,11 @@ use std::net::{Ipv4Addr, Ipv6Addr};
17
17
#[ cfg( all(
18
18
feature = "all" ,
19
19
any(
20
+ target_os = "android" ,
21
+ target_os = "fuchsia" ,
20
22
target_os = "ios" ,
21
23
target_os = "visionos" ,
24
+ target_os = "linux" ,
22
25
target_os = "macos" ,
23
26
target_os = "tvos" ,
24
27
target_os = "watchos" ,
@@ -1782,7 +1785,8 @@ impl crate::Socket {
1782
1785
///
1783
1786
/// If a socket is bound to an interface, only packets received from that
1784
1787
/// particular interface are processed by the socket. Note that this only
1785
- /// works for some socket types, particularly `AF_INET` sockets.
1788
+ /// works for some socket types, particularly `AF_INET` and `AF_INET6`
1789
+ /// sockets.
1786
1790
///
1787
1791
/// If `interface` is `None` or an empty string it removes the binding.
1788
1792
#[ cfg( all(
@@ -1820,6 +1824,31 @@ impl crate::Socket {
1820
1824
. map ( |_| ( ) )
1821
1825
}
1822
1826
1827
+ /// Sets the value for `SO_BINDTOIFINDEX` option on this socket.
1828
+ ///
1829
+ /// If a socket is bound to an interface, only packets received from that
1830
+ /// particular interface are processed by the socket. Note that this only
1831
+ /// works for some socket types, particularly `AF_INET` and `AF_INET6`
1832
+ /// sockets.
1833
+ ///
1834
+ /// If `interface` is `None`, the binding is removed. If the `interface`
1835
+ /// index is not valid, an error is returned.
1836
+ #[ cfg( all(
1837
+ feature = "all" ,
1838
+ any( target_os = "android" , target_os = "fuchsia" , target_os = "linux" )
1839
+ ) ) ]
1840
+ pub fn bind_device_by_index ( & self , interface : Option < NonZeroU32 > ) -> io:: Result < ( ) > {
1841
+ let index = interface. map_or ( 0 , NonZeroU32 :: get) ;
1842
+ unsafe {
1843
+ setsockopt (
1844
+ self . as_raw ( ) ,
1845
+ libc:: SOL_SOCKET ,
1846
+ libc:: SO_BINDTOIFINDEX ,
1847
+ index as c_int ,
1848
+ )
1849
+ }
1850
+ }
1851
+
1823
1852
/// Sets the value for `IP_BOUND_IF` option on this socket.
1824
1853
///
1825
1854
/// If a socket is bound to an interface, only packets received from that
@@ -1874,6 +1903,21 @@ impl crate::Socket {
1874
1903
unsafe { setsockopt ( self . as_raw ( ) , IPPROTO_IPV6 , libc:: IPV6_BOUND_IF , index) }
1875
1904
}
1876
1905
1906
+ /// Gets the value for the `SO_BINDTOIFINDEX` option on this socket.
1907
+ ///
1908
+ /// Returns `None` if the socket is not bound to any interface, otherwise
1909
+ /// returns an interface index.
1910
+ #[ cfg( all(
1911
+ feature = "all" ,
1912
+ any( target_os = "android" , target_os = "fuchsia" , target_os = "linux" )
1913
+ ) ) ]
1914
+ pub fn device_index ( & self ) -> io:: Result < Option < NonZeroU32 > > {
1915
+ let index_raw = unsafe {
1916
+ getsockopt :: < libc:: c_uint > ( self . as_raw ( ) , libc:: SOL_SOCKET , libc:: SO_BINDTOIFINDEX ) ?
1917
+ } ;
1918
+ Ok ( NonZeroU32 :: new ( index_raw) )
1919
+ }
1920
+
1877
1921
/// Gets the value for `IP_BOUND_IF` option on this socket, i.e. the index
1878
1922
/// for the interface to which the socket is bound.
1879
1923
///
0 commit comments