Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,19 @@ pub enum ControlMessageOwned {
target_os = "openbsd",
))]
Ipv4RecvDstAddr(libc::in_addr),
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV4(libc::sockaddr_in),
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV6(libc::sockaddr_in6),

/// Catch-all variant for unimplemented cmsg types.
#[doc(hidden)]
Unknown(UnknownCmsg),
Expand Down Expand Up @@ -546,6 +559,16 @@ impl ControlMessageOwned {
let dl = ptr::read_unaligned(p as *const libc::in_addr);
ControlMessageOwned::Ipv4RecvDstAddr(dl)
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
(libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {
let dl = ptr::read_unaligned(p as *const libc::sockaddr_in);
ControlMessageOwned::OrigDstAddrV4(dl)
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
(libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {
let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6);
ControlMessageOwned::OrigDstAddrV6(dl)
},
(_, _) => {
let sl = slice::from_raw_parts(p, len);
let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(&sl[..]));
Expand Down Expand Up @@ -587,6 +610,34 @@ pub enum ControlMessage<'a> {
#[cfg(any(target_os = "android", target_os = "linux"))]
ScmCredentials(&'a UnixCredentials),

/// A message of type `IP_ORIGDSTADDR` which is triggered by setting
/// `RecvOrigDstAddrV4` socket option and is used to get original IPv4
/// UDP or TCP destination address when actual destination address
/// is overwritten by [`TPROXY`][1], which in turn may be used to
/// make a transparent proxy server.
///
/// [1]:https://www.kernel.org/doc/Documentation/networking/tproxy.txt
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV4(&'a libc::sockaddr_in),

/// A message of type `IPV6_ORIGDSTADDR` which is triggered by setting
/// `RecvOrigDstAddrV6` socket option and is used to get original IPv6
/// UDP or TCP destination address when actual destination address
/// is overwritten by [`TPROXY`][1], which in turn may be used to
/// make a transparent proxy server.
///
/// [1]:https://www.kernel.org/doc/Documentation/networking/tproxy.txt
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV6(&'a libc::sockaddr_in6),

/// Set IV for `AF_ALG` crypto API.
///
/// For further information, please refer to the
Expand Down Expand Up @@ -655,6 +706,22 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmCredentials(creds) => {
&creds.0 as *const libc::ucred as *const u8
}
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV4(origaddr) => {
origaddr as *const libc::sockaddr_in as *const u8
},
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV6(origaddr) => {
origaddr as *const libc::sockaddr_in6 as *const u8
},
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetIv(iv) => {
unsafe {
Expand Down Expand Up @@ -696,6 +763,22 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmCredentials(creds) => {
mem::size_of_val(creds)
}
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV4(origaddr) => {
mem::size_of_val(origaddr)
},
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV6(origaddr) => {
mem::size_of_val(origaddr)
},
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetIv(iv) => {
mem::size_of::<libc::af_alg_iv>() + iv.len()
Expand All @@ -720,6 +803,10 @@ impl<'a> ControlMessage<'a> {
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) |
ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG ,
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV4(_) => libc::IPPROTO_IP,
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV6(_) => libc::IPPROTO_IPV6,
}
}

Expand All @@ -733,6 +820,14 @@ impl<'a> ControlMessage<'a> {
ControlMessage::AlgSetIv(_) => {
libc::ALG_SET_IV
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV4(_) => {
libc::IP_ORIGDSTADDR
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV6(_) => {
libc::IPV6_ORIGDSTADDR
},
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetOp(_) => {
libc::ALG_SET_OP
Expand Down
4 changes: 4 additions & 0 deletions src/sys/socket/sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::s
sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
#[cfg(any(target_os = "android", target_os = "linux"))]
sockopt_impl!(Both, IpTransparent, libc::SOL_IP, libc::IP_TRANSPARENT, bool);
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
sockopt_impl!(Both, RecvOrigDstAddrV4, libc::SOL_IP, libc::IP_RECVORIGDSTADDR, bool);
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
sockopt_impl!(Both, RecvOrigDstAddrV6, libc::SOL_IPV6, libc::IPV6_RECVORIGDSTADDR, bool);
#[cfg(target_os = "openbsd")]
sockopt_impl!(Both, BindAny, libc::SOL_SOCKET, libc::SO_BINDANY, bool);
#[cfg(target_os = "freebsd")]
Expand Down