Skip to content

Commit 071378d

Browse files
authored
Added bind_device_by_index_{v4,v6} for linux and android (#569) (#572)
1 parent 1fe6c54 commit 071378d

File tree

2 files changed

+93
-9
lines changed

2 files changed

+93
-9
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ targets = [
5151
features = ["all"]
5252

5353
[target."cfg(unix)".dependencies]
54-
libc = "0.2.171"
54+
libc = "0.2.172"
5555

5656
[target.'cfg(windows)'.dependencies.windows-sys]
5757
version = "0.52"

src/sys/unix.rs

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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
))]
2931
use 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

Comments
 (0)