@@ -1789,6 +1789,68 @@ impl crate::Socket {
17891789 }
17901790 }
17911791
1792+ /// Get the value for the `SO_ORIGINAL_DST` option on this socket.
1793+ ///
1794+ /// This value contains the original destination IPv4 address of the connection
1795+ /// redirected using `iptables` `REDIRECT` or `TPROXY`.
1796+ #[ cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) ]
1797+ #[ cfg_attr(
1798+ docsrs,
1799+ doc( cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) )
1800+ ) ]
1801+ pub fn original_dst ( & self ) -> io:: Result < Option < SockAddr > > {
1802+ // Safety: `getsockopt` initialises the `SockAddr` for us.
1803+ unsafe {
1804+ SockAddr :: try_init ( |storage, len| {
1805+ syscall ! ( getsockopt(
1806+ self . as_raw( ) ,
1807+ libc:: SOL_IP ,
1808+ libc:: SO_ORIGINAL_DST ,
1809+ storage. cast( ) ,
1810+ len
1811+ ) )
1812+ } )
1813+ }
1814+ . map_or_else (
1815+ |e| match e. raw_os_error ( ) {
1816+ Some ( libc:: ENOENT ) => Ok ( None ) ,
1817+ _ => Err ( e) ,
1818+ } ,
1819+ |( _, addr) | Ok ( Some ( addr) ) ,
1820+ )
1821+ }
1822+
1823+ /// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket.
1824+ ///
1825+ /// This value contains the original destination IPv6 address of the connection
1826+ /// redirected using `ip6tables` `REDIRECT` or `TPROXY`.
1827+ #[ cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) ]
1828+ #[ cfg_attr(
1829+ docsrs,
1830+ doc( cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) )
1831+ ) ]
1832+ pub fn original_dst_ipv6 ( & self ) -> io:: Result < Option < SockAddr > > {
1833+ // Safety: `getsockopt` initialises the `SockAddr` for us.
1834+ unsafe {
1835+ SockAddr :: try_init ( |storage, len| {
1836+ syscall ! ( getsockopt(
1837+ self . as_raw( ) ,
1838+ libc:: SOL_IPV6 ,
1839+ libc:: IP6T_SO_ORIGINAL_DST ,
1840+ storage. cast( ) ,
1841+ len
1842+ ) )
1843+ } )
1844+ }
1845+ . map_or_else (
1846+ |e| match e. raw_os_error ( ) {
1847+ Some ( libc:: ENOENT ) => Ok ( None ) ,
1848+ _ => Err ( e) ,
1849+ } ,
1850+ |( _, addr) | Ok ( Some ( addr) ) ,
1851+ )
1852+ }
1853+
17921854 /// Copies data between a `file` and this socket using the `sendfile(2)`
17931855 /// system call. Because this copying is done within the kernel,
17941856 /// `sendfile()` is more efficient than the combination of `read(2)` and
0 commit comments