diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2017-12-04 05:13:51 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2017-12-04 05:13:51 +0000 |
commit | 3871586a9bcff84eea6dd05f229fbe6ddb3f2bdd (patch) | |
tree | b818216ed82cf901884e80ea0eaf627ac9a423af /src/sys/socket/addr.rs | |
parent | 86ebf7b0eac4cd0d092b816060042c55ca8871c5 (diff) | |
parent | 985ea01aa84811378eede881dad6f2f9020aa5d1 (diff) | |
download | nix-3871586a9bcff84eea6dd05f229fbe6ddb3f2bdd.zip |
Merge #667
667: Add support for getifaddrs. r=asomers a=mwanner
Here's a first attempt at a rustian interface for `getifaddrs`, please review.
Changes for the changelog:
- Added `nix::ifaddrs::{getifaddrs, InterfaceAddressIterator,
InterfaceAddress and InterfaceFlags}`
Closes #650.
Closes #764.
Diffstat (limited to 'src/sys/socket/addr.rs')
-rw-r--r-- | src/sys/socket/addr.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 29832b37..a1f86518 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -201,6 +201,26 @@ pub enum AddressFamily { Natm = libc::AF_NATM, } +impl AddressFamily { + /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from + /// the `sa_family` field of a `sockaddr`. + /// + /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink + /// and System. Returns None for unsupported or unknown address families. + pub fn from_i32(family: i32) -> Option<AddressFamily> { + match family { + libc::AF_UNIX => Some(AddressFamily::Unix), + libc::AF_INET => Some(AddressFamily::Inet), + libc::AF_INET6 => Some(AddressFamily::Inet6), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => Some(AddressFamily::Netlink), + #[cfg(any(target_os = "macos", target_os = "macos"))] + libc::AF_SYSTEM => Some(AddressFamily::System), + _ => None + } + } +} + #[derive(Copy)] pub enum InetAddr { V4(libc::sockaddr_in), @@ -707,6 +727,34 @@ impl SockAddr { format!("{}", self) } + /// Creates a `SockAddr` struct from libc's sockaddr. + /// + /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System. + /// Returns None for unsupported families. + pub unsafe fn from_libc_sockaddr(addr: *const libc::sockaddr) -> Option<SockAddr> { + if addr.is_null() { + None + } else { + match AddressFamily::from_i32((*addr).sa_family as i32) { + Some(AddressFamily::Unix) => None, + Some(AddressFamily::Inet) => Some(SockAddr::Inet( + InetAddr::V4(*(addr as *const libc::sockaddr_in)))), + Some(AddressFamily::Inet6) => Some(SockAddr::Inet( + InetAddr::V6(*(addr as *const libc::sockaddr_in6)))), + #[cfg(any(target_os = "android", target_os = "linux"))] + Some(AddressFamily::Netlink) => Some(SockAddr::Netlink( + NetlinkAddr(*(addr as *const libc::sockaddr_nl)))), + #[cfg(any(target_os = "ios", target_os = "macos"))] + Some(AddressFamily::System) => Some(SockAddr::SysControl( + SysControlAddr(*(addr as *const sys_control::sockaddr_ctl)))), + // Other address families are currently not supported and simply yield a None + // entry instead of a proper conversion to a `SockAddr`. + Some(_) => None, + None => None, + } + } + } + pub unsafe fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) { match *self { SockAddr::Inet(InetAddr::V4(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in>() as libc::socklen_t), |