13da5c369Sopenharmony_ci#[cfg(any( 23da5c369Sopenharmony_ci target_os = "android", 33da5c369Sopenharmony_ci target_os = "dragonfly", 43da5c369Sopenharmony_ci target_os = "freebsd", 53da5c369Sopenharmony_ci target_os = "ios", 63da5c369Sopenharmony_ci target_os = "linux", 73da5c369Sopenharmony_ci target_os = "macos", 83da5c369Sopenharmony_ci target_os = "illumos", 93da5c369Sopenharmony_ci target_os = "netbsd", 103da5c369Sopenharmony_ci target_os = "openbsd", 113da5c369Sopenharmony_ci target_os = "haiku", 123da5c369Sopenharmony_ci target_os = "fuchsia" 133da5c369Sopenharmony_ci))] 143da5c369Sopenharmony_ci#[cfg(feature = "net")] 153da5c369Sopenharmony_cipub use self::datalink::LinkAddr; 163da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 173da5c369Sopenharmony_cipub use self::vsock::VsockAddr; 183da5c369Sopenharmony_ciuse super::sa_family_t; 193da5c369Sopenharmony_ciuse crate::errno::Errno; 203da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 213da5c369Sopenharmony_ciuse crate::sys::socket::addr::alg::AlgAddr; 223da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 233da5c369Sopenharmony_ciuse crate::sys::socket::addr::netlink::NetlinkAddr; 243da5c369Sopenharmony_ci#[cfg(all( 253da5c369Sopenharmony_ci feature = "ioctl", 263da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 273da5c369Sopenharmony_ci))] 283da5c369Sopenharmony_ciuse crate::sys::socket::addr::sys_control::SysControlAddr; 293da5c369Sopenharmony_ciuse crate::{NixPath, Result}; 303da5c369Sopenharmony_ciuse cfg_if::cfg_if; 313da5c369Sopenharmony_ciuse memoffset::offset_of; 323da5c369Sopenharmony_ciuse std::convert::TryInto; 333da5c369Sopenharmony_ciuse std::ffi::OsStr; 343da5c369Sopenharmony_ciuse std::hash::{Hash, Hasher}; 353da5c369Sopenharmony_ciuse std::os::unix::ffi::OsStrExt; 363da5c369Sopenharmony_ci#[cfg(any(target_os = "ios", target_os = "macos"))] 373da5c369Sopenharmony_ciuse std::os::unix::io::RawFd; 383da5c369Sopenharmony_ciuse std::path::Path; 393da5c369Sopenharmony_ciuse std::{fmt, mem, net, ptr, slice}; 403da5c369Sopenharmony_ci 413da5c369Sopenharmony_ci/// Convert a std::net::Ipv4Addr into the libc form. 423da5c369Sopenharmony_ci#[cfg(feature = "net")] 433da5c369Sopenharmony_cipub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr { 443da5c369Sopenharmony_ci static_assertions::assert_eq_size!(net::Ipv4Addr, libc::in_addr); 453da5c369Sopenharmony_ci // Safe because both types have the same memory layout, and no fancy Drop 463da5c369Sopenharmony_ci // impls. 473da5c369Sopenharmony_ci unsafe { 483da5c369Sopenharmony_ci mem::transmute(addr) 493da5c369Sopenharmony_ci } 503da5c369Sopenharmony_ci} 513da5c369Sopenharmony_ci 523da5c369Sopenharmony_ci/// Convert a std::net::Ipv6Addr into the libc form. 533da5c369Sopenharmony_ci#[cfg(feature = "net")] 543da5c369Sopenharmony_cipub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr { 553da5c369Sopenharmony_ci static_assertions::assert_eq_size!(net::Ipv6Addr, libc::in6_addr); 563da5c369Sopenharmony_ci // Safe because both are Newtype wrappers around the same libc type 573da5c369Sopenharmony_ci unsafe { 583da5c369Sopenharmony_ci mem::transmute(*addr) 593da5c369Sopenharmony_ci } 603da5c369Sopenharmony_ci} 613da5c369Sopenharmony_ci 623da5c369Sopenharmony_ci/// These constants specify the protocol family to be used 633da5c369Sopenharmony_ci/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) 643da5c369Sopenharmony_ci/// 653da5c369Sopenharmony_ci/// # References 663da5c369Sopenharmony_ci/// 673da5c369Sopenharmony_ci/// [address_families(7)](https://man7.org/linux/man-pages/man7/address_families.7.html) 683da5c369Sopenharmony_ci// Should this be u8? 693da5c369Sopenharmony_ci#[repr(i32)] 703da5c369Sopenharmony_ci#[non_exhaustive] 713da5c369Sopenharmony_ci#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 723da5c369Sopenharmony_cipub enum AddressFamily { 733da5c369Sopenharmony_ci /// Local communication (see [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html)) 743da5c369Sopenharmony_ci Unix = libc::AF_UNIX, 753da5c369Sopenharmony_ci /// IPv4 Internet protocols (see [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html)) 763da5c369Sopenharmony_ci Inet = libc::AF_INET, 773da5c369Sopenharmony_ci /// IPv6 Internet protocols (see [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html)) 783da5c369Sopenharmony_ci Inet6 = libc::AF_INET6, 793da5c369Sopenharmony_ci /// Kernel user interface device (see [`netlink(7)`](https://man7.org/linux/man-pages/man7/netlink.7.html)) 803da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 813da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 823da5c369Sopenharmony_ci Netlink = libc::AF_NETLINK, 833da5c369Sopenharmony_ci /// Low level packet interface (see [`packet(7)`](https://man7.org/linux/man-pages/man7/packet.7.html)) 843da5c369Sopenharmony_ci #[cfg(any( 853da5c369Sopenharmony_ci target_os = "android", 863da5c369Sopenharmony_ci target_os = "linux", 873da5c369Sopenharmony_ci target_os = "illumos", 883da5c369Sopenharmony_ci target_os = "fuchsia", 893da5c369Sopenharmony_ci target_os = "solaris" 903da5c369Sopenharmony_ci ))] 913da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 923da5c369Sopenharmony_ci Packet = libc::AF_PACKET, 933da5c369Sopenharmony_ci /// KEXT Controls and Notifications 943da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 953da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 963da5c369Sopenharmony_ci System = libc::AF_SYSTEM, 973da5c369Sopenharmony_ci /// Amateur radio AX.25 protocol 983da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 993da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1003da5c369Sopenharmony_ci Ax25 = libc::AF_AX25, 1013da5c369Sopenharmony_ci /// IPX - Novell protocols 1023da5c369Sopenharmony_ci Ipx = libc::AF_IPX, 1033da5c369Sopenharmony_ci /// AppleTalk 1043da5c369Sopenharmony_ci AppleTalk = libc::AF_APPLETALK, 1053da5c369Sopenharmony_ci /// AX.25 packet layer protocol. 1063da5c369Sopenharmony_ci /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/)) 1073da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1083da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1093da5c369Sopenharmony_ci NetRom = libc::AF_NETROM, 1103da5c369Sopenharmony_ci /// Can't be used for creating sockets; mostly used for bridge 1113da5c369Sopenharmony_ci /// links in 1123da5c369Sopenharmony_ci /// [rtnetlink(7)](https://man7.org/linux/man-pages/man7/rtnetlink.7.html) 1133da5c369Sopenharmony_ci /// protocol commands. 1143da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1153da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1163da5c369Sopenharmony_ci Bridge = libc::AF_BRIDGE, 1173da5c369Sopenharmony_ci /// Access to raw ATM PVCs 1183da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1193da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1203da5c369Sopenharmony_ci AtmPvc = libc::AF_ATMPVC, 1213da5c369Sopenharmony_ci /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](https://man7.org/linux/man-pages/man7/x25.7.html)) 1223da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1233da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1243da5c369Sopenharmony_ci X25 = libc::AF_X25, 1253da5c369Sopenharmony_ci /// RATS (Radio Amateur Telecommunications Society) Open 1263da5c369Sopenharmony_ci /// Systems environment (ROSE) AX.25 packet layer protocol. 1273da5c369Sopenharmony_ci /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/)) 1283da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1293da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1303da5c369Sopenharmony_ci Rose = libc::AF_ROSE, 1313da5c369Sopenharmony_ci /// DECet protocol sockets. 1323da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 1333da5c369Sopenharmony_ci Decnet = libc::AF_DECnet, 1343da5c369Sopenharmony_ci /// Reserved for "802.2LLC project"; never used. 1353da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1363da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1373da5c369Sopenharmony_ci NetBeui = libc::AF_NETBEUI, 1383da5c369Sopenharmony_ci /// This was a short-lived (between Linux 2.1.30 and 1393da5c369Sopenharmony_ci /// 2.1.99pre2) protocol family for firewall upcalls. 1403da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1413da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1423da5c369Sopenharmony_ci Security = libc::AF_SECURITY, 1433da5c369Sopenharmony_ci /// Key management protocol. 1443da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1453da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1463da5c369Sopenharmony_ci Key = libc::AF_KEY, 1473da5c369Sopenharmony_ci #[allow(missing_docs)] // Not documented anywhere that I can find 1483da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1493da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1503da5c369Sopenharmony_ci Ash = libc::AF_ASH, 1513da5c369Sopenharmony_ci /// Acorn Econet protocol 1523da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1533da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1543da5c369Sopenharmony_ci Econet = libc::AF_ECONET, 1553da5c369Sopenharmony_ci /// Access to ATM Switched Virtual Circuits 1563da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1573da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1583da5c369Sopenharmony_ci AtmSvc = libc::AF_ATMSVC, 1593da5c369Sopenharmony_ci /// Reliable Datagram Sockets (RDS) protocol 1603da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1613da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1623da5c369Sopenharmony_ci Rds = libc::AF_RDS, 1633da5c369Sopenharmony_ci /// IBM SNA 1643da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 1653da5c369Sopenharmony_ci Sna = libc::AF_SNA, 1663da5c369Sopenharmony_ci /// Socket interface over IrDA 1673da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1683da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1693da5c369Sopenharmony_ci Irda = libc::AF_IRDA, 1703da5c369Sopenharmony_ci /// Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE) 1713da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1723da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1733da5c369Sopenharmony_ci Pppox = libc::AF_PPPOX, 1743da5c369Sopenharmony_ci /// Legacy protocol for wide area network (WAN) connectivity that was used 1753da5c369Sopenharmony_ci /// by Sangoma WAN cards 1763da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1773da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1783da5c369Sopenharmony_ci Wanpipe = libc::AF_WANPIPE, 1793da5c369Sopenharmony_ci /// Logical link control (IEEE 802.2 LLC) protocol 1803da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1813da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1823da5c369Sopenharmony_ci Llc = libc::AF_LLC, 1833da5c369Sopenharmony_ci /// InfiniBand native addressing 1843da5c369Sopenharmony_ci #[cfg(all(target_os = "linux", not(target_env = "uclibc")))] 1853da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1863da5c369Sopenharmony_ci Ib = libc::AF_IB, 1873da5c369Sopenharmony_ci /// Multiprotocol Label Switching 1883da5c369Sopenharmony_ci #[cfg(all(target_os = "linux", not(target_env = "uclibc")))] 1893da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1903da5c369Sopenharmony_ci Mpls = libc::AF_MPLS, 1913da5c369Sopenharmony_ci /// Controller Area Network automotive bus protocol 1923da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1933da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1943da5c369Sopenharmony_ci Can = libc::AF_CAN, 1953da5c369Sopenharmony_ci /// TIPC, "cluster domain sockets" protocol 1963da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 1973da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1983da5c369Sopenharmony_ci Tipc = libc::AF_TIPC, 1993da5c369Sopenharmony_ci /// Bluetooth low-level socket protocol 2003da5c369Sopenharmony_ci #[cfg(not(any( 2013da5c369Sopenharmony_ci target_os = "illumos", 2023da5c369Sopenharmony_ci target_os = "ios", 2033da5c369Sopenharmony_ci target_os = "macos", 2043da5c369Sopenharmony_ci target_os = "solaris" 2053da5c369Sopenharmony_ci )))] 2063da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2073da5c369Sopenharmony_ci Bluetooth = libc::AF_BLUETOOTH, 2083da5c369Sopenharmony_ci /// IUCV (inter-user communication vehicle) z/VM protocol for 2093da5c369Sopenharmony_ci /// hypervisor-guest interaction 2103da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2113da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2123da5c369Sopenharmony_ci Iucv = libc::AF_IUCV, 2133da5c369Sopenharmony_ci /// Rx, Andrew File System remote procedure call protocol 2143da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2153da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2163da5c369Sopenharmony_ci RxRpc = libc::AF_RXRPC, 2173da5c369Sopenharmony_ci /// New "modular ISDN" driver interface protocol 2183da5c369Sopenharmony_ci #[cfg(not(any( 2193da5c369Sopenharmony_ci target_os = "illumos", 2203da5c369Sopenharmony_ci target_os = "solaris", 2213da5c369Sopenharmony_ci target_os = "haiku" 2223da5c369Sopenharmony_ci )))] 2233da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2243da5c369Sopenharmony_ci Isdn = libc::AF_ISDN, 2253da5c369Sopenharmony_ci /// Nokia cellular modem IPC/RPC interface 2263da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2273da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2283da5c369Sopenharmony_ci Phonet = libc::AF_PHONET, 2293da5c369Sopenharmony_ci /// IEEE 802.15.4 WPAN (wireless personal area network) raw packet protocol 2303da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2313da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2323da5c369Sopenharmony_ci Ieee802154 = libc::AF_IEEE802154, 2333da5c369Sopenharmony_ci /// Ericsson's Communication CPU to Application CPU interface (CAIF) 2343da5c369Sopenharmony_ci /// protocol. 2353da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2363da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2373da5c369Sopenharmony_ci Caif = libc::AF_CAIF, 2383da5c369Sopenharmony_ci /// Interface to kernel crypto API 2393da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2403da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2413da5c369Sopenharmony_ci Alg = libc::AF_ALG, 2423da5c369Sopenharmony_ci /// Near field communication 2433da5c369Sopenharmony_ci #[cfg(target_os = "linux")] 2443da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2453da5c369Sopenharmony_ci Nfc = libc::AF_NFC, 2463da5c369Sopenharmony_ci /// VMWare VSockets protocol for hypervisor-guest interaction. 2473da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 2483da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2493da5c369Sopenharmony_ci Vsock = libc::AF_VSOCK, 2503da5c369Sopenharmony_ci /// ARPANet IMP addresses 2513da5c369Sopenharmony_ci #[cfg(any( 2523da5c369Sopenharmony_ci target_os = "dragonfly", 2533da5c369Sopenharmony_ci target_os = "freebsd", 2543da5c369Sopenharmony_ci target_os = "ios", 2553da5c369Sopenharmony_ci target_os = "macos", 2563da5c369Sopenharmony_ci target_os = "netbsd", 2573da5c369Sopenharmony_ci target_os = "openbsd" 2583da5c369Sopenharmony_ci ))] 2593da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2603da5c369Sopenharmony_ci ImpLink = libc::AF_IMPLINK, 2613da5c369Sopenharmony_ci /// PUP protocols, e.g. BSP 2623da5c369Sopenharmony_ci #[cfg(any( 2633da5c369Sopenharmony_ci target_os = "dragonfly", 2643da5c369Sopenharmony_ci target_os = "freebsd", 2653da5c369Sopenharmony_ci target_os = "ios", 2663da5c369Sopenharmony_ci target_os = "macos", 2673da5c369Sopenharmony_ci target_os = "netbsd", 2683da5c369Sopenharmony_ci target_os = "openbsd" 2693da5c369Sopenharmony_ci ))] 2703da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2713da5c369Sopenharmony_ci Pup = libc::AF_PUP, 2723da5c369Sopenharmony_ci /// MIT CHAOS protocols 2733da5c369Sopenharmony_ci #[cfg(any( 2743da5c369Sopenharmony_ci target_os = "dragonfly", 2753da5c369Sopenharmony_ci target_os = "freebsd", 2763da5c369Sopenharmony_ci target_os = "ios", 2773da5c369Sopenharmony_ci target_os = "macos", 2783da5c369Sopenharmony_ci target_os = "netbsd", 2793da5c369Sopenharmony_ci target_os = "openbsd" 2803da5c369Sopenharmony_ci ))] 2813da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2823da5c369Sopenharmony_ci Chaos = libc::AF_CHAOS, 2833da5c369Sopenharmony_ci /// Novell and Xerox protocol 2843da5c369Sopenharmony_ci #[cfg(any( 2853da5c369Sopenharmony_ci target_os = "ios", 2863da5c369Sopenharmony_ci target_os = "macos", 2873da5c369Sopenharmony_ci target_os = "netbsd", 2883da5c369Sopenharmony_ci target_os = "openbsd" 2893da5c369Sopenharmony_ci ))] 2903da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 2913da5c369Sopenharmony_ci Ns = libc::AF_NS, 2923da5c369Sopenharmony_ci #[allow(missing_docs)] // Not documented anywhere that I can find 2933da5c369Sopenharmony_ci #[cfg(any( 2943da5c369Sopenharmony_ci target_os = "dragonfly", 2953da5c369Sopenharmony_ci target_os = "freebsd", 2963da5c369Sopenharmony_ci target_os = "ios", 2973da5c369Sopenharmony_ci target_os = "macos", 2983da5c369Sopenharmony_ci target_os = "netbsd", 2993da5c369Sopenharmony_ci target_os = "openbsd" 3003da5c369Sopenharmony_ci ))] 3013da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3023da5c369Sopenharmony_ci Iso = libc::AF_ISO, 3033da5c369Sopenharmony_ci /// Bell Labs virtual circuit switch ? 3043da5c369Sopenharmony_ci #[cfg(any( 3053da5c369Sopenharmony_ci target_os = "dragonfly", 3063da5c369Sopenharmony_ci target_os = "freebsd", 3073da5c369Sopenharmony_ci target_os = "ios", 3083da5c369Sopenharmony_ci target_os = "macos", 3093da5c369Sopenharmony_ci target_os = "netbsd", 3103da5c369Sopenharmony_ci target_os = "openbsd" 3113da5c369Sopenharmony_ci ))] 3123da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3133da5c369Sopenharmony_ci Datakit = libc::AF_DATAKIT, 3143da5c369Sopenharmony_ci /// CCITT protocols, X.25 etc 3153da5c369Sopenharmony_ci #[cfg(any( 3163da5c369Sopenharmony_ci target_os = "dragonfly", 3173da5c369Sopenharmony_ci target_os = "freebsd", 3183da5c369Sopenharmony_ci target_os = "ios", 3193da5c369Sopenharmony_ci target_os = "macos", 3203da5c369Sopenharmony_ci target_os = "netbsd", 3213da5c369Sopenharmony_ci target_os = "openbsd" 3223da5c369Sopenharmony_ci ))] 3233da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3243da5c369Sopenharmony_ci Ccitt = libc::AF_CCITT, 3253da5c369Sopenharmony_ci /// DEC Direct data link interface 3263da5c369Sopenharmony_ci #[cfg(any( 3273da5c369Sopenharmony_ci target_os = "dragonfly", 3283da5c369Sopenharmony_ci target_os = "freebsd", 3293da5c369Sopenharmony_ci target_os = "ios", 3303da5c369Sopenharmony_ci target_os = "macos", 3313da5c369Sopenharmony_ci target_os = "netbsd", 3323da5c369Sopenharmony_ci target_os = "openbsd" 3333da5c369Sopenharmony_ci ))] 3343da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3353da5c369Sopenharmony_ci Dli = libc::AF_DLI, 3363da5c369Sopenharmony_ci #[allow(missing_docs)] // Not documented anywhere that I can find 3373da5c369Sopenharmony_ci #[cfg(any( 3383da5c369Sopenharmony_ci target_os = "dragonfly", 3393da5c369Sopenharmony_ci target_os = "freebsd", 3403da5c369Sopenharmony_ci target_os = "ios", 3413da5c369Sopenharmony_ci target_os = "macos", 3423da5c369Sopenharmony_ci target_os = "netbsd", 3433da5c369Sopenharmony_ci target_os = "openbsd" 3443da5c369Sopenharmony_ci ))] 3453da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3463da5c369Sopenharmony_ci Lat = libc::AF_LAT, 3473da5c369Sopenharmony_ci /// NSC Hyperchannel 3483da5c369Sopenharmony_ci #[cfg(any( 3493da5c369Sopenharmony_ci target_os = "dragonfly", 3503da5c369Sopenharmony_ci target_os = "freebsd", 3513da5c369Sopenharmony_ci target_os = "ios", 3523da5c369Sopenharmony_ci target_os = "macos", 3533da5c369Sopenharmony_ci target_os = "netbsd", 3543da5c369Sopenharmony_ci target_os = "openbsd" 3553da5c369Sopenharmony_ci ))] 3563da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3573da5c369Sopenharmony_ci Hylink = libc::AF_HYLINK, 3583da5c369Sopenharmony_ci /// Link layer interface 3593da5c369Sopenharmony_ci #[cfg(any( 3603da5c369Sopenharmony_ci target_os = "dragonfly", 3613da5c369Sopenharmony_ci target_os = "freebsd", 3623da5c369Sopenharmony_ci target_os = "ios", 3633da5c369Sopenharmony_ci target_os = "macos", 3643da5c369Sopenharmony_ci target_os = "illumos", 3653da5c369Sopenharmony_ci target_os = "netbsd", 3663da5c369Sopenharmony_ci target_os = "openbsd" 3673da5c369Sopenharmony_ci ))] 3683da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3693da5c369Sopenharmony_ci Link = libc::AF_LINK, 3703da5c369Sopenharmony_ci /// connection-oriented IP, aka ST II 3713da5c369Sopenharmony_ci #[cfg(any( 3723da5c369Sopenharmony_ci target_os = "dragonfly", 3733da5c369Sopenharmony_ci target_os = "freebsd", 3743da5c369Sopenharmony_ci target_os = "ios", 3753da5c369Sopenharmony_ci target_os = "macos", 3763da5c369Sopenharmony_ci target_os = "netbsd", 3773da5c369Sopenharmony_ci target_os = "openbsd" 3783da5c369Sopenharmony_ci ))] 3793da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3803da5c369Sopenharmony_ci Coip = libc::AF_COIP, 3813da5c369Sopenharmony_ci /// Computer Network Technology 3823da5c369Sopenharmony_ci #[cfg(any( 3833da5c369Sopenharmony_ci target_os = "dragonfly", 3843da5c369Sopenharmony_ci target_os = "freebsd", 3853da5c369Sopenharmony_ci target_os = "ios", 3863da5c369Sopenharmony_ci target_os = "macos", 3873da5c369Sopenharmony_ci target_os = "netbsd", 3883da5c369Sopenharmony_ci target_os = "openbsd" 3893da5c369Sopenharmony_ci ))] 3903da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 3913da5c369Sopenharmony_ci Cnt = libc::AF_CNT, 3923da5c369Sopenharmony_ci /// Native ATM access 3933da5c369Sopenharmony_ci #[cfg(any( 3943da5c369Sopenharmony_ci target_os = "dragonfly", 3953da5c369Sopenharmony_ci target_os = "freebsd", 3963da5c369Sopenharmony_ci target_os = "ios", 3973da5c369Sopenharmony_ci target_os = "macos", 3983da5c369Sopenharmony_ci target_os = "netbsd", 3993da5c369Sopenharmony_ci target_os = "openbsd" 4003da5c369Sopenharmony_ci ))] 4013da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 4023da5c369Sopenharmony_ci Natm = libc::AF_NATM, 4033da5c369Sopenharmony_ci /// Unspecified address family, (see [`getaddrinfo(3)`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html)) 4043da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 4053da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 4063da5c369Sopenharmony_ci Unspec = libc::AF_UNSPEC, 4073da5c369Sopenharmony_ci} 4083da5c369Sopenharmony_ci 4093da5c369Sopenharmony_ciimpl AddressFamily { 4103da5c369Sopenharmony_ci /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from 4113da5c369Sopenharmony_ci /// the `sa_family` field of a `sockaddr`. 4123da5c369Sopenharmony_ci /// 4133da5c369Sopenharmony_ci /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet 4143da5c369Sopenharmony_ci /// and System. Returns None for unsupported or unknown address families. 4153da5c369Sopenharmony_ci pub const fn from_i32(family: i32) -> Option<AddressFamily> { 4163da5c369Sopenharmony_ci match family { 4173da5c369Sopenharmony_ci libc::AF_UNIX => Some(AddressFamily::Unix), 4183da5c369Sopenharmony_ci libc::AF_INET => Some(AddressFamily::Inet), 4193da5c369Sopenharmony_ci libc::AF_INET6 => Some(AddressFamily::Inet6), 4203da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 4213da5c369Sopenharmony_ci libc::AF_NETLINK => Some(AddressFamily::Netlink), 4223da5c369Sopenharmony_ci #[cfg(any(target_os = "macos", target_os = "macos"))] 4233da5c369Sopenharmony_ci libc::AF_SYSTEM => Some(AddressFamily::System), 4243da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 4253da5c369Sopenharmony_ci libc::AF_PACKET => Some(AddressFamily::Packet), 4263da5c369Sopenharmony_ci #[cfg(any( 4273da5c369Sopenharmony_ci target_os = "dragonfly", 4283da5c369Sopenharmony_ci target_os = "freebsd", 4293da5c369Sopenharmony_ci target_os = "ios", 4303da5c369Sopenharmony_ci target_os = "macos", 4313da5c369Sopenharmony_ci target_os = "netbsd", 4323da5c369Sopenharmony_ci target_os = "illumos", 4333da5c369Sopenharmony_ci target_os = "openbsd" 4343da5c369Sopenharmony_ci ))] 4353da5c369Sopenharmony_ci libc::AF_LINK => Some(AddressFamily::Link), 4363da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 4373da5c369Sopenharmony_ci libc::AF_VSOCK => Some(AddressFamily::Vsock), 4383da5c369Sopenharmony_ci _ => None, 4393da5c369Sopenharmony_ci } 4403da5c369Sopenharmony_ci } 4413da5c369Sopenharmony_ci} 4423da5c369Sopenharmony_ci 4433da5c369Sopenharmony_cifeature! { 4443da5c369Sopenharmony_ci#![feature = "net"] 4453da5c369Sopenharmony_ci 4463da5c369Sopenharmony_ci#[deprecated( 4473da5c369Sopenharmony_ci since = "0.24.0", 4483da5c369Sopenharmony_ci note = "use SockaddrIn, SockaddrIn6, or SockaddrStorage instead" 4493da5c369Sopenharmony_ci)] 4503da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 4513da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 4523da5c369Sopenharmony_cipub enum InetAddr { 4533da5c369Sopenharmony_ci V4(libc::sockaddr_in), 4543da5c369Sopenharmony_ci V6(libc::sockaddr_in6), 4553da5c369Sopenharmony_ci} 4563da5c369Sopenharmony_ci 4573da5c369Sopenharmony_ci#[allow(missing_docs)] // It's deprecated anyway 4583da5c369Sopenharmony_ci#[allow(deprecated)] 4593da5c369Sopenharmony_ciimpl InetAddr { 4603da5c369Sopenharmony_ci #[allow(clippy::needless_update)] // It isn't needless on all OSes 4613da5c369Sopenharmony_ci pub fn from_std(std: &net::SocketAddr) -> InetAddr { 4623da5c369Sopenharmony_ci match *std { 4633da5c369Sopenharmony_ci net::SocketAddr::V4(ref addr) => { 4643da5c369Sopenharmony_ci InetAddr::V4(libc::sockaddr_in { 4653da5c369Sopenharmony_ci #[cfg(any(target_os = "dragonfly", target_os = "freebsd", 4663da5c369Sopenharmony_ci target_os = "haiku", target_os = "hermit", 4673da5c369Sopenharmony_ci target_os = "ios", target_os = "macos", 4683da5c369Sopenharmony_ci target_os = "netbsd", target_os = "openbsd"))] 4693da5c369Sopenharmony_ci sin_len: mem::size_of::<libc::sockaddr_in>() as u8, 4703da5c369Sopenharmony_ci sin_family: AddressFamily::Inet as sa_family_t, 4713da5c369Sopenharmony_ci sin_port: addr.port().to_be(), // network byte order 4723da5c369Sopenharmony_ci sin_addr: Ipv4Addr::from_std(addr.ip()).0, 4733da5c369Sopenharmony_ci .. unsafe { mem::zeroed() } 4743da5c369Sopenharmony_ci }) 4753da5c369Sopenharmony_ci } 4763da5c369Sopenharmony_ci net::SocketAddr::V6(ref addr) => { 4773da5c369Sopenharmony_ci InetAddr::V6(libc::sockaddr_in6 { 4783da5c369Sopenharmony_ci #[cfg(any(target_os = "dragonfly", target_os = "freebsd", 4793da5c369Sopenharmony_ci target_os = "haiku", target_os = "hermit", 4803da5c369Sopenharmony_ci target_os = "ios", target_os = "macos", 4813da5c369Sopenharmony_ci target_os = "netbsd", target_os = "openbsd"))] 4823da5c369Sopenharmony_ci sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8, 4833da5c369Sopenharmony_ci sin6_family: AddressFamily::Inet6 as sa_family_t, 4843da5c369Sopenharmony_ci sin6_port: addr.port().to_be(), // network byte order 4853da5c369Sopenharmony_ci sin6_addr: Ipv6Addr::from_std(addr.ip()).0, 4863da5c369Sopenharmony_ci sin6_flowinfo: addr.flowinfo(), // host byte order 4873da5c369Sopenharmony_ci sin6_scope_id: addr.scope_id(), // host byte order 4883da5c369Sopenharmony_ci .. unsafe { mem::zeroed() } 4893da5c369Sopenharmony_ci }) 4903da5c369Sopenharmony_ci } 4913da5c369Sopenharmony_ci } 4923da5c369Sopenharmony_ci } 4933da5c369Sopenharmony_ci 4943da5c369Sopenharmony_ci #[allow(clippy::needless_update)] // It isn't needless on all OSes 4953da5c369Sopenharmony_ci pub fn new(ip: IpAddr, port: u16) -> InetAddr { 4963da5c369Sopenharmony_ci match ip { 4973da5c369Sopenharmony_ci IpAddr::V4(ref ip) => { 4983da5c369Sopenharmony_ci InetAddr::V4(libc::sockaddr_in { 4993da5c369Sopenharmony_ci sin_family: AddressFamily::Inet as sa_family_t, 5003da5c369Sopenharmony_ci sin_port: port.to_be(), 5013da5c369Sopenharmony_ci sin_addr: ip.0, 5023da5c369Sopenharmony_ci .. unsafe { mem::zeroed() } 5033da5c369Sopenharmony_ci }) 5043da5c369Sopenharmony_ci } 5053da5c369Sopenharmony_ci IpAddr::V6(ref ip) => { 5063da5c369Sopenharmony_ci InetAddr::V6(libc::sockaddr_in6 { 5073da5c369Sopenharmony_ci sin6_family: AddressFamily::Inet6 as sa_family_t, 5083da5c369Sopenharmony_ci sin6_port: port.to_be(), 5093da5c369Sopenharmony_ci sin6_addr: ip.0, 5103da5c369Sopenharmony_ci .. unsafe { mem::zeroed() } 5113da5c369Sopenharmony_ci }) 5123da5c369Sopenharmony_ci } 5133da5c369Sopenharmony_ci } 5143da5c369Sopenharmony_ci } 5153da5c369Sopenharmony_ci /// Gets the IP address associated with this socket address. 5163da5c369Sopenharmony_ci pub const fn ip(&self) -> IpAddr { 5173da5c369Sopenharmony_ci match *self { 5183da5c369Sopenharmony_ci InetAddr::V4(ref sa) => IpAddr::V4(Ipv4Addr(sa.sin_addr)), 5193da5c369Sopenharmony_ci InetAddr::V6(ref sa) => IpAddr::V6(Ipv6Addr(sa.sin6_addr)), 5203da5c369Sopenharmony_ci } 5213da5c369Sopenharmony_ci } 5223da5c369Sopenharmony_ci 5233da5c369Sopenharmony_ci /// Gets the port number associated with this socket address 5243da5c369Sopenharmony_ci pub const fn port(&self) -> u16 { 5253da5c369Sopenharmony_ci match *self { 5263da5c369Sopenharmony_ci InetAddr::V6(ref sa) => u16::from_be(sa.sin6_port), 5273da5c369Sopenharmony_ci InetAddr::V4(ref sa) => u16::from_be(sa.sin_port), 5283da5c369Sopenharmony_ci } 5293da5c369Sopenharmony_ci } 5303da5c369Sopenharmony_ci 5313da5c369Sopenharmony_ci pub fn to_std(&self) -> net::SocketAddr { 5323da5c369Sopenharmony_ci match *self { 5333da5c369Sopenharmony_ci InetAddr::V4(ref sa) => net::SocketAddr::V4( 5343da5c369Sopenharmony_ci net::SocketAddrV4::new( 5353da5c369Sopenharmony_ci Ipv4Addr(sa.sin_addr).to_std(), 5363da5c369Sopenharmony_ci self.port())), 5373da5c369Sopenharmony_ci InetAddr::V6(ref sa) => net::SocketAddr::V6( 5383da5c369Sopenharmony_ci net::SocketAddrV6::new( 5393da5c369Sopenharmony_ci Ipv6Addr(sa.sin6_addr).to_std(), 5403da5c369Sopenharmony_ci self.port(), 5413da5c369Sopenharmony_ci sa.sin6_flowinfo, 5423da5c369Sopenharmony_ci sa.sin6_scope_id)), 5433da5c369Sopenharmony_ci } 5443da5c369Sopenharmony_ci } 5453da5c369Sopenharmony_ci 5463da5c369Sopenharmony_ci #[deprecated(since = "0.23.0", note = "use .to_string() instead")] 5473da5c369Sopenharmony_ci pub fn to_str(&self) -> String { 5483da5c369Sopenharmony_ci format!("{}", self) 5493da5c369Sopenharmony_ci } 5503da5c369Sopenharmony_ci} 5513da5c369Sopenharmony_ci 5523da5c369Sopenharmony_ci#[allow(deprecated)] 5533da5c369Sopenharmony_ciimpl fmt::Display for InetAddr { 5543da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 5553da5c369Sopenharmony_ci match *self { 5563da5c369Sopenharmony_ci InetAddr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()), 5573da5c369Sopenharmony_ci InetAddr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()), 5583da5c369Sopenharmony_ci } 5593da5c369Sopenharmony_ci } 5603da5c369Sopenharmony_ci} 5613da5c369Sopenharmony_ci 5623da5c369Sopenharmony_ci/* 5633da5c369Sopenharmony_ci * 5643da5c369Sopenharmony_ci * ===== IpAddr ===== 5653da5c369Sopenharmony_ci * 5663da5c369Sopenharmony_ci */ 5673da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 5683da5c369Sopenharmony_ci#[allow(deprecated)] 5693da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 5703da5c369Sopenharmony_ci#[deprecated( 5713da5c369Sopenharmony_ci since = "0.24.0", 5723da5c369Sopenharmony_ci note = "Use std::net::IpAddr instead" 5733da5c369Sopenharmony_ci)] 5743da5c369Sopenharmony_cipub enum IpAddr { 5753da5c369Sopenharmony_ci V4(Ipv4Addr), 5763da5c369Sopenharmony_ci V6(Ipv6Addr), 5773da5c369Sopenharmony_ci} 5783da5c369Sopenharmony_ci 5793da5c369Sopenharmony_ci#[allow(deprecated)] 5803da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 5813da5c369Sopenharmony_ciimpl IpAddr { 5823da5c369Sopenharmony_ci /// Create a new IpAddr that contains an IPv4 address. 5833da5c369Sopenharmony_ci /// 5843da5c369Sopenharmony_ci /// The result will represent the IP address a.b.c.d 5853da5c369Sopenharmony_ci pub const fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr { 5863da5c369Sopenharmony_ci IpAddr::V4(Ipv4Addr::new(a, b, c, d)) 5873da5c369Sopenharmony_ci } 5883da5c369Sopenharmony_ci 5893da5c369Sopenharmony_ci /// Create a new IpAddr that contains an IPv6 address. 5903da5c369Sopenharmony_ci /// 5913da5c369Sopenharmony_ci /// The result will represent the IP address a:b:c:d:e:f 5923da5c369Sopenharmony_ci #[allow(clippy::many_single_char_names)] 5933da5c369Sopenharmony_ci #[allow(clippy::too_many_arguments)] 5943da5c369Sopenharmony_ci pub const fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr { 5953da5c369Sopenharmony_ci IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h)) 5963da5c369Sopenharmony_ci } 5973da5c369Sopenharmony_ci 5983da5c369Sopenharmony_ci pub fn from_std(std: &net::IpAddr) -> IpAddr { 5993da5c369Sopenharmony_ci match *std { 6003da5c369Sopenharmony_ci net::IpAddr::V4(ref std) => IpAddr::V4(Ipv4Addr::from_std(std)), 6013da5c369Sopenharmony_ci net::IpAddr::V6(ref std) => IpAddr::V6(Ipv6Addr::from_std(std)), 6023da5c369Sopenharmony_ci } 6033da5c369Sopenharmony_ci } 6043da5c369Sopenharmony_ci 6053da5c369Sopenharmony_ci pub const fn to_std(&self) -> net::IpAddr { 6063da5c369Sopenharmony_ci match *self { 6073da5c369Sopenharmony_ci IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()), 6083da5c369Sopenharmony_ci IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()), 6093da5c369Sopenharmony_ci } 6103da5c369Sopenharmony_ci } 6113da5c369Sopenharmony_ci} 6123da5c369Sopenharmony_ci 6133da5c369Sopenharmony_ci#[allow(deprecated)] 6143da5c369Sopenharmony_ciimpl fmt::Display for IpAddr { 6153da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 6163da5c369Sopenharmony_ci match *self { 6173da5c369Sopenharmony_ci IpAddr::V4(ref v4) => v4.fmt(f), 6183da5c369Sopenharmony_ci IpAddr::V6(ref v6) => v6.fmt(f) 6193da5c369Sopenharmony_ci } 6203da5c369Sopenharmony_ci } 6213da5c369Sopenharmony_ci} 6223da5c369Sopenharmony_ci 6233da5c369Sopenharmony_ci/* 6243da5c369Sopenharmony_ci * 6253da5c369Sopenharmony_ci * ===== Ipv4Addr ===== 6263da5c369Sopenharmony_ci * 6273da5c369Sopenharmony_ci */ 6283da5c369Sopenharmony_ci 6293da5c369Sopenharmony_ci#[deprecated( 6303da5c369Sopenharmony_ci since = "0.24.0", 6313da5c369Sopenharmony_ci note = "Use std::net::Ipv4Addr instead" 6323da5c369Sopenharmony_ci)] 6333da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 6343da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 6353da5c369Sopenharmony_ci#[repr(transparent)] 6363da5c369Sopenharmony_cipub struct Ipv4Addr(pub libc::in_addr); 6373da5c369Sopenharmony_ci 6383da5c369Sopenharmony_ci#[allow(deprecated)] 6393da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 6403da5c369Sopenharmony_ciimpl Ipv4Addr { 6413da5c369Sopenharmony_ci #[allow(clippy::identity_op)] // More readable this way 6423da5c369Sopenharmony_ci pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { 6433da5c369Sopenharmony_ci let ip = (((a as u32) << 24) | 6443da5c369Sopenharmony_ci ((b as u32) << 16) | 6453da5c369Sopenharmony_ci ((c as u32) << 8) | 6463da5c369Sopenharmony_ci ((d as u32) << 0)).to_be(); 6473da5c369Sopenharmony_ci 6483da5c369Sopenharmony_ci Ipv4Addr(libc::in_addr { s_addr: ip }) 6493da5c369Sopenharmony_ci } 6503da5c369Sopenharmony_ci 6513da5c369Sopenharmony_ci // Use pass by reference for symmetry with Ipv6Addr::from_std 6523da5c369Sopenharmony_ci #[allow(clippy::trivially_copy_pass_by_ref)] 6533da5c369Sopenharmony_ci pub fn from_std(std: &net::Ipv4Addr) -> Ipv4Addr { 6543da5c369Sopenharmony_ci let bits = std.octets(); 6553da5c369Sopenharmony_ci Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3]) 6563da5c369Sopenharmony_ci } 6573da5c369Sopenharmony_ci 6583da5c369Sopenharmony_ci pub const fn any() -> Ipv4Addr { 6593da5c369Sopenharmony_ci Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY }) 6603da5c369Sopenharmony_ci } 6613da5c369Sopenharmony_ci 6623da5c369Sopenharmony_ci pub const fn octets(self) -> [u8; 4] { 6633da5c369Sopenharmony_ci let bits = u32::from_be(self.0.s_addr); 6643da5c369Sopenharmony_ci [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8] 6653da5c369Sopenharmony_ci } 6663da5c369Sopenharmony_ci 6673da5c369Sopenharmony_ci pub const fn to_std(self) -> net::Ipv4Addr { 6683da5c369Sopenharmony_ci let bits = self.octets(); 6693da5c369Sopenharmony_ci net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3]) 6703da5c369Sopenharmony_ci } 6713da5c369Sopenharmony_ci} 6723da5c369Sopenharmony_ci 6733da5c369Sopenharmony_ci#[allow(deprecated)] 6743da5c369Sopenharmony_ciimpl fmt::Display for Ipv4Addr { 6753da5c369Sopenharmony_ci fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 6763da5c369Sopenharmony_ci let octets = self.octets(); 6773da5c369Sopenharmony_ci write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]) 6783da5c369Sopenharmony_ci } 6793da5c369Sopenharmony_ci} 6803da5c369Sopenharmony_ci 6813da5c369Sopenharmony_ci/* 6823da5c369Sopenharmony_ci * 6833da5c369Sopenharmony_ci * ===== Ipv6Addr ===== 6843da5c369Sopenharmony_ci * 6853da5c369Sopenharmony_ci */ 6863da5c369Sopenharmony_ci 6873da5c369Sopenharmony_ci#[deprecated( 6883da5c369Sopenharmony_ci since = "0.24.0", 6893da5c369Sopenharmony_ci note = "Use std::net::Ipv6Addr instead" 6903da5c369Sopenharmony_ci)] 6913da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 6923da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 6933da5c369Sopenharmony_ci#[repr(transparent)] 6943da5c369Sopenharmony_cipub struct Ipv6Addr(pub libc::in6_addr); 6953da5c369Sopenharmony_ci 6963da5c369Sopenharmony_ci// Note that IPv6 addresses are stored in big endian order on all architectures. 6973da5c369Sopenharmony_ci// See https://tools.ietf.org/html/rfc1700 or consult your favorite search 6983da5c369Sopenharmony_ci// engine. 6993da5c369Sopenharmony_ci 7003da5c369Sopenharmony_cimacro_rules! to_u8_array { 7013da5c369Sopenharmony_ci ($($num:ident),*) => { 7023da5c369Sopenharmony_ci [ $(($num>>8) as u8, ($num&0xff) as u8,)* ] 7033da5c369Sopenharmony_ci } 7043da5c369Sopenharmony_ci} 7053da5c369Sopenharmony_ci 7063da5c369Sopenharmony_cimacro_rules! to_u16_array { 7073da5c369Sopenharmony_ci ($slf:ident, $($first:expr, $second:expr),*) => { 7083da5c369Sopenharmony_ci [$( (($slf.0.s6_addr[$first] as u16) << 8) + $slf.0.s6_addr[$second] as u16,)*] 7093da5c369Sopenharmony_ci } 7103da5c369Sopenharmony_ci} 7113da5c369Sopenharmony_ci 7123da5c369Sopenharmony_ci#[allow(deprecated)] 7133da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 7143da5c369Sopenharmony_ciimpl Ipv6Addr { 7153da5c369Sopenharmony_ci #[allow(clippy::many_single_char_names)] 7163da5c369Sopenharmony_ci #[allow(clippy::too_many_arguments)] 7173da5c369Sopenharmony_ci pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr { 7183da5c369Sopenharmony_ci Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)}) 7193da5c369Sopenharmony_ci } 7203da5c369Sopenharmony_ci 7213da5c369Sopenharmony_ci pub fn from_std(std: &net::Ipv6Addr) -> Ipv6Addr { 7223da5c369Sopenharmony_ci let s = std.segments(); 7233da5c369Sopenharmony_ci Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]) 7243da5c369Sopenharmony_ci } 7253da5c369Sopenharmony_ci 7263da5c369Sopenharmony_ci /// Return the eight 16-bit segments that make up this address 7273da5c369Sopenharmony_ci pub const fn segments(&self) -> [u16; 8] { 7283da5c369Sopenharmony_ci to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) 7293da5c369Sopenharmony_ci } 7303da5c369Sopenharmony_ci 7313da5c369Sopenharmony_ci pub const fn to_std(&self) -> net::Ipv6Addr { 7323da5c369Sopenharmony_ci let s = self.segments(); 7333da5c369Sopenharmony_ci net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]) 7343da5c369Sopenharmony_ci } 7353da5c369Sopenharmony_ci} 7363da5c369Sopenharmony_ci 7373da5c369Sopenharmony_ci#[allow(deprecated)] 7383da5c369Sopenharmony_ciimpl fmt::Display for Ipv6Addr { 7393da5c369Sopenharmony_ci fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 7403da5c369Sopenharmony_ci self.to_std().fmt(fmt) 7413da5c369Sopenharmony_ci } 7423da5c369Sopenharmony_ci} 7433da5c369Sopenharmony_ci} 7443da5c369Sopenharmony_ci 7453da5c369Sopenharmony_ci/// A wrapper around `sockaddr_un`. 7463da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug)] 7473da5c369Sopenharmony_ci#[repr(C)] 7483da5c369Sopenharmony_cipub struct UnixAddr { 7493da5c369Sopenharmony_ci // INVARIANT: sun & sun_len are valid as defined by docs for from_raw_parts 7503da5c369Sopenharmony_ci sun: libc::sockaddr_un, 7513da5c369Sopenharmony_ci /// The length of the valid part of `sun`, including the sun_family field 7523da5c369Sopenharmony_ci /// but excluding any trailing nul. 7533da5c369Sopenharmony_ci // On the BSDs, this field is built into sun 7543da5c369Sopenharmony_ci #[cfg(any( 7553da5c369Sopenharmony_ci target_os = "android", 7563da5c369Sopenharmony_ci target_os = "fuchsia", 7573da5c369Sopenharmony_ci target_os = "illumos", 7583da5c369Sopenharmony_ci target_os = "linux" 7593da5c369Sopenharmony_ci ))] 7603da5c369Sopenharmony_ci sun_len: u8, 7613da5c369Sopenharmony_ci} 7623da5c369Sopenharmony_ci 7633da5c369Sopenharmony_ci// linux man page unix(7) says there are 3 kinds of unix socket: 7643da5c369Sopenharmony_ci// pathname: addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1 7653da5c369Sopenharmony_ci// unnamed: addrlen = sizeof(sa_family_t) 7663da5c369Sopenharmony_ci// abstract: addren > sizeof(sa_family_t), name = sun_path[..(addrlen - sizeof(sa_family_t))] 7673da5c369Sopenharmony_ci// 7683da5c369Sopenharmony_ci// what we call path_len = addrlen - offsetof(struct sockaddr_un, sun_path) 7693da5c369Sopenharmony_ci#[derive(PartialEq, Eq, Hash)] 7703da5c369Sopenharmony_cienum UnixAddrKind<'a> { 7713da5c369Sopenharmony_ci Pathname(&'a Path), 7723da5c369Sopenharmony_ci Unnamed, 7733da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 7743da5c369Sopenharmony_ci Abstract(&'a [u8]), 7753da5c369Sopenharmony_ci} 7763da5c369Sopenharmony_ciimpl<'a> UnixAddrKind<'a> { 7773da5c369Sopenharmony_ci /// Safety: sun & sun_len must be valid 7783da5c369Sopenharmony_ci unsafe fn get(sun: &'a libc::sockaddr_un, sun_len: u8) -> Self { 7793da5c369Sopenharmony_ci assert!(sun_len as usize >= offset_of!(libc::sockaddr_un, sun_path)); 7803da5c369Sopenharmony_ci let path_len = 7813da5c369Sopenharmony_ci sun_len as usize - offset_of!(libc::sockaddr_un, sun_path); 7823da5c369Sopenharmony_ci if path_len == 0 { 7833da5c369Sopenharmony_ci return Self::Unnamed; 7843da5c369Sopenharmony_ci } 7853da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 7863da5c369Sopenharmony_ci if sun.sun_path[0] == 0 { 7873da5c369Sopenharmony_ci let name = slice::from_raw_parts( 7883da5c369Sopenharmony_ci sun.sun_path.as_ptr().add(1) as *const u8, 7893da5c369Sopenharmony_ci path_len - 1, 7903da5c369Sopenharmony_ci ); 7913da5c369Sopenharmony_ci return Self::Abstract(name); 7923da5c369Sopenharmony_ci } 7933da5c369Sopenharmony_ci let pathname = 7943da5c369Sopenharmony_ci slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len); 7953da5c369Sopenharmony_ci if pathname.last() == Some(&0) { 7963da5c369Sopenharmony_ci // A trailing NUL is not considered part of the path, and it does 7973da5c369Sopenharmony_ci // not need to be included in the addrlen passed to functions like 7983da5c369Sopenharmony_ci // bind(). However, Linux adds a trailing NUL, even if one was not 7993da5c369Sopenharmony_ci // originally present, when returning addrs from functions like 8003da5c369Sopenharmony_ci // getsockname() (the BSDs do not do that). So we need to filter 8013da5c369Sopenharmony_ci // out any trailing NUL here, so sockaddrs can round-trip through 8023da5c369Sopenharmony_ci // the kernel and still compare equal. 8033da5c369Sopenharmony_ci Self::Pathname(Path::new(OsStr::from_bytes( 8043da5c369Sopenharmony_ci &pathname[0..pathname.len() - 1], 8053da5c369Sopenharmony_ci ))) 8063da5c369Sopenharmony_ci } else { 8073da5c369Sopenharmony_ci Self::Pathname(Path::new(OsStr::from_bytes(pathname))) 8083da5c369Sopenharmony_ci } 8093da5c369Sopenharmony_ci } 8103da5c369Sopenharmony_ci} 8113da5c369Sopenharmony_ci 8123da5c369Sopenharmony_ciimpl UnixAddr { 8133da5c369Sopenharmony_ci /// Create a new sockaddr_un representing a filesystem path. 8143da5c369Sopenharmony_ci pub fn new<P: ?Sized + NixPath>(path: &P) -> Result<UnixAddr> { 8153da5c369Sopenharmony_ci path.with_nix_path(|cstr| unsafe { 8163da5c369Sopenharmony_ci let mut ret = libc::sockaddr_un { 8173da5c369Sopenharmony_ci sun_family: AddressFamily::Unix as sa_family_t, 8183da5c369Sopenharmony_ci ..mem::zeroed() 8193da5c369Sopenharmony_ci }; 8203da5c369Sopenharmony_ci 8213da5c369Sopenharmony_ci let bytes = cstr.to_bytes(); 8223da5c369Sopenharmony_ci 8233da5c369Sopenharmony_ci if bytes.len() >= ret.sun_path.len() { 8243da5c369Sopenharmony_ci return Err(Errno::ENAMETOOLONG); 8253da5c369Sopenharmony_ci } 8263da5c369Sopenharmony_ci 8273da5c369Sopenharmony_ci let sun_len = (bytes.len() 8283da5c369Sopenharmony_ci + offset_of!(libc::sockaddr_un, sun_path)) 8293da5c369Sopenharmony_ci .try_into() 8303da5c369Sopenharmony_ci .unwrap(); 8313da5c369Sopenharmony_ci 8323da5c369Sopenharmony_ci #[cfg(any( 8333da5c369Sopenharmony_ci target_os = "dragonfly", 8343da5c369Sopenharmony_ci target_os = "freebsd", 8353da5c369Sopenharmony_ci target_os = "ios", 8363da5c369Sopenharmony_ci target_os = "macos", 8373da5c369Sopenharmony_ci target_os = "netbsd", 8383da5c369Sopenharmony_ci target_os = "openbsd" 8393da5c369Sopenharmony_ci ))] 8403da5c369Sopenharmony_ci { 8413da5c369Sopenharmony_ci ret.sun_len = sun_len; 8423da5c369Sopenharmony_ci } 8433da5c369Sopenharmony_ci ptr::copy_nonoverlapping( 8443da5c369Sopenharmony_ci bytes.as_ptr(), 8453da5c369Sopenharmony_ci ret.sun_path.as_mut_ptr() as *mut u8, 8463da5c369Sopenharmony_ci bytes.len(), 8473da5c369Sopenharmony_ci ); 8483da5c369Sopenharmony_ci 8493da5c369Sopenharmony_ci Ok(UnixAddr::from_raw_parts(ret, sun_len)) 8503da5c369Sopenharmony_ci })? 8513da5c369Sopenharmony_ci } 8523da5c369Sopenharmony_ci 8533da5c369Sopenharmony_ci /// Create a new `sockaddr_un` representing an address in the "abstract namespace". 8543da5c369Sopenharmony_ci /// 8553da5c369Sopenharmony_ci /// The leading nul byte for the abstract namespace is automatically added; 8563da5c369Sopenharmony_ci /// thus the input `path` is expected to be the bare name, not NUL-prefixed. 8573da5c369Sopenharmony_ci /// This is a Linux-specific extension, primarily used to allow chrooted 8583da5c369Sopenharmony_ci /// processes to communicate with processes having a different filesystem view. 8593da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 8603da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 8613da5c369Sopenharmony_ci pub fn new_abstract(path: &[u8]) -> Result<UnixAddr> { 8623da5c369Sopenharmony_ci unsafe { 8633da5c369Sopenharmony_ci let mut ret = libc::sockaddr_un { 8643da5c369Sopenharmony_ci sun_family: AddressFamily::Unix as sa_family_t, 8653da5c369Sopenharmony_ci ..mem::zeroed() 8663da5c369Sopenharmony_ci }; 8673da5c369Sopenharmony_ci 8683da5c369Sopenharmony_ci if path.len() >= ret.sun_path.len() { 8693da5c369Sopenharmony_ci return Err(Errno::ENAMETOOLONG); 8703da5c369Sopenharmony_ci } 8713da5c369Sopenharmony_ci let sun_len = 8723da5c369Sopenharmony_ci (path.len() + 1 + offset_of!(libc::sockaddr_un, sun_path)) 8733da5c369Sopenharmony_ci .try_into() 8743da5c369Sopenharmony_ci .unwrap(); 8753da5c369Sopenharmony_ci 8763da5c369Sopenharmony_ci // Abstract addresses are represented by sun_path[0] == 8773da5c369Sopenharmony_ci // b'\0', so copy starting one byte in. 8783da5c369Sopenharmony_ci ptr::copy_nonoverlapping( 8793da5c369Sopenharmony_ci path.as_ptr(), 8803da5c369Sopenharmony_ci ret.sun_path.as_mut_ptr().offset(1) as *mut u8, 8813da5c369Sopenharmony_ci path.len(), 8823da5c369Sopenharmony_ci ); 8833da5c369Sopenharmony_ci 8843da5c369Sopenharmony_ci Ok(UnixAddr::from_raw_parts(ret, sun_len)) 8853da5c369Sopenharmony_ci } 8863da5c369Sopenharmony_ci } 8873da5c369Sopenharmony_ci 8883da5c369Sopenharmony_ci /// Create a new `sockaddr_un` representing an "unnamed" unix socket address. 8893da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 8903da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 8913da5c369Sopenharmony_ci pub fn new_unnamed() -> UnixAddr { 8923da5c369Sopenharmony_ci let ret = libc::sockaddr_un { 8933da5c369Sopenharmony_ci sun_family: AddressFamily::Unix as sa_family_t, 8943da5c369Sopenharmony_ci .. unsafe { mem::zeroed() } 8953da5c369Sopenharmony_ci }; 8963da5c369Sopenharmony_ci 8973da5c369Sopenharmony_ci let sun_len: u8 = offset_of!(libc::sockaddr_un, sun_path).try_into().unwrap(); 8983da5c369Sopenharmony_ci 8993da5c369Sopenharmony_ci unsafe { UnixAddr::from_raw_parts(ret, sun_len) } 9003da5c369Sopenharmony_ci } 9013da5c369Sopenharmony_ci 9023da5c369Sopenharmony_ci /// Create a UnixAddr from a raw `sockaddr_un` struct and a size. `sun_len` 9033da5c369Sopenharmony_ci /// is the size of the valid portion of the struct, excluding any trailing 9043da5c369Sopenharmony_ci /// NUL. 9053da5c369Sopenharmony_ci /// 9063da5c369Sopenharmony_ci /// # Safety 9073da5c369Sopenharmony_ci /// This pair of sockaddr_un & sun_len must be a valid unix addr, which 9083da5c369Sopenharmony_ci /// means: 9093da5c369Sopenharmony_ci /// - sun_len >= offset_of(sockaddr_un, sun_path) 9103da5c369Sopenharmony_ci /// - sun_len <= sockaddr_un.sun_path.len() - offset_of(sockaddr_un, sun_path) 9113da5c369Sopenharmony_ci /// - if this is a unix addr with a pathname, sun.sun_path is a 9123da5c369Sopenharmony_ci /// fs path, not necessarily nul-terminated. 9133da5c369Sopenharmony_ci pub(crate) unsafe fn from_raw_parts( 9143da5c369Sopenharmony_ci sun: libc::sockaddr_un, 9153da5c369Sopenharmony_ci sun_len: u8, 9163da5c369Sopenharmony_ci ) -> UnixAddr { 9173da5c369Sopenharmony_ci cfg_if! { 9183da5c369Sopenharmony_ci if #[cfg(any(target_os = "android", 9193da5c369Sopenharmony_ci target_os = "fuchsia", 9203da5c369Sopenharmony_ci target_os = "illumos", 9213da5c369Sopenharmony_ci target_os = "linux" 9223da5c369Sopenharmony_ci ))] 9233da5c369Sopenharmony_ci { 9243da5c369Sopenharmony_ci UnixAddr { sun, sun_len } 9253da5c369Sopenharmony_ci } else { 9263da5c369Sopenharmony_ci assert_eq!(sun_len, sun.sun_len); 9273da5c369Sopenharmony_ci UnixAddr {sun} 9283da5c369Sopenharmony_ci } 9293da5c369Sopenharmony_ci } 9303da5c369Sopenharmony_ci } 9313da5c369Sopenharmony_ci 9323da5c369Sopenharmony_ci fn kind(&self) -> UnixAddrKind<'_> { 9333da5c369Sopenharmony_ci // SAFETY: our sockaddr is always valid because of the invariant on the struct 9343da5c369Sopenharmony_ci unsafe { UnixAddrKind::get(&self.sun, self.sun_len()) } 9353da5c369Sopenharmony_ci } 9363da5c369Sopenharmony_ci 9373da5c369Sopenharmony_ci /// If this address represents a filesystem path, return that path. 9383da5c369Sopenharmony_ci pub fn path(&self) -> Option<&Path> { 9393da5c369Sopenharmony_ci match self.kind() { 9403da5c369Sopenharmony_ci UnixAddrKind::Pathname(path) => Some(path), 9413da5c369Sopenharmony_ci _ => None, 9423da5c369Sopenharmony_ci } 9433da5c369Sopenharmony_ci } 9443da5c369Sopenharmony_ci 9453da5c369Sopenharmony_ci /// If this address represents an abstract socket, return its name. 9463da5c369Sopenharmony_ci /// 9473da5c369Sopenharmony_ci /// For abstract sockets only the bare name is returned, without the 9483da5c369Sopenharmony_ci /// leading NUL byte. `None` is returned for unnamed or path-backed sockets. 9493da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 9503da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 9513da5c369Sopenharmony_ci pub fn as_abstract(&self) -> Option<&[u8]> { 9523da5c369Sopenharmony_ci match self.kind() { 9533da5c369Sopenharmony_ci UnixAddrKind::Abstract(name) => Some(name), 9543da5c369Sopenharmony_ci _ => None, 9553da5c369Sopenharmony_ci } 9563da5c369Sopenharmony_ci } 9573da5c369Sopenharmony_ci 9583da5c369Sopenharmony_ci /// Check if this address is an "unnamed" unix socket address. 9593da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 9603da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 9613da5c369Sopenharmony_ci #[inline] 9623da5c369Sopenharmony_ci pub fn is_unnamed(&self) -> bool { 9633da5c369Sopenharmony_ci matches!(self.kind(), UnixAddrKind::Unnamed) 9643da5c369Sopenharmony_ci } 9653da5c369Sopenharmony_ci 9663da5c369Sopenharmony_ci /// Returns the addrlen of this socket - `offsetof(struct sockaddr_un, sun_path)` 9673da5c369Sopenharmony_ci #[inline] 9683da5c369Sopenharmony_ci pub fn path_len(&self) -> usize { 9693da5c369Sopenharmony_ci self.sun_len() as usize - offset_of!(libc::sockaddr_un, sun_path) 9703da5c369Sopenharmony_ci } 9713da5c369Sopenharmony_ci /// Returns a pointer to the raw `sockaddr_un` struct 9723da5c369Sopenharmony_ci #[inline] 9733da5c369Sopenharmony_ci pub fn as_ptr(&self) -> *const libc::sockaddr_un { 9743da5c369Sopenharmony_ci &self.sun 9753da5c369Sopenharmony_ci } 9763da5c369Sopenharmony_ci /// Returns a mutable pointer to the raw `sockaddr_un` struct 9773da5c369Sopenharmony_ci #[inline] 9783da5c369Sopenharmony_ci pub fn as_mut_ptr(&mut self) -> *mut libc::sockaddr_un { 9793da5c369Sopenharmony_ci &mut self.sun 9803da5c369Sopenharmony_ci } 9813da5c369Sopenharmony_ci 9823da5c369Sopenharmony_ci fn sun_len(&self) -> u8 { 9833da5c369Sopenharmony_ci cfg_if! { 9843da5c369Sopenharmony_ci if #[cfg(any(target_os = "android", 9853da5c369Sopenharmony_ci target_os = "fuchsia", 9863da5c369Sopenharmony_ci target_os = "illumos", 9873da5c369Sopenharmony_ci target_os = "linux" 9883da5c369Sopenharmony_ci ))] 9893da5c369Sopenharmony_ci { 9903da5c369Sopenharmony_ci self.sun_len 9913da5c369Sopenharmony_ci } else { 9923da5c369Sopenharmony_ci self.sun.sun_len 9933da5c369Sopenharmony_ci } 9943da5c369Sopenharmony_ci } 9953da5c369Sopenharmony_ci } 9963da5c369Sopenharmony_ci} 9973da5c369Sopenharmony_ci 9983da5c369Sopenharmony_ciimpl private::SockaddrLikePriv for UnixAddr {} 9993da5c369Sopenharmony_ciimpl SockaddrLike for UnixAddr { 10003da5c369Sopenharmony_ci #[cfg(any( 10013da5c369Sopenharmony_ci target_os = "android", 10023da5c369Sopenharmony_ci target_os = "fuchsia", 10033da5c369Sopenharmony_ci target_os = "illumos", 10043da5c369Sopenharmony_ci target_os = "linux" 10053da5c369Sopenharmony_ci ))] 10063da5c369Sopenharmony_ci fn len(&self) -> libc::socklen_t { 10073da5c369Sopenharmony_ci self.sun_len.into() 10083da5c369Sopenharmony_ci } 10093da5c369Sopenharmony_ci 10103da5c369Sopenharmony_ci unsafe fn from_raw( 10113da5c369Sopenharmony_ci addr: *const libc::sockaddr, 10123da5c369Sopenharmony_ci len: Option<libc::socklen_t>, 10133da5c369Sopenharmony_ci ) -> Option<Self> 10143da5c369Sopenharmony_ci where 10153da5c369Sopenharmony_ci Self: Sized, 10163da5c369Sopenharmony_ci { 10173da5c369Sopenharmony_ci if let Some(l) = len { 10183da5c369Sopenharmony_ci if (l as usize) < offset_of!(libc::sockaddr_un, sun_path) 10193da5c369Sopenharmony_ci || l > u8::MAX as libc::socklen_t 10203da5c369Sopenharmony_ci { 10213da5c369Sopenharmony_ci return None; 10223da5c369Sopenharmony_ci } 10233da5c369Sopenharmony_ci } 10243da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_UNIX { 10253da5c369Sopenharmony_ci return None; 10263da5c369Sopenharmony_ci } 10273da5c369Sopenharmony_ci let mut su: libc::sockaddr_un = mem::zeroed(); 10283da5c369Sopenharmony_ci let sup = &mut su as *mut libc::sockaddr_un as *mut u8; 10293da5c369Sopenharmony_ci cfg_if! { 10303da5c369Sopenharmony_ci if #[cfg(any(target_os = "android", 10313da5c369Sopenharmony_ci target_os = "fuchsia", 10323da5c369Sopenharmony_ci target_os = "illumos", 10333da5c369Sopenharmony_ci target_os = "linux" 10343da5c369Sopenharmony_ci ))] { 10353da5c369Sopenharmony_ci let su_len = len.unwrap_or( 10363da5c369Sopenharmony_ci mem::size_of::<libc::sockaddr_un>() as libc::socklen_t 10373da5c369Sopenharmony_ci ); 10383da5c369Sopenharmony_ci } else { 10393da5c369Sopenharmony_ci let su_len = len.unwrap_or((*addr).sa_len as libc::socklen_t); 10403da5c369Sopenharmony_ci } 10413da5c369Sopenharmony_ci }; 10423da5c369Sopenharmony_ci ptr::copy(addr as *const u8, sup, su_len as usize); 10433da5c369Sopenharmony_ci Some(Self::from_raw_parts(su, su_len as u8)) 10443da5c369Sopenharmony_ci } 10453da5c369Sopenharmony_ci 10463da5c369Sopenharmony_ci fn size() -> libc::socklen_t 10473da5c369Sopenharmony_ci where 10483da5c369Sopenharmony_ci Self: Sized, 10493da5c369Sopenharmony_ci { 10503da5c369Sopenharmony_ci mem::size_of::<libc::sockaddr_un>() as libc::socklen_t 10513da5c369Sopenharmony_ci } 10523da5c369Sopenharmony_ci} 10533da5c369Sopenharmony_ci 10543da5c369Sopenharmony_ciimpl AsRef<libc::sockaddr_un> for UnixAddr { 10553da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_un { 10563da5c369Sopenharmony_ci &self.sun 10573da5c369Sopenharmony_ci } 10583da5c369Sopenharmony_ci} 10593da5c369Sopenharmony_ci 10603da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 10613da5c369Sopenharmony_cifn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result { 10623da5c369Sopenharmony_ci use fmt::Write; 10633da5c369Sopenharmony_ci f.write_str("@\"")?; 10643da5c369Sopenharmony_ci for &b in abs { 10653da5c369Sopenharmony_ci use fmt::Display; 10663da5c369Sopenharmony_ci char::from(b).escape_default().fmt(f)?; 10673da5c369Sopenharmony_ci } 10683da5c369Sopenharmony_ci f.write_char('"')?; 10693da5c369Sopenharmony_ci Ok(()) 10703da5c369Sopenharmony_ci} 10713da5c369Sopenharmony_ci 10723da5c369Sopenharmony_ciimpl fmt::Display for UnixAddr { 10733da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 10743da5c369Sopenharmony_ci match self.kind() { 10753da5c369Sopenharmony_ci UnixAddrKind::Pathname(path) => path.display().fmt(f), 10763da5c369Sopenharmony_ci UnixAddrKind::Unnamed => f.pad("<unbound UNIX socket>"), 10773da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 10783da5c369Sopenharmony_ci UnixAddrKind::Abstract(name) => fmt_abstract(name, f), 10793da5c369Sopenharmony_ci } 10803da5c369Sopenharmony_ci } 10813da5c369Sopenharmony_ci} 10823da5c369Sopenharmony_ci 10833da5c369Sopenharmony_ciimpl PartialEq for UnixAddr { 10843da5c369Sopenharmony_ci fn eq(&self, other: &UnixAddr) -> bool { 10853da5c369Sopenharmony_ci self.kind() == other.kind() 10863da5c369Sopenharmony_ci } 10873da5c369Sopenharmony_ci} 10883da5c369Sopenharmony_ci 10893da5c369Sopenharmony_ciimpl Eq for UnixAddr {} 10903da5c369Sopenharmony_ci 10913da5c369Sopenharmony_ciimpl Hash for UnixAddr { 10923da5c369Sopenharmony_ci fn hash<H: Hasher>(&self, s: &mut H) { 10933da5c369Sopenharmony_ci self.kind().hash(s) 10943da5c369Sopenharmony_ci } 10953da5c369Sopenharmony_ci} 10963da5c369Sopenharmony_ci 10973da5c369Sopenharmony_ci/// Anything that, in C, can be cast back and forth to `sockaddr`. 10983da5c369Sopenharmony_ci/// 10993da5c369Sopenharmony_ci/// Most implementors also implement `AsRef<libc::XXX>` to access their 11003da5c369Sopenharmony_ci/// inner type read-only. 11013da5c369Sopenharmony_ci#[allow(clippy::len_without_is_empty)] 11023da5c369Sopenharmony_cipub trait SockaddrLike: private::SockaddrLikePriv { 11033da5c369Sopenharmony_ci /// Returns a raw pointer to the inner structure. Useful for FFI. 11043da5c369Sopenharmony_ci fn as_ptr(&self) -> *const libc::sockaddr { 11053da5c369Sopenharmony_ci self as *const Self as *const libc::sockaddr 11063da5c369Sopenharmony_ci } 11073da5c369Sopenharmony_ci 11083da5c369Sopenharmony_ci /// Unsafe constructor from a variable length source 11093da5c369Sopenharmony_ci /// 11103da5c369Sopenharmony_ci /// Some C APIs from provide `len`, and others do not. If it's provided it 11113da5c369Sopenharmony_ci /// will be validated. If not, it will be guessed based on the family. 11123da5c369Sopenharmony_ci /// 11133da5c369Sopenharmony_ci /// # Arguments 11143da5c369Sopenharmony_ci /// 11153da5c369Sopenharmony_ci /// - `addr`: raw pointer to something that can be cast to a 11163da5c369Sopenharmony_ci /// `libc::sockaddr`. For example, `libc::sockaddr_in`, 11173da5c369Sopenharmony_ci /// `libc::sockaddr_in6`, etc. 11183da5c369Sopenharmony_ci /// - `len`: For fixed-width types like `sockaddr_in`, it will be 11193da5c369Sopenharmony_ci /// validated if present and ignored if not. For variable-width 11203da5c369Sopenharmony_ci /// types it is required and must be the total length of valid 11213da5c369Sopenharmony_ci /// data. For example, if `addr` points to a 11223da5c369Sopenharmony_ci /// named `sockaddr_un`, then `len` must be the length of the 11233da5c369Sopenharmony_ci /// structure up to but not including the trailing NUL. 11243da5c369Sopenharmony_ci /// 11253da5c369Sopenharmony_ci /// # Safety 11263da5c369Sopenharmony_ci /// 11273da5c369Sopenharmony_ci /// `addr` must be valid for the specific type of sockaddr. `len`, if 11283da5c369Sopenharmony_ci /// present, must not exceed the length of valid data in `addr`. 11293da5c369Sopenharmony_ci unsafe fn from_raw( 11303da5c369Sopenharmony_ci addr: *const libc::sockaddr, 11313da5c369Sopenharmony_ci len: Option<libc::socklen_t>, 11323da5c369Sopenharmony_ci ) -> Option<Self> 11333da5c369Sopenharmony_ci where 11343da5c369Sopenharmony_ci Self: Sized; 11353da5c369Sopenharmony_ci 11363da5c369Sopenharmony_ci /// Return the address family of this socket 11373da5c369Sopenharmony_ci /// 11383da5c369Sopenharmony_ci /// # Examples 11393da5c369Sopenharmony_ci /// One common use is to match on the family of a union type, like this: 11403da5c369Sopenharmony_ci /// ``` 11413da5c369Sopenharmony_ci /// # use nix::sys::socket::*; 11423da5c369Sopenharmony_ci /// let fd = socket(AddressFamily::Inet, SockType::Stream, 11433da5c369Sopenharmony_ci /// SockFlag::empty(), None).unwrap(); 11443da5c369Sopenharmony_ci /// let ss: SockaddrStorage = getsockname(fd).unwrap(); 11453da5c369Sopenharmony_ci /// match ss.family().unwrap() { 11463da5c369Sopenharmony_ci /// AddressFamily::Inet => println!("{}", ss.as_sockaddr_in().unwrap()), 11473da5c369Sopenharmony_ci /// AddressFamily::Inet6 => println!("{}", ss.as_sockaddr_in6().unwrap()), 11483da5c369Sopenharmony_ci /// _ => println!("Unexpected address family") 11493da5c369Sopenharmony_ci /// } 11503da5c369Sopenharmony_ci /// ``` 11513da5c369Sopenharmony_ci fn family(&self) -> Option<AddressFamily> { 11523da5c369Sopenharmony_ci // Safe since all implementors have a sa_family field at the same 11533da5c369Sopenharmony_ci // address, and they're all repr(C) 11543da5c369Sopenharmony_ci AddressFamily::from_i32(unsafe { 11553da5c369Sopenharmony_ci (*(self as *const Self as *const libc::sockaddr)).sa_family as i32 11563da5c369Sopenharmony_ci }) 11573da5c369Sopenharmony_ci } 11583da5c369Sopenharmony_ci 11593da5c369Sopenharmony_ci cfg_if! { 11603da5c369Sopenharmony_ci if #[cfg(any(target_os = "dragonfly", 11613da5c369Sopenharmony_ci target_os = "freebsd", 11623da5c369Sopenharmony_ci target_os = "ios", 11633da5c369Sopenharmony_ci target_os = "macos", 11643da5c369Sopenharmony_ci target_os = "netbsd", 11653da5c369Sopenharmony_ci target_os = "openbsd"))] { 11663da5c369Sopenharmony_ci /// Return the length of valid data in the sockaddr structure. 11673da5c369Sopenharmony_ci /// 11683da5c369Sopenharmony_ci /// For fixed-size sockaddrs, this should be the size of the 11693da5c369Sopenharmony_ci /// structure. But for variable-sized types like [`UnixAddr`] it 11703da5c369Sopenharmony_ci /// may be less. 11713da5c369Sopenharmony_ci fn len(&self) -> libc::socklen_t { 11723da5c369Sopenharmony_ci // Safe since all implementors have a sa_len field at the same 11733da5c369Sopenharmony_ci // address, and they're all repr(transparent). 11743da5c369Sopenharmony_ci // Robust for all implementors. 11753da5c369Sopenharmony_ci unsafe { 11763da5c369Sopenharmony_ci (*(self as *const Self as *const libc::sockaddr)).sa_len 11773da5c369Sopenharmony_ci }.into() 11783da5c369Sopenharmony_ci } 11793da5c369Sopenharmony_ci } else { 11803da5c369Sopenharmony_ci /// Return the length of valid data in the sockaddr structure. 11813da5c369Sopenharmony_ci /// 11823da5c369Sopenharmony_ci /// For fixed-size sockaddrs, this should be the size of the 11833da5c369Sopenharmony_ci /// structure. But for variable-sized types like [`UnixAddr`] it 11843da5c369Sopenharmony_ci /// may be less. 11853da5c369Sopenharmony_ci fn len(&self) -> libc::socklen_t { 11863da5c369Sopenharmony_ci // No robust default implementation is possible without an 11873da5c369Sopenharmony_ci // sa_len field. Implementors with a variable size must 11883da5c369Sopenharmony_ci // override this method. 11893da5c369Sopenharmony_ci mem::size_of_val(self) as libc::socklen_t 11903da5c369Sopenharmony_ci } 11913da5c369Sopenharmony_ci } 11923da5c369Sopenharmony_ci } 11933da5c369Sopenharmony_ci 11943da5c369Sopenharmony_ci /// Return the available space in the structure 11953da5c369Sopenharmony_ci fn size() -> libc::socklen_t 11963da5c369Sopenharmony_ci where 11973da5c369Sopenharmony_ci Self: Sized, 11983da5c369Sopenharmony_ci { 11993da5c369Sopenharmony_ci mem::size_of::<Self>() as libc::socklen_t 12003da5c369Sopenharmony_ci } 12013da5c369Sopenharmony_ci} 12023da5c369Sopenharmony_ci 12033da5c369Sopenharmony_ciimpl private::SockaddrLikePriv for () { 12043da5c369Sopenharmony_ci fn as_mut_ptr(&mut self) -> *mut libc::sockaddr { 12053da5c369Sopenharmony_ci ptr::null_mut() 12063da5c369Sopenharmony_ci } 12073da5c369Sopenharmony_ci} 12083da5c369Sopenharmony_ci 12093da5c369Sopenharmony_ci/// `()` can be used in place of a real Sockaddr when no address is expected, 12103da5c369Sopenharmony_ci/// for example for a field of `Option<S> where S: SockaddrLike`. 12113da5c369Sopenharmony_ci// If this RFC ever stabilizes, then ! will be a better choice. 12123da5c369Sopenharmony_ci// https://github.com/rust-lang/rust/issues/35121 12133da5c369Sopenharmony_ciimpl SockaddrLike for () { 12143da5c369Sopenharmony_ci fn as_ptr(&self) -> *const libc::sockaddr { 12153da5c369Sopenharmony_ci ptr::null() 12163da5c369Sopenharmony_ci } 12173da5c369Sopenharmony_ci 12183da5c369Sopenharmony_ci unsafe fn from_raw( 12193da5c369Sopenharmony_ci _: *const libc::sockaddr, 12203da5c369Sopenharmony_ci _: Option<libc::socklen_t>, 12213da5c369Sopenharmony_ci ) -> Option<Self> 12223da5c369Sopenharmony_ci where 12233da5c369Sopenharmony_ci Self: Sized, 12243da5c369Sopenharmony_ci { 12253da5c369Sopenharmony_ci None 12263da5c369Sopenharmony_ci } 12273da5c369Sopenharmony_ci 12283da5c369Sopenharmony_ci fn family(&self) -> Option<AddressFamily> { 12293da5c369Sopenharmony_ci None 12303da5c369Sopenharmony_ci } 12313da5c369Sopenharmony_ci 12323da5c369Sopenharmony_ci fn len(&self) -> libc::socklen_t { 12333da5c369Sopenharmony_ci 0 12343da5c369Sopenharmony_ci } 12353da5c369Sopenharmony_ci} 12363da5c369Sopenharmony_ci 12373da5c369Sopenharmony_ci/// An IPv4 socket address 12383da5c369Sopenharmony_ci// This is identical to net::SocketAddrV4. But the standard library 12393da5c369Sopenharmony_ci// doesn't allow direct access to the libc fields, which we need. So we 12403da5c369Sopenharmony_ci// reimplement it here. 12413da5c369Sopenharmony_ci#[cfg(feature = "net")] 12423da5c369Sopenharmony_ci#[repr(transparent)] 12433da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 12443da5c369Sopenharmony_cipub struct SockaddrIn(libc::sockaddr_in); 12453da5c369Sopenharmony_ci 12463da5c369Sopenharmony_ci#[cfg(feature = "net")] 12473da5c369Sopenharmony_ciimpl SockaddrIn { 12483da5c369Sopenharmony_ci /// Returns the IP address associated with this socket address, in native 12493da5c369Sopenharmony_ci /// endian. 12503da5c369Sopenharmony_ci pub const fn ip(&self) -> libc::in_addr_t { 12513da5c369Sopenharmony_ci u32::from_be(self.0.sin_addr.s_addr) 12523da5c369Sopenharmony_ci } 12533da5c369Sopenharmony_ci 12543da5c369Sopenharmony_ci /// Creates a new socket address from IPv4 octets and a port number. 12553da5c369Sopenharmony_ci pub fn new(a: u8, b: u8, c: u8, d: u8, port: u16) -> Self { 12563da5c369Sopenharmony_ci Self(libc::sockaddr_in { 12573da5c369Sopenharmony_ci #[cfg(any( 12583da5c369Sopenharmony_ci target_os = "dragonfly", 12593da5c369Sopenharmony_ci target_os = "freebsd", 12603da5c369Sopenharmony_ci target_os = "ios", 12613da5c369Sopenharmony_ci target_os = "macos", 12623da5c369Sopenharmony_ci target_os = "netbsd", 12633da5c369Sopenharmony_ci target_os = "haiku", 12643da5c369Sopenharmony_ci target_os = "openbsd" 12653da5c369Sopenharmony_ci ))] 12663da5c369Sopenharmony_ci sin_len: Self::size() as u8, 12673da5c369Sopenharmony_ci sin_family: AddressFamily::Inet as sa_family_t, 12683da5c369Sopenharmony_ci sin_port: u16::to_be(port), 12693da5c369Sopenharmony_ci sin_addr: libc::in_addr { 12703da5c369Sopenharmony_ci s_addr: u32::from_ne_bytes([a, b, c, d]), 12713da5c369Sopenharmony_ci }, 12723da5c369Sopenharmony_ci sin_zero: unsafe { mem::zeroed() }, 12733da5c369Sopenharmony_ci }) 12743da5c369Sopenharmony_ci } 12753da5c369Sopenharmony_ci 12763da5c369Sopenharmony_ci /// Returns the port number associated with this socket address, in native 12773da5c369Sopenharmony_ci /// endian. 12783da5c369Sopenharmony_ci pub const fn port(&self) -> u16 { 12793da5c369Sopenharmony_ci u16::from_be(self.0.sin_port) 12803da5c369Sopenharmony_ci } 12813da5c369Sopenharmony_ci} 12823da5c369Sopenharmony_ci 12833da5c369Sopenharmony_ci#[cfg(feature = "net")] 12843da5c369Sopenharmony_ciimpl private::SockaddrLikePriv for SockaddrIn {} 12853da5c369Sopenharmony_ci#[cfg(feature = "net")] 12863da5c369Sopenharmony_ciimpl SockaddrLike for SockaddrIn { 12873da5c369Sopenharmony_ci unsafe fn from_raw( 12883da5c369Sopenharmony_ci addr: *const libc::sockaddr, 12893da5c369Sopenharmony_ci len: Option<libc::socklen_t>, 12903da5c369Sopenharmony_ci ) -> Option<Self> 12913da5c369Sopenharmony_ci where 12923da5c369Sopenharmony_ci Self: Sized, 12933da5c369Sopenharmony_ci { 12943da5c369Sopenharmony_ci if let Some(l) = len { 12953da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_in>() as libc::socklen_t { 12963da5c369Sopenharmony_ci return None; 12973da5c369Sopenharmony_ci } 12983da5c369Sopenharmony_ci } 12993da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_INET { 13003da5c369Sopenharmony_ci return None; 13013da5c369Sopenharmony_ci } 13023da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 13033da5c369Sopenharmony_ci } 13043da5c369Sopenharmony_ci} 13053da5c369Sopenharmony_ci 13063da5c369Sopenharmony_ci#[cfg(feature = "net")] 13073da5c369Sopenharmony_ciimpl AsRef<libc::sockaddr_in> for SockaddrIn { 13083da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_in { 13093da5c369Sopenharmony_ci &self.0 13103da5c369Sopenharmony_ci } 13113da5c369Sopenharmony_ci} 13123da5c369Sopenharmony_ci 13133da5c369Sopenharmony_ci#[cfg(feature = "net")] 13143da5c369Sopenharmony_ciimpl fmt::Display for SockaddrIn { 13153da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 13163da5c369Sopenharmony_ci let ne = u32::from_be(self.0.sin_addr.s_addr); 13173da5c369Sopenharmony_ci let port = u16::from_be(self.0.sin_port); 13183da5c369Sopenharmony_ci write!( 13193da5c369Sopenharmony_ci f, 13203da5c369Sopenharmony_ci "{}.{}.{}.{}:{}", 13213da5c369Sopenharmony_ci ne >> 24, 13223da5c369Sopenharmony_ci (ne >> 16) & 0xFF, 13233da5c369Sopenharmony_ci (ne >> 8) & 0xFF, 13243da5c369Sopenharmony_ci ne & 0xFF, 13253da5c369Sopenharmony_ci port 13263da5c369Sopenharmony_ci ) 13273da5c369Sopenharmony_ci } 13283da5c369Sopenharmony_ci} 13293da5c369Sopenharmony_ci 13303da5c369Sopenharmony_ci#[cfg(feature = "net")] 13313da5c369Sopenharmony_ciimpl From<net::SocketAddrV4> for SockaddrIn { 13323da5c369Sopenharmony_ci fn from(addr: net::SocketAddrV4) -> Self { 13333da5c369Sopenharmony_ci Self(libc::sockaddr_in { 13343da5c369Sopenharmony_ci #[cfg(any( 13353da5c369Sopenharmony_ci target_os = "dragonfly", 13363da5c369Sopenharmony_ci target_os = "freebsd", 13373da5c369Sopenharmony_ci target_os = "haiku", 13383da5c369Sopenharmony_ci target_os = "hermit", 13393da5c369Sopenharmony_ci target_os = "ios", 13403da5c369Sopenharmony_ci target_os = "macos", 13413da5c369Sopenharmony_ci target_os = "netbsd", 13423da5c369Sopenharmony_ci target_os = "openbsd" 13433da5c369Sopenharmony_ci ))] 13443da5c369Sopenharmony_ci sin_len: mem::size_of::<libc::sockaddr_in>() as u8, 13453da5c369Sopenharmony_ci sin_family: AddressFamily::Inet as sa_family_t, 13463da5c369Sopenharmony_ci sin_port: addr.port().to_be(), // network byte order 13473da5c369Sopenharmony_ci sin_addr: ipv4addr_to_libc(*addr.ip()), 13483da5c369Sopenharmony_ci ..unsafe { mem::zeroed() } 13493da5c369Sopenharmony_ci }) 13503da5c369Sopenharmony_ci } 13513da5c369Sopenharmony_ci} 13523da5c369Sopenharmony_ci 13533da5c369Sopenharmony_ci#[cfg(feature = "net")] 13543da5c369Sopenharmony_ciimpl From<SockaddrIn> for net::SocketAddrV4 { 13553da5c369Sopenharmony_ci fn from(addr: SockaddrIn) -> Self { 13563da5c369Sopenharmony_ci net::SocketAddrV4::new( 13573da5c369Sopenharmony_ci net::Ipv4Addr::from(addr.0.sin_addr.s_addr.to_ne_bytes()), 13583da5c369Sopenharmony_ci u16::from_be(addr.0.sin_port), 13593da5c369Sopenharmony_ci ) 13603da5c369Sopenharmony_ci } 13613da5c369Sopenharmony_ci} 13623da5c369Sopenharmony_ci 13633da5c369Sopenharmony_ci#[cfg(feature = "net")] 13643da5c369Sopenharmony_ciimpl std::str::FromStr for SockaddrIn { 13653da5c369Sopenharmony_ci type Err = net::AddrParseError; 13663da5c369Sopenharmony_ci 13673da5c369Sopenharmony_ci fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { 13683da5c369Sopenharmony_ci net::SocketAddrV4::from_str(s).map(SockaddrIn::from) 13693da5c369Sopenharmony_ci } 13703da5c369Sopenharmony_ci} 13713da5c369Sopenharmony_ci 13723da5c369Sopenharmony_ci/// An IPv6 socket address 13733da5c369Sopenharmony_ci#[cfg(feature = "net")] 13743da5c369Sopenharmony_ci#[repr(transparent)] 13753da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 13763da5c369Sopenharmony_cipub struct SockaddrIn6(libc::sockaddr_in6); 13773da5c369Sopenharmony_ci 13783da5c369Sopenharmony_ci#[cfg(feature = "net")] 13793da5c369Sopenharmony_ciimpl SockaddrIn6 { 13803da5c369Sopenharmony_ci /// Returns the flow information associated with this address. 13813da5c369Sopenharmony_ci pub const fn flowinfo(&self) -> u32 { 13823da5c369Sopenharmony_ci self.0.sin6_flowinfo 13833da5c369Sopenharmony_ci } 13843da5c369Sopenharmony_ci 13853da5c369Sopenharmony_ci /// Returns the IP address associated with this socket address. 13863da5c369Sopenharmony_ci pub fn ip(&self) -> net::Ipv6Addr { 13873da5c369Sopenharmony_ci net::Ipv6Addr::from(self.0.sin6_addr.s6_addr) 13883da5c369Sopenharmony_ci } 13893da5c369Sopenharmony_ci 13903da5c369Sopenharmony_ci /// Returns the port number associated with this socket address, in native 13913da5c369Sopenharmony_ci /// endian. 13923da5c369Sopenharmony_ci pub const fn port(&self) -> u16 { 13933da5c369Sopenharmony_ci u16::from_be(self.0.sin6_port) 13943da5c369Sopenharmony_ci } 13953da5c369Sopenharmony_ci 13963da5c369Sopenharmony_ci /// Returns the scope ID associated with this address. 13973da5c369Sopenharmony_ci pub const fn scope_id(&self) -> u32 { 13983da5c369Sopenharmony_ci self.0.sin6_scope_id 13993da5c369Sopenharmony_ci } 14003da5c369Sopenharmony_ci} 14013da5c369Sopenharmony_ci 14023da5c369Sopenharmony_ci#[cfg(feature = "net")] 14033da5c369Sopenharmony_ciimpl private::SockaddrLikePriv for SockaddrIn6 {} 14043da5c369Sopenharmony_ci#[cfg(feature = "net")] 14053da5c369Sopenharmony_ciimpl SockaddrLike for SockaddrIn6 { 14063da5c369Sopenharmony_ci unsafe fn from_raw( 14073da5c369Sopenharmony_ci addr: *const libc::sockaddr, 14083da5c369Sopenharmony_ci len: Option<libc::socklen_t>, 14093da5c369Sopenharmony_ci ) -> Option<Self> 14103da5c369Sopenharmony_ci where 14113da5c369Sopenharmony_ci Self: Sized, 14123da5c369Sopenharmony_ci { 14133da5c369Sopenharmony_ci if let Some(l) = len { 14143da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t { 14153da5c369Sopenharmony_ci return None; 14163da5c369Sopenharmony_ci } 14173da5c369Sopenharmony_ci } 14183da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_INET6 { 14193da5c369Sopenharmony_ci return None; 14203da5c369Sopenharmony_ci } 14213da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 14223da5c369Sopenharmony_ci } 14233da5c369Sopenharmony_ci} 14243da5c369Sopenharmony_ci 14253da5c369Sopenharmony_ci#[cfg(feature = "net")] 14263da5c369Sopenharmony_ciimpl AsRef<libc::sockaddr_in6> for SockaddrIn6 { 14273da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_in6 { 14283da5c369Sopenharmony_ci &self.0 14293da5c369Sopenharmony_ci } 14303da5c369Sopenharmony_ci} 14313da5c369Sopenharmony_ci 14323da5c369Sopenharmony_ci#[cfg(feature = "net")] 14333da5c369Sopenharmony_ciimpl fmt::Display for SockaddrIn6 { 14343da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 14353da5c369Sopenharmony_ci // These things are really hard to display properly. Easier to let std 14363da5c369Sopenharmony_ci // do it. 14373da5c369Sopenharmony_ci let std = net::SocketAddrV6::new( 14383da5c369Sopenharmony_ci self.ip(), 14393da5c369Sopenharmony_ci self.port(), 14403da5c369Sopenharmony_ci self.flowinfo(), 14413da5c369Sopenharmony_ci self.scope_id(), 14423da5c369Sopenharmony_ci ); 14433da5c369Sopenharmony_ci std.fmt(f) 14443da5c369Sopenharmony_ci } 14453da5c369Sopenharmony_ci} 14463da5c369Sopenharmony_ci 14473da5c369Sopenharmony_ci#[cfg(feature = "net")] 14483da5c369Sopenharmony_ciimpl From<net::SocketAddrV6> for SockaddrIn6 { 14493da5c369Sopenharmony_ci fn from(addr: net::SocketAddrV6) -> Self { 14503da5c369Sopenharmony_ci #[allow(clippy::needless_update)] // It isn't needless on Illumos 14513da5c369Sopenharmony_ci Self(libc::sockaddr_in6 { 14523da5c369Sopenharmony_ci #[cfg(any( 14533da5c369Sopenharmony_ci target_os = "dragonfly", 14543da5c369Sopenharmony_ci target_os = "freebsd", 14553da5c369Sopenharmony_ci target_os = "haiku", 14563da5c369Sopenharmony_ci target_os = "hermit", 14573da5c369Sopenharmony_ci target_os = "ios", 14583da5c369Sopenharmony_ci target_os = "macos", 14593da5c369Sopenharmony_ci target_os = "netbsd", 14603da5c369Sopenharmony_ci target_os = "openbsd" 14613da5c369Sopenharmony_ci ))] 14623da5c369Sopenharmony_ci sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8, 14633da5c369Sopenharmony_ci sin6_family: AddressFamily::Inet6 as sa_family_t, 14643da5c369Sopenharmony_ci sin6_port: addr.port().to_be(), // network byte order 14653da5c369Sopenharmony_ci sin6_addr: ipv6addr_to_libc(addr.ip()), 14663da5c369Sopenharmony_ci sin6_flowinfo: addr.flowinfo(), // host byte order 14673da5c369Sopenharmony_ci sin6_scope_id: addr.scope_id(), // host byte order 14683da5c369Sopenharmony_ci ..unsafe { mem::zeroed() } 14693da5c369Sopenharmony_ci }) 14703da5c369Sopenharmony_ci } 14713da5c369Sopenharmony_ci} 14723da5c369Sopenharmony_ci 14733da5c369Sopenharmony_ci#[cfg(feature = "net")] 14743da5c369Sopenharmony_ciimpl From<SockaddrIn6> for net::SocketAddrV6 { 14753da5c369Sopenharmony_ci fn from(addr: SockaddrIn6) -> Self { 14763da5c369Sopenharmony_ci net::SocketAddrV6::new( 14773da5c369Sopenharmony_ci net::Ipv6Addr::from(addr.0.sin6_addr.s6_addr), 14783da5c369Sopenharmony_ci u16::from_be(addr.0.sin6_port), 14793da5c369Sopenharmony_ci addr.0.sin6_flowinfo, 14803da5c369Sopenharmony_ci addr.0.sin6_scope_id, 14813da5c369Sopenharmony_ci ) 14823da5c369Sopenharmony_ci } 14833da5c369Sopenharmony_ci} 14843da5c369Sopenharmony_ci 14853da5c369Sopenharmony_ci#[cfg(feature = "net")] 14863da5c369Sopenharmony_ciimpl std::str::FromStr for SockaddrIn6 { 14873da5c369Sopenharmony_ci type Err = net::AddrParseError; 14883da5c369Sopenharmony_ci 14893da5c369Sopenharmony_ci fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { 14903da5c369Sopenharmony_ci net::SocketAddrV6::from_str(s).map(SockaddrIn6::from) 14913da5c369Sopenharmony_ci } 14923da5c369Sopenharmony_ci} 14933da5c369Sopenharmony_ci 14943da5c369Sopenharmony_ci/// A container for any sockaddr type 14953da5c369Sopenharmony_ci/// 14963da5c369Sopenharmony_ci/// Just like C's `sockaddr_storage`, this type is large enough to hold any type 14973da5c369Sopenharmony_ci/// of sockaddr. It can be used as an argument with functions like 14983da5c369Sopenharmony_ci/// [`bind`](super::bind) and [`getsockname`](super::getsockname). Though it is 14993da5c369Sopenharmony_ci/// a union, it can be safely accessed through the `as_*` methods. 15003da5c369Sopenharmony_ci/// 15013da5c369Sopenharmony_ci/// # Example 15023da5c369Sopenharmony_ci/// ``` 15033da5c369Sopenharmony_ci/// # use nix::sys::socket::*; 15043da5c369Sopenharmony_ci/// # use std::str::FromStr; 15053da5c369Sopenharmony_ci/// let localhost = SockaddrIn::from_str("127.0.0.1:8081").unwrap(); 15063da5c369Sopenharmony_ci/// let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), 15073da5c369Sopenharmony_ci/// None).unwrap(); 15083da5c369Sopenharmony_ci/// bind(fd, &localhost).expect("bind"); 15093da5c369Sopenharmony_ci/// let ss: SockaddrStorage = getsockname(fd).expect("getsockname"); 15103da5c369Sopenharmony_ci/// assert_eq!(&localhost, ss.as_sockaddr_in().unwrap()); 15113da5c369Sopenharmony_ci/// ``` 15123da5c369Sopenharmony_ci#[derive(Clone, Copy, Eq)] 15133da5c369Sopenharmony_ci#[repr(C)] 15143da5c369Sopenharmony_cipub union SockaddrStorage { 15153da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 15163da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 15173da5c369Sopenharmony_ci alg: AlgAddr, 15183da5c369Sopenharmony_ci #[cfg(feature = "net")] 15193da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(feature = "net")))] 15203da5c369Sopenharmony_ci dl: LinkAddr, 15213da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 15223da5c369Sopenharmony_ci nl: NetlinkAddr, 15233da5c369Sopenharmony_ci #[cfg(all( 15243da5c369Sopenharmony_ci feature = "ioctl", 15253da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 15263da5c369Sopenharmony_ci ))] 15273da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] 15283da5c369Sopenharmony_ci sctl: SysControlAddr, 15293da5c369Sopenharmony_ci #[cfg(feature = "net")] 15303da5c369Sopenharmony_ci sin: SockaddrIn, 15313da5c369Sopenharmony_ci #[cfg(feature = "net")] 15323da5c369Sopenharmony_ci sin6: SockaddrIn6, 15333da5c369Sopenharmony_ci ss: libc::sockaddr_storage, 15343da5c369Sopenharmony_ci su: UnixAddr, 15353da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 15363da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 15373da5c369Sopenharmony_ci vsock: VsockAddr, 15383da5c369Sopenharmony_ci} 15393da5c369Sopenharmony_ciimpl private::SockaddrLikePriv for SockaddrStorage {} 15403da5c369Sopenharmony_ciimpl SockaddrLike for SockaddrStorage { 15413da5c369Sopenharmony_ci unsafe fn from_raw( 15423da5c369Sopenharmony_ci addr: *const libc::sockaddr, 15433da5c369Sopenharmony_ci l: Option<libc::socklen_t>, 15443da5c369Sopenharmony_ci ) -> Option<Self> 15453da5c369Sopenharmony_ci where 15463da5c369Sopenharmony_ci Self: Sized, 15473da5c369Sopenharmony_ci { 15483da5c369Sopenharmony_ci if addr.is_null() { 15493da5c369Sopenharmony_ci return None; 15503da5c369Sopenharmony_ci } 15513da5c369Sopenharmony_ci if let Some(len) = l { 15523da5c369Sopenharmony_ci let ulen = len as usize; 15533da5c369Sopenharmony_ci if ulen < offset_of!(libc::sockaddr, sa_data) 15543da5c369Sopenharmony_ci || ulen > mem::size_of::<libc::sockaddr_storage>() 15553da5c369Sopenharmony_ci { 15563da5c369Sopenharmony_ci None 15573da5c369Sopenharmony_ci } else { 15583da5c369Sopenharmony_ci let mut ss: libc::sockaddr_storage = mem::zeroed(); 15593da5c369Sopenharmony_ci let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8; 15603da5c369Sopenharmony_ci ptr::copy(addr as *const u8, ssp, len as usize); 15613da5c369Sopenharmony_ci #[cfg(any( 15623da5c369Sopenharmony_ci target_os = "android", 15633da5c369Sopenharmony_ci target_os = "fuchsia", 15643da5c369Sopenharmony_ci target_os = "illumos", 15653da5c369Sopenharmony_ci target_os = "linux" 15663da5c369Sopenharmony_ci ))] 15673da5c369Sopenharmony_ci if i32::from(ss.ss_family) == libc::AF_UNIX { 15683da5c369Sopenharmony_ci // Safe because we UnixAddr is strictly smaller than 15693da5c369Sopenharmony_ci // SockaddrStorage, and we just initialized the structure. 15703da5c369Sopenharmony_ci (*(&mut ss as *mut libc::sockaddr_storage as *mut UnixAddr)).sun_len = len as u8; 15713da5c369Sopenharmony_ci } 15723da5c369Sopenharmony_ci Some(Self { ss }) 15733da5c369Sopenharmony_ci } 15743da5c369Sopenharmony_ci } else { 15753da5c369Sopenharmony_ci // If length is not available and addr is of a fixed-length type, 15763da5c369Sopenharmony_ci // copy it. If addr is of a variable length type and len is not 15773da5c369Sopenharmony_ci // available, then there's nothing we can do. 15783da5c369Sopenharmony_ci match (*addr).sa_family as i32 { 15793da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 15803da5c369Sopenharmony_ci libc::AF_ALG => { 15813da5c369Sopenharmony_ci AlgAddr::from_raw(addr, l).map(|alg| Self { alg }) 15823da5c369Sopenharmony_ci } 15833da5c369Sopenharmony_ci #[cfg(feature = "net")] 15843da5c369Sopenharmony_ci libc::AF_INET => { 15853da5c369Sopenharmony_ci SockaddrIn::from_raw(addr, l).map(|sin| Self { sin }) 15863da5c369Sopenharmony_ci } 15873da5c369Sopenharmony_ci #[cfg(feature = "net")] 15883da5c369Sopenharmony_ci libc::AF_INET6 => { 15893da5c369Sopenharmony_ci SockaddrIn6::from_raw(addr, l).map(|sin6| Self { sin6 }) 15903da5c369Sopenharmony_ci } 15913da5c369Sopenharmony_ci #[cfg(any( 15923da5c369Sopenharmony_ci target_os = "dragonfly", 15933da5c369Sopenharmony_ci target_os = "freebsd", 15943da5c369Sopenharmony_ci target_os = "ios", 15953da5c369Sopenharmony_ci target_os = "macos", 15963da5c369Sopenharmony_ci target_os = "illumos", 15973da5c369Sopenharmony_ci target_os = "netbsd", 15983da5c369Sopenharmony_ci target_os = "haiku", 15993da5c369Sopenharmony_ci target_os = "openbsd" 16003da5c369Sopenharmony_ci ))] 16013da5c369Sopenharmony_ci #[cfg(feature = "net")] 16023da5c369Sopenharmony_ci libc::AF_LINK => { 16033da5c369Sopenharmony_ci LinkAddr::from_raw(addr, l).map(|dl| Self { dl }) 16043da5c369Sopenharmony_ci } 16053da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 16063da5c369Sopenharmony_ci libc::AF_NETLINK => { 16073da5c369Sopenharmony_ci NetlinkAddr::from_raw(addr, l).map(|nl| Self { nl }) 16083da5c369Sopenharmony_ci } 16093da5c369Sopenharmony_ci #[cfg(any( 16103da5c369Sopenharmony_ci target_os = "android", 16113da5c369Sopenharmony_ci target_os = "fuchsia", 16123da5c369Sopenharmony_ci target_os = "linux" 16133da5c369Sopenharmony_ci ))] 16143da5c369Sopenharmony_ci #[cfg(feature = "net")] 16153da5c369Sopenharmony_ci libc::AF_PACKET => { 16163da5c369Sopenharmony_ci LinkAddr::from_raw(addr, l).map(|dl| Self { dl }) 16173da5c369Sopenharmony_ci } 16183da5c369Sopenharmony_ci #[cfg(all( 16193da5c369Sopenharmony_ci feature = "ioctl", 16203da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 16213da5c369Sopenharmony_ci ))] 16223da5c369Sopenharmony_ci libc::AF_SYSTEM => { 16233da5c369Sopenharmony_ci SysControlAddr::from_raw(addr, l).map(|sctl| Self { sctl }) 16243da5c369Sopenharmony_ci } 16253da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 16263da5c369Sopenharmony_ci libc::AF_VSOCK => { 16273da5c369Sopenharmony_ci VsockAddr::from_raw(addr, l).map(|vsock| Self { vsock }) 16283da5c369Sopenharmony_ci } 16293da5c369Sopenharmony_ci _ => None, 16303da5c369Sopenharmony_ci } 16313da5c369Sopenharmony_ci } 16323da5c369Sopenharmony_ci } 16333da5c369Sopenharmony_ci 16343da5c369Sopenharmony_ci #[cfg(any( 16353da5c369Sopenharmony_ci target_os = "android", 16363da5c369Sopenharmony_ci target_os = "fuchsia", 16373da5c369Sopenharmony_ci target_os = "illumos", 16383da5c369Sopenharmony_ci target_os = "linux" 16393da5c369Sopenharmony_ci ))] 16403da5c369Sopenharmony_ci fn len(&self) -> libc::socklen_t { 16413da5c369Sopenharmony_ci match self.as_unix_addr() { 16423da5c369Sopenharmony_ci // The UnixAddr type knows its own length 16433da5c369Sopenharmony_ci Some(ua) => ua.len(), 16443da5c369Sopenharmony_ci // For all else, we're just a boring SockaddrStorage 16453da5c369Sopenharmony_ci None => mem::size_of_val(self) as libc::socklen_t 16463da5c369Sopenharmony_ci } 16473da5c369Sopenharmony_ci } 16483da5c369Sopenharmony_ci} 16493da5c369Sopenharmony_ci 16503da5c369Sopenharmony_cimacro_rules! accessors { 16513da5c369Sopenharmony_ci ( 16523da5c369Sopenharmony_ci $fname:ident, 16533da5c369Sopenharmony_ci $fname_mut:ident, 16543da5c369Sopenharmony_ci $sockty:ty, 16553da5c369Sopenharmony_ci $family:expr, 16563da5c369Sopenharmony_ci $libc_ty:ty, 16573da5c369Sopenharmony_ci $field:ident) => { 16583da5c369Sopenharmony_ci /// Safely and falliably downcast to an immutable reference 16593da5c369Sopenharmony_ci pub fn $fname(&self) -> Option<&$sockty> { 16603da5c369Sopenharmony_ci if self.family() == Some($family) 16613da5c369Sopenharmony_ci && self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t 16623da5c369Sopenharmony_ci { 16633da5c369Sopenharmony_ci // Safe because family and len are validated 16643da5c369Sopenharmony_ci Some(unsafe { &self.$field }) 16653da5c369Sopenharmony_ci } else { 16663da5c369Sopenharmony_ci None 16673da5c369Sopenharmony_ci } 16683da5c369Sopenharmony_ci } 16693da5c369Sopenharmony_ci 16703da5c369Sopenharmony_ci /// Safely and falliably downcast to a mutable reference 16713da5c369Sopenharmony_ci pub fn $fname_mut(&mut self) -> Option<&mut $sockty> { 16723da5c369Sopenharmony_ci if self.family() == Some($family) 16733da5c369Sopenharmony_ci && self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t 16743da5c369Sopenharmony_ci { 16753da5c369Sopenharmony_ci // Safe because family and len are validated 16763da5c369Sopenharmony_ci Some(unsafe { &mut self.$field }) 16773da5c369Sopenharmony_ci } else { 16783da5c369Sopenharmony_ci None 16793da5c369Sopenharmony_ci } 16803da5c369Sopenharmony_ci } 16813da5c369Sopenharmony_ci }; 16823da5c369Sopenharmony_ci} 16833da5c369Sopenharmony_ci 16843da5c369Sopenharmony_ciimpl SockaddrStorage { 16853da5c369Sopenharmony_ci /// Downcast to an immutable `[UnixAddr]` reference. 16863da5c369Sopenharmony_ci pub fn as_unix_addr(&self) -> Option<&UnixAddr> { 16873da5c369Sopenharmony_ci cfg_if! { 16883da5c369Sopenharmony_ci if #[cfg(any(target_os = "android", 16893da5c369Sopenharmony_ci target_os = "fuchsia", 16903da5c369Sopenharmony_ci target_os = "illumos", 16913da5c369Sopenharmony_ci target_os = "linux" 16923da5c369Sopenharmony_ci ))] 16933da5c369Sopenharmony_ci { 16943da5c369Sopenharmony_ci let p = unsafe{ &self.ss as *const libc::sockaddr_storage }; 16953da5c369Sopenharmony_ci // Safe because UnixAddr is strictly smaller than 16963da5c369Sopenharmony_ci // sockaddr_storage, and we're fully initialized 16973da5c369Sopenharmony_ci let len = unsafe { 16983da5c369Sopenharmony_ci (*(p as *const UnixAddr )).sun_len as usize 16993da5c369Sopenharmony_ci }; 17003da5c369Sopenharmony_ci } else { 17013da5c369Sopenharmony_ci let len = self.len() as usize; 17023da5c369Sopenharmony_ci } 17033da5c369Sopenharmony_ci } 17043da5c369Sopenharmony_ci // Sanity checks 17053da5c369Sopenharmony_ci if self.family() != Some(AddressFamily::Unix) || 17063da5c369Sopenharmony_ci len < offset_of!(libc::sockaddr_un, sun_path) || 17073da5c369Sopenharmony_ci len > mem::size_of::<libc::sockaddr_un>() { 17083da5c369Sopenharmony_ci None 17093da5c369Sopenharmony_ci } else { 17103da5c369Sopenharmony_ci Some(unsafe{&self.su}) 17113da5c369Sopenharmony_ci } 17123da5c369Sopenharmony_ci } 17133da5c369Sopenharmony_ci 17143da5c369Sopenharmony_ci /// Downcast to a mutable `[UnixAddr]` reference. 17153da5c369Sopenharmony_ci pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> { 17163da5c369Sopenharmony_ci cfg_if! { 17173da5c369Sopenharmony_ci if #[cfg(any(target_os = "android", 17183da5c369Sopenharmony_ci target_os = "fuchsia", 17193da5c369Sopenharmony_ci target_os = "illumos", 17203da5c369Sopenharmony_ci target_os = "linux" 17213da5c369Sopenharmony_ci ))] 17223da5c369Sopenharmony_ci { 17233da5c369Sopenharmony_ci let p = unsafe{ &self.ss as *const libc::sockaddr_storage }; 17243da5c369Sopenharmony_ci // Safe because UnixAddr is strictly smaller than 17253da5c369Sopenharmony_ci // sockaddr_storage, and we're fully initialized 17263da5c369Sopenharmony_ci let len = unsafe { 17273da5c369Sopenharmony_ci (*(p as *const UnixAddr )).sun_len as usize 17283da5c369Sopenharmony_ci }; 17293da5c369Sopenharmony_ci } else { 17303da5c369Sopenharmony_ci let len = self.len() as usize; 17313da5c369Sopenharmony_ci } 17323da5c369Sopenharmony_ci } 17333da5c369Sopenharmony_ci // Sanity checks 17343da5c369Sopenharmony_ci if self.family() != Some(AddressFamily::Unix) || 17353da5c369Sopenharmony_ci len < offset_of!(libc::sockaddr_un, sun_path) || 17363da5c369Sopenharmony_ci len > mem::size_of::<libc::sockaddr_un>() { 17373da5c369Sopenharmony_ci None 17383da5c369Sopenharmony_ci } else { 17393da5c369Sopenharmony_ci Some(unsafe{&mut self.su}) 17403da5c369Sopenharmony_ci } 17413da5c369Sopenharmony_ci } 17423da5c369Sopenharmony_ci 17433da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 17443da5c369Sopenharmony_ci accessors! {as_alg_addr, as_alg_addr_mut, AlgAddr, 17453da5c369Sopenharmony_ci AddressFamily::Alg, libc::sockaddr_alg, alg} 17463da5c369Sopenharmony_ci 17473da5c369Sopenharmony_ci #[cfg(any( 17483da5c369Sopenharmony_ci target_os = "android", 17493da5c369Sopenharmony_ci target_os = "fuchsia", 17503da5c369Sopenharmony_ci target_os = "linux" 17513da5c369Sopenharmony_ci ))] 17523da5c369Sopenharmony_ci #[cfg(feature = "net")] 17533da5c369Sopenharmony_ci accessors! { 17543da5c369Sopenharmony_ci as_link_addr, as_link_addr_mut, LinkAddr, 17553da5c369Sopenharmony_ci AddressFamily::Packet, libc::sockaddr_ll, dl} 17563da5c369Sopenharmony_ci 17573da5c369Sopenharmony_ci #[cfg(any( 17583da5c369Sopenharmony_ci target_os = "dragonfly", 17593da5c369Sopenharmony_ci target_os = "freebsd", 17603da5c369Sopenharmony_ci target_os = "ios", 17613da5c369Sopenharmony_ci target_os = "macos", 17623da5c369Sopenharmony_ci target_os = "illumos", 17633da5c369Sopenharmony_ci target_os = "netbsd", 17643da5c369Sopenharmony_ci target_os = "openbsd" 17653da5c369Sopenharmony_ci ))] 17663da5c369Sopenharmony_ci #[cfg(feature = "net")] 17673da5c369Sopenharmony_ci accessors! { 17683da5c369Sopenharmony_ci as_link_addr, as_link_addr_mut, LinkAddr, 17693da5c369Sopenharmony_ci AddressFamily::Link, libc::sockaddr_dl, dl} 17703da5c369Sopenharmony_ci 17713da5c369Sopenharmony_ci #[cfg(feature = "net")] 17723da5c369Sopenharmony_ci accessors! { 17733da5c369Sopenharmony_ci as_sockaddr_in, as_sockaddr_in_mut, SockaddrIn, 17743da5c369Sopenharmony_ci AddressFamily::Inet, libc::sockaddr_in, sin} 17753da5c369Sopenharmony_ci 17763da5c369Sopenharmony_ci #[cfg(feature = "net")] 17773da5c369Sopenharmony_ci accessors! { 17783da5c369Sopenharmony_ci as_sockaddr_in6, as_sockaddr_in6_mut, SockaddrIn6, 17793da5c369Sopenharmony_ci AddressFamily::Inet6, libc::sockaddr_in6, sin6} 17803da5c369Sopenharmony_ci 17813da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 17823da5c369Sopenharmony_ci accessors! {as_netlink_addr, as_netlink_addr_mut, NetlinkAddr, 17833da5c369Sopenharmony_ci AddressFamily::Netlink, libc::sockaddr_nl, nl} 17843da5c369Sopenharmony_ci 17853da5c369Sopenharmony_ci #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))] 17863da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] 17873da5c369Sopenharmony_ci accessors! {as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr, 17883da5c369Sopenharmony_ci AddressFamily::System, libc::sockaddr_ctl, sctl} 17893da5c369Sopenharmony_ci 17903da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 17913da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 17923da5c369Sopenharmony_ci accessors! {as_vsock_addr, as_vsock_addr_mut, VsockAddr, 17933da5c369Sopenharmony_ci AddressFamily::Vsock, libc::sockaddr_vm, vsock} 17943da5c369Sopenharmony_ci} 17953da5c369Sopenharmony_ci 17963da5c369Sopenharmony_ciimpl fmt::Debug for SockaddrStorage { 17973da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 17983da5c369Sopenharmony_ci f.debug_struct("SockaddrStorage") 17993da5c369Sopenharmony_ci // Safe because sockaddr_storage has the least specific 18003da5c369Sopenharmony_ci // field types 18013da5c369Sopenharmony_ci .field("ss", unsafe { &self.ss }) 18023da5c369Sopenharmony_ci .finish() 18033da5c369Sopenharmony_ci } 18043da5c369Sopenharmony_ci} 18053da5c369Sopenharmony_ci 18063da5c369Sopenharmony_ciimpl fmt::Display for SockaddrStorage { 18073da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 18083da5c369Sopenharmony_ci unsafe { 18093da5c369Sopenharmony_ci match self.ss.ss_family as i32 { 18103da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 18113da5c369Sopenharmony_ci libc::AF_ALG => self.alg.fmt(f), 18123da5c369Sopenharmony_ci #[cfg(feature = "net")] 18133da5c369Sopenharmony_ci libc::AF_INET => self.sin.fmt(f), 18143da5c369Sopenharmony_ci #[cfg(feature = "net")] 18153da5c369Sopenharmony_ci libc::AF_INET6 => self.sin6.fmt(f), 18163da5c369Sopenharmony_ci #[cfg(any( 18173da5c369Sopenharmony_ci target_os = "dragonfly", 18183da5c369Sopenharmony_ci target_os = "freebsd", 18193da5c369Sopenharmony_ci target_os = "ios", 18203da5c369Sopenharmony_ci target_os = "macos", 18213da5c369Sopenharmony_ci target_os = "illumos", 18223da5c369Sopenharmony_ci target_os = "netbsd", 18233da5c369Sopenharmony_ci target_os = "openbsd" 18243da5c369Sopenharmony_ci ))] 18253da5c369Sopenharmony_ci #[cfg(feature = "net")] 18263da5c369Sopenharmony_ci libc::AF_LINK => self.dl.fmt(f), 18273da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 18283da5c369Sopenharmony_ci libc::AF_NETLINK => self.nl.fmt(f), 18293da5c369Sopenharmony_ci #[cfg(any( 18303da5c369Sopenharmony_ci target_os = "android", 18313da5c369Sopenharmony_ci target_os = "linux", 18323da5c369Sopenharmony_ci target_os = "fuchsia" 18333da5c369Sopenharmony_ci ))] 18343da5c369Sopenharmony_ci #[cfg(feature = "net")] 18353da5c369Sopenharmony_ci libc::AF_PACKET => self.dl.fmt(f), 18363da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 18373da5c369Sopenharmony_ci #[cfg(feature = "ioctl")] 18383da5c369Sopenharmony_ci libc::AF_SYSTEM => self.sctl.fmt(f), 18393da5c369Sopenharmony_ci libc::AF_UNIX => self.su.fmt(f), 18403da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 18413da5c369Sopenharmony_ci libc::AF_VSOCK => self.vsock.fmt(f), 18423da5c369Sopenharmony_ci _ => "<Address family unspecified>".fmt(f), 18433da5c369Sopenharmony_ci } 18443da5c369Sopenharmony_ci } 18453da5c369Sopenharmony_ci } 18463da5c369Sopenharmony_ci} 18473da5c369Sopenharmony_ci 18483da5c369Sopenharmony_ci#[cfg(feature = "net")] 18493da5c369Sopenharmony_ciimpl From<net::SocketAddrV4> for SockaddrStorage { 18503da5c369Sopenharmony_ci fn from(s: net::SocketAddrV4) -> Self { 18513da5c369Sopenharmony_ci unsafe { 18523da5c369Sopenharmony_ci let mut ss: Self = mem::zeroed(); 18533da5c369Sopenharmony_ci ss.sin = SockaddrIn::from(s); 18543da5c369Sopenharmony_ci ss 18553da5c369Sopenharmony_ci } 18563da5c369Sopenharmony_ci } 18573da5c369Sopenharmony_ci} 18583da5c369Sopenharmony_ci 18593da5c369Sopenharmony_ci#[cfg(feature = "net")] 18603da5c369Sopenharmony_ciimpl From<net::SocketAddrV6> for SockaddrStorage { 18613da5c369Sopenharmony_ci fn from(s: net::SocketAddrV6) -> Self { 18623da5c369Sopenharmony_ci unsafe { 18633da5c369Sopenharmony_ci let mut ss: Self = mem::zeroed(); 18643da5c369Sopenharmony_ci ss.sin6 = SockaddrIn6::from(s); 18653da5c369Sopenharmony_ci ss 18663da5c369Sopenharmony_ci } 18673da5c369Sopenharmony_ci } 18683da5c369Sopenharmony_ci} 18693da5c369Sopenharmony_ci 18703da5c369Sopenharmony_ci#[cfg(feature = "net")] 18713da5c369Sopenharmony_ciimpl From<net::SocketAddr> for SockaddrStorage { 18723da5c369Sopenharmony_ci fn from(s: net::SocketAddr) -> Self { 18733da5c369Sopenharmony_ci match s { 18743da5c369Sopenharmony_ci net::SocketAddr::V4(sa4) => Self::from(sa4), 18753da5c369Sopenharmony_ci net::SocketAddr::V6(sa6) => Self::from(sa6), 18763da5c369Sopenharmony_ci } 18773da5c369Sopenharmony_ci } 18783da5c369Sopenharmony_ci} 18793da5c369Sopenharmony_ci 18803da5c369Sopenharmony_ciimpl Hash for SockaddrStorage { 18813da5c369Sopenharmony_ci fn hash<H: Hasher>(&self, s: &mut H) { 18823da5c369Sopenharmony_ci unsafe { 18833da5c369Sopenharmony_ci match self.ss.ss_family as i32 { 18843da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 18853da5c369Sopenharmony_ci libc::AF_ALG => self.alg.hash(s), 18863da5c369Sopenharmony_ci #[cfg(feature = "net")] 18873da5c369Sopenharmony_ci libc::AF_INET => self.sin.hash(s), 18883da5c369Sopenharmony_ci #[cfg(feature = "net")] 18893da5c369Sopenharmony_ci libc::AF_INET6 => self.sin6.hash(s), 18903da5c369Sopenharmony_ci #[cfg(any( 18913da5c369Sopenharmony_ci target_os = "dragonfly", 18923da5c369Sopenharmony_ci target_os = "freebsd", 18933da5c369Sopenharmony_ci target_os = "ios", 18943da5c369Sopenharmony_ci target_os = "macos", 18953da5c369Sopenharmony_ci target_os = "illumos", 18963da5c369Sopenharmony_ci target_os = "netbsd", 18973da5c369Sopenharmony_ci target_os = "openbsd" 18983da5c369Sopenharmony_ci ))] 18993da5c369Sopenharmony_ci #[cfg(feature = "net")] 19003da5c369Sopenharmony_ci libc::AF_LINK => self.dl.hash(s), 19013da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19023da5c369Sopenharmony_ci libc::AF_NETLINK => self.nl.hash(s), 19033da5c369Sopenharmony_ci #[cfg(any( 19043da5c369Sopenharmony_ci target_os = "android", 19053da5c369Sopenharmony_ci target_os = "linux", 19063da5c369Sopenharmony_ci target_os = "fuchsia" 19073da5c369Sopenharmony_ci ))] 19083da5c369Sopenharmony_ci #[cfg(feature = "net")] 19093da5c369Sopenharmony_ci libc::AF_PACKET => self.dl.hash(s), 19103da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 19113da5c369Sopenharmony_ci #[cfg(feature = "ioctl")] 19123da5c369Sopenharmony_ci libc::AF_SYSTEM => self.sctl.hash(s), 19133da5c369Sopenharmony_ci libc::AF_UNIX => self.su.hash(s), 19143da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19153da5c369Sopenharmony_ci libc::AF_VSOCK => self.vsock.hash(s), 19163da5c369Sopenharmony_ci _ => self.ss.hash(s), 19173da5c369Sopenharmony_ci } 19183da5c369Sopenharmony_ci } 19193da5c369Sopenharmony_ci } 19203da5c369Sopenharmony_ci} 19213da5c369Sopenharmony_ci 19223da5c369Sopenharmony_ciimpl PartialEq for SockaddrStorage { 19233da5c369Sopenharmony_ci fn eq(&self, other: &Self) -> bool { 19243da5c369Sopenharmony_ci unsafe { 19253da5c369Sopenharmony_ci match (self.ss.ss_family as i32, other.ss.ss_family as i32) { 19263da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19273da5c369Sopenharmony_ci (libc::AF_ALG, libc::AF_ALG) => self.alg == other.alg, 19283da5c369Sopenharmony_ci #[cfg(feature = "net")] 19293da5c369Sopenharmony_ci (libc::AF_INET, libc::AF_INET) => self.sin == other.sin, 19303da5c369Sopenharmony_ci #[cfg(feature = "net")] 19313da5c369Sopenharmony_ci (libc::AF_INET6, libc::AF_INET6) => self.sin6 == other.sin6, 19323da5c369Sopenharmony_ci #[cfg(any( 19333da5c369Sopenharmony_ci target_os = "dragonfly", 19343da5c369Sopenharmony_ci target_os = "freebsd", 19353da5c369Sopenharmony_ci target_os = "ios", 19363da5c369Sopenharmony_ci target_os = "macos", 19373da5c369Sopenharmony_ci target_os = "illumos", 19383da5c369Sopenharmony_ci target_os = "netbsd", 19393da5c369Sopenharmony_ci target_os = "openbsd" 19403da5c369Sopenharmony_ci ))] 19413da5c369Sopenharmony_ci #[cfg(feature = "net")] 19423da5c369Sopenharmony_ci (libc::AF_LINK, libc::AF_LINK) => self.dl == other.dl, 19433da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19443da5c369Sopenharmony_ci (libc::AF_NETLINK, libc::AF_NETLINK) => self.nl == other.nl, 19453da5c369Sopenharmony_ci #[cfg(any( 19463da5c369Sopenharmony_ci target_os = "android", 19473da5c369Sopenharmony_ci target_os = "fuchsia", 19483da5c369Sopenharmony_ci target_os = "linux" 19493da5c369Sopenharmony_ci ))] 19503da5c369Sopenharmony_ci #[cfg(feature = "net")] 19513da5c369Sopenharmony_ci (libc::AF_PACKET, libc::AF_PACKET) => self.dl == other.dl, 19523da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 19533da5c369Sopenharmony_ci #[cfg(feature = "ioctl")] 19543da5c369Sopenharmony_ci (libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl, 19553da5c369Sopenharmony_ci (libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su, 19563da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19573da5c369Sopenharmony_ci (libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock, 19583da5c369Sopenharmony_ci _ => false, 19593da5c369Sopenharmony_ci } 19603da5c369Sopenharmony_ci } 19613da5c369Sopenharmony_ci } 19623da5c369Sopenharmony_ci} 19633da5c369Sopenharmony_ci 19643da5c369Sopenharmony_cimod private { 19653da5c369Sopenharmony_ci pub trait SockaddrLikePriv { 19663da5c369Sopenharmony_ci /// Returns a mutable raw pointer to the inner structure. 19673da5c369Sopenharmony_ci /// 19683da5c369Sopenharmony_ci /// # Safety 19693da5c369Sopenharmony_ci /// 19703da5c369Sopenharmony_ci /// This method is technically safe, but modifying the inner structure's 19713da5c369Sopenharmony_ci /// `family` or `len` fields may result in violating Nix's invariants. 19723da5c369Sopenharmony_ci /// It is best to use this method only with foreign functions that do 19733da5c369Sopenharmony_ci /// not change the sockaddr type. 19743da5c369Sopenharmony_ci fn as_mut_ptr(&mut self) -> *mut libc::sockaddr { 19753da5c369Sopenharmony_ci self as *mut Self as *mut libc::sockaddr 19763da5c369Sopenharmony_ci } 19773da5c369Sopenharmony_ci } 19783da5c369Sopenharmony_ci} 19793da5c369Sopenharmony_ci 19803da5c369Sopenharmony_ci/// Represents a socket address 19813da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 19823da5c369Sopenharmony_ci#[deprecated( 19833da5c369Sopenharmony_ci since = "0.24.0", 19843da5c369Sopenharmony_ci note = "use SockaddrLike or SockaddrStorage instead" 19853da5c369Sopenharmony_ci)] 19863da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 19873da5c369Sopenharmony_ci#[allow(deprecated)] 19883da5c369Sopenharmony_ci#[non_exhaustive] 19893da5c369Sopenharmony_cipub enum SockAddr { 19903da5c369Sopenharmony_ci #[cfg(feature = "net")] 19913da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(feature = "net")))] 19923da5c369Sopenharmony_ci Inet(InetAddr), 19933da5c369Sopenharmony_ci Unix(UnixAddr), 19943da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19953da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 19963da5c369Sopenharmony_ci Netlink(NetlinkAddr), 19973da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 19983da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 19993da5c369Sopenharmony_ci Alg(AlgAddr), 20003da5c369Sopenharmony_ci #[cfg(all( 20013da5c369Sopenharmony_ci feature = "ioctl", 20023da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 20033da5c369Sopenharmony_ci ))] 20043da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] 20053da5c369Sopenharmony_ci SysControl(SysControlAddr), 20063da5c369Sopenharmony_ci /// Datalink address (MAC) 20073da5c369Sopenharmony_ci #[cfg(any( 20083da5c369Sopenharmony_ci target_os = "android", 20093da5c369Sopenharmony_ci target_os = "dragonfly", 20103da5c369Sopenharmony_ci target_os = "freebsd", 20113da5c369Sopenharmony_ci target_os = "ios", 20123da5c369Sopenharmony_ci target_os = "linux", 20133da5c369Sopenharmony_ci target_os = "macos", 20143da5c369Sopenharmony_ci target_os = "illumos", 20153da5c369Sopenharmony_ci target_os = "netbsd", 20163da5c369Sopenharmony_ci target_os = "openbsd" 20173da5c369Sopenharmony_ci ))] 20183da5c369Sopenharmony_ci #[cfg(feature = "net")] 20193da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(feature = "net")))] 20203da5c369Sopenharmony_ci Link(LinkAddr), 20213da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20223da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 20233da5c369Sopenharmony_ci Vsock(VsockAddr), 20243da5c369Sopenharmony_ci} 20253da5c369Sopenharmony_ci 20263da5c369Sopenharmony_ci#[allow(missing_docs)] // Since they're all deprecated anyway 20273da5c369Sopenharmony_ci#[allow(deprecated)] 20283da5c369Sopenharmony_ciimpl SockAddr { 20293da5c369Sopenharmony_ci feature! { 20303da5c369Sopenharmony_ci #![feature = "net"] 20313da5c369Sopenharmony_ci pub fn new_inet(addr: InetAddr) -> SockAddr { 20323da5c369Sopenharmony_ci SockAddr::Inet(addr) 20333da5c369Sopenharmony_ci } 20343da5c369Sopenharmony_ci } 20353da5c369Sopenharmony_ci 20363da5c369Sopenharmony_ci pub fn new_unix<P: ?Sized + NixPath>(path: &P) -> Result<SockAddr> { 20373da5c369Sopenharmony_ci Ok(SockAddr::Unix(UnixAddr::new(path)?)) 20383da5c369Sopenharmony_ci } 20393da5c369Sopenharmony_ci 20403da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20413da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 20423da5c369Sopenharmony_ci pub fn new_netlink(pid: u32, groups: u32) -> SockAddr { 20433da5c369Sopenharmony_ci SockAddr::Netlink(NetlinkAddr::new(pid, groups)) 20443da5c369Sopenharmony_ci } 20453da5c369Sopenharmony_ci 20463da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20473da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 20483da5c369Sopenharmony_ci pub fn new_alg(alg_type: &str, alg_name: &str) -> SockAddr { 20493da5c369Sopenharmony_ci SockAddr::Alg(AlgAddr::new(alg_type, alg_name)) 20503da5c369Sopenharmony_ci } 20513da5c369Sopenharmony_ci 20523da5c369Sopenharmony_ci feature! { 20533da5c369Sopenharmony_ci #![feature = "ioctl"] 20543da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 20553da5c369Sopenharmony_ci pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result<SockAddr> { 20563da5c369Sopenharmony_ci SysControlAddr::from_name(sockfd, name, unit).map(SockAddr::SysControl) 20573da5c369Sopenharmony_ci } 20583da5c369Sopenharmony_ci } 20593da5c369Sopenharmony_ci 20603da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20613da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 20623da5c369Sopenharmony_ci pub fn new_vsock(cid: u32, port: u32) -> SockAddr { 20633da5c369Sopenharmony_ci SockAddr::Vsock(VsockAddr::new(cid, port)) 20643da5c369Sopenharmony_ci } 20653da5c369Sopenharmony_ci 20663da5c369Sopenharmony_ci pub fn family(&self) -> AddressFamily { 20673da5c369Sopenharmony_ci match *self { 20683da5c369Sopenharmony_ci #[cfg(feature = "net")] 20693da5c369Sopenharmony_ci SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet, 20703da5c369Sopenharmony_ci #[cfg(feature = "net")] 20713da5c369Sopenharmony_ci SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6, 20723da5c369Sopenharmony_ci SockAddr::Unix(..) => AddressFamily::Unix, 20733da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20743da5c369Sopenharmony_ci SockAddr::Netlink(..) => AddressFamily::Netlink, 20753da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20763da5c369Sopenharmony_ci SockAddr::Alg(..) => AddressFamily::Alg, 20773da5c369Sopenharmony_ci #[cfg(all( 20783da5c369Sopenharmony_ci feature = "ioctl", 20793da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 20803da5c369Sopenharmony_ci ))] 20813da5c369Sopenharmony_ci SockAddr::SysControl(..) => AddressFamily::System, 20823da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20833da5c369Sopenharmony_ci #[cfg(feature = "net")] 20843da5c369Sopenharmony_ci SockAddr::Link(..) => AddressFamily::Packet, 20853da5c369Sopenharmony_ci #[cfg(any( 20863da5c369Sopenharmony_ci target_os = "dragonfly", 20873da5c369Sopenharmony_ci target_os = "freebsd", 20883da5c369Sopenharmony_ci target_os = "ios", 20893da5c369Sopenharmony_ci target_os = "macos", 20903da5c369Sopenharmony_ci target_os = "netbsd", 20913da5c369Sopenharmony_ci target_os = "illumos", 20923da5c369Sopenharmony_ci target_os = "openbsd" 20933da5c369Sopenharmony_ci ))] 20943da5c369Sopenharmony_ci #[cfg(feature = "net")] 20953da5c369Sopenharmony_ci SockAddr::Link(..) => AddressFamily::Link, 20963da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 20973da5c369Sopenharmony_ci SockAddr::Vsock(..) => AddressFamily::Vsock, 20983da5c369Sopenharmony_ci } 20993da5c369Sopenharmony_ci } 21003da5c369Sopenharmony_ci 21013da5c369Sopenharmony_ci #[deprecated(since = "0.23.0", note = "use .to_string() instead")] 21023da5c369Sopenharmony_ci pub fn to_str(&self) -> String { 21033da5c369Sopenharmony_ci format!("{}", self) 21043da5c369Sopenharmony_ci } 21053da5c369Sopenharmony_ci 21063da5c369Sopenharmony_ci /// Creates a `SockAddr` struct from libc's sockaddr. 21073da5c369Sopenharmony_ci /// 21083da5c369Sopenharmony_ci /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System. 21093da5c369Sopenharmony_ci /// Returns None for unsupported families. 21103da5c369Sopenharmony_ci /// 21113da5c369Sopenharmony_ci /// # Safety 21123da5c369Sopenharmony_ci /// 21133da5c369Sopenharmony_ci /// unsafe because it takes a raw pointer as argument. The caller must 21143da5c369Sopenharmony_ci /// ensure that the pointer is valid. 21153da5c369Sopenharmony_ci #[cfg(not(target_os = "fuchsia"))] 21163da5c369Sopenharmony_ci #[cfg(feature = "net")] 21173da5c369Sopenharmony_ci pub(crate) unsafe fn from_libc_sockaddr( 21183da5c369Sopenharmony_ci addr: *const libc::sockaddr, 21193da5c369Sopenharmony_ci ) -> Option<SockAddr> { 21203da5c369Sopenharmony_ci if addr.is_null() { 21213da5c369Sopenharmony_ci None 21223da5c369Sopenharmony_ci } else { 21233da5c369Sopenharmony_ci match AddressFamily::from_i32(i32::from((*addr).sa_family)) { 21243da5c369Sopenharmony_ci Some(AddressFamily::Unix) => None, 21253da5c369Sopenharmony_ci #[cfg(feature = "net")] 21263da5c369Sopenharmony_ci Some(AddressFamily::Inet) => Some(SockAddr::Inet( 21273da5c369Sopenharmony_ci InetAddr::V4(ptr::read_unaligned(addr as *const _)), 21283da5c369Sopenharmony_ci )), 21293da5c369Sopenharmony_ci #[cfg(feature = "net")] 21303da5c369Sopenharmony_ci Some(AddressFamily::Inet6) => Some(SockAddr::Inet( 21313da5c369Sopenharmony_ci InetAddr::V6(ptr::read_unaligned(addr as *const _)), 21323da5c369Sopenharmony_ci )), 21333da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 21343da5c369Sopenharmony_ci Some(AddressFamily::Netlink) => Some(SockAddr::Netlink( 21353da5c369Sopenharmony_ci NetlinkAddr(ptr::read_unaligned(addr as *const _)), 21363da5c369Sopenharmony_ci )), 21373da5c369Sopenharmony_ci #[cfg(all( 21383da5c369Sopenharmony_ci feature = "ioctl", 21393da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 21403da5c369Sopenharmony_ci ))] 21413da5c369Sopenharmony_ci Some(AddressFamily::System) => Some(SockAddr::SysControl( 21423da5c369Sopenharmony_ci SysControlAddr(ptr::read_unaligned(addr as *const _)), 21433da5c369Sopenharmony_ci )), 21443da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 21453da5c369Sopenharmony_ci #[cfg(feature = "net")] 21463da5c369Sopenharmony_ci Some(AddressFamily::Packet) => Some(SockAddr::Link(LinkAddr( 21473da5c369Sopenharmony_ci ptr::read_unaligned(addr as *const _), 21483da5c369Sopenharmony_ci ))), 21493da5c369Sopenharmony_ci #[cfg(any( 21503da5c369Sopenharmony_ci target_os = "dragonfly", 21513da5c369Sopenharmony_ci target_os = "freebsd", 21523da5c369Sopenharmony_ci target_os = "ios", 21533da5c369Sopenharmony_ci target_os = "macos", 21543da5c369Sopenharmony_ci target_os = "netbsd", 21553da5c369Sopenharmony_ci target_os = "illumos", 21563da5c369Sopenharmony_ci target_os = "openbsd" 21573da5c369Sopenharmony_ci ))] 21583da5c369Sopenharmony_ci #[cfg(feature = "net")] 21593da5c369Sopenharmony_ci Some(AddressFamily::Link) => { 21603da5c369Sopenharmony_ci let ether_addr = 21613da5c369Sopenharmony_ci LinkAddr(ptr::read_unaligned(addr as *const _)); 21623da5c369Sopenharmony_ci if ether_addr.is_empty() { 21633da5c369Sopenharmony_ci None 21643da5c369Sopenharmony_ci } else { 21653da5c369Sopenharmony_ci Some(SockAddr::Link(ether_addr)) 21663da5c369Sopenharmony_ci } 21673da5c369Sopenharmony_ci } 21683da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 21693da5c369Sopenharmony_ci Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(VsockAddr( 21703da5c369Sopenharmony_ci ptr::read_unaligned(addr as *const _), 21713da5c369Sopenharmony_ci ))), 21723da5c369Sopenharmony_ci // Other address families are currently not supported and simply yield a None 21733da5c369Sopenharmony_ci // entry instead of a proper conversion to a `SockAddr`. 21743da5c369Sopenharmony_ci Some(_) | None => None, 21753da5c369Sopenharmony_ci } 21763da5c369Sopenharmony_ci } 21773da5c369Sopenharmony_ci } 21783da5c369Sopenharmony_ci 21793da5c369Sopenharmony_ci /// Conversion from nix's SockAddr type to the underlying libc sockaddr type. 21803da5c369Sopenharmony_ci /// 21813da5c369Sopenharmony_ci /// This is useful for interfacing with other libc functions that don't yet have nix wrappers. 21823da5c369Sopenharmony_ci /// Returns a reference to the underlying data type (as a sockaddr reference) along 21833da5c369Sopenharmony_ci /// with the size of the actual data type. sockaddr is commonly used as a proxy for 21843da5c369Sopenharmony_ci /// a superclass as C doesn't support inheritance, so many functions that take 21853da5c369Sopenharmony_ci /// a sockaddr * need to take the size of the underlying type as well and then internally cast it back. 21863da5c369Sopenharmony_ci pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) { 21873da5c369Sopenharmony_ci match *self { 21883da5c369Sopenharmony_ci #[cfg(feature = "net")] 21893da5c369Sopenharmony_ci SockAddr::Inet(InetAddr::V4(ref addr)) => ( 21903da5c369Sopenharmony_ci // This cast is always allowed in C 21913da5c369Sopenharmony_ci unsafe { 21923da5c369Sopenharmony_ci &*(addr as *const libc::sockaddr_in 21933da5c369Sopenharmony_ci as *const libc::sockaddr) 21943da5c369Sopenharmony_ci }, 21953da5c369Sopenharmony_ci mem::size_of_val(addr) as libc::socklen_t, 21963da5c369Sopenharmony_ci ), 21973da5c369Sopenharmony_ci #[cfg(feature = "net")] 21983da5c369Sopenharmony_ci SockAddr::Inet(InetAddr::V6(ref addr)) => ( 21993da5c369Sopenharmony_ci // This cast is always allowed in C 22003da5c369Sopenharmony_ci unsafe { 22013da5c369Sopenharmony_ci &*(addr as *const libc::sockaddr_in6 22023da5c369Sopenharmony_ci as *const libc::sockaddr) 22033da5c369Sopenharmony_ci }, 22043da5c369Sopenharmony_ci mem::size_of_val(addr) as libc::socklen_t, 22053da5c369Sopenharmony_ci ), 22063da5c369Sopenharmony_ci SockAddr::Unix(ref unix_addr) => ( 22073da5c369Sopenharmony_ci // This cast is always allowed in C 22083da5c369Sopenharmony_ci unsafe { 22093da5c369Sopenharmony_ci &*(&unix_addr.sun as *const libc::sockaddr_un 22103da5c369Sopenharmony_ci as *const libc::sockaddr) 22113da5c369Sopenharmony_ci }, 22123da5c369Sopenharmony_ci unix_addr.sun_len() as libc::socklen_t, 22133da5c369Sopenharmony_ci ), 22143da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 22153da5c369Sopenharmony_ci SockAddr::Netlink(NetlinkAddr(ref sa)) => ( 22163da5c369Sopenharmony_ci // This cast is always allowed in C 22173da5c369Sopenharmony_ci unsafe { 22183da5c369Sopenharmony_ci &*(sa as *const libc::sockaddr_nl as *const libc::sockaddr) 22193da5c369Sopenharmony_ci }, 22203da5c369Sopenharmony_ci mem::size_of_val(sa) as libc::socklen_t, 22213da5c369Sopenharmony_ci ), 22223da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 22233da5c369Sopenharmony_ci SockAddr::Alg(AlgAddr(ref sa)) => ( 22243da5c369Sopenharmony_ci // This cast is always allowed in C 22253da5c369Sopenharmony_ci unsafe { 22263da5c369Sopenharmony_ci &*(sa as *const libc::sockaddr_alg as *const libc::sockaddr) 22273da5c369Sopenharmony_ci }, 22283da5c369Sopenharmony_ci mem::size_of_val(sa) as libc::socklen_t, 22293da5c369Sopenharmony_ci ), 22303da5c369Sopenharmony_ci #[cfg(all( 22313da5c369Sopenharmony_ci feature = "ioctl", 22323da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 22333da5c369Sopenharmony_ci ))] 22343da5c369Sopenharmony_ci SockAddr::SysControl(SysControlAddr(ref sa)) => ( 22353da5c369Sopenharmony_ci // This cast is always allowed in C 22363da5c369Sopenharmony_ci unsafe { 22373da5c369Sopenharmony_ci &*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr) 22383da5c369Sopenharmony_ci }, 22393da5c369Sopenharmony_ci mem::size_of_val(sa) as libc::socklen_t, 22403da5c369Sopenharmony_ci ), 22413da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 22423da5c369Sopenharmony_ci #[cfg(feature = "net")] 22433da5c369Sopenharmony_ci SockAddr::Link(LinkAddr(ref addr)) => ( 22443da5c369Sopenharmony_ci // This cast is always allowed in C 22453da5c369Sopenharmony_ci unsafe { 22463da5c369Sopenharmony_ci &*(addr as *const libc::sockaddr_ll 22473da5c369Sopenharmony_ci as *const libc::sockaddr) 22483da5c369Sopenharmony_ci }, 22493da5c369Sopenharmony_ci mem::size_of_val(addr) as libc::socklen_t, 22503da5c369Sopenharmony_ci ), 22513da5c369Sopenharmony_ci #[cfg(any( 22523da5c369Sopenharmony_ci target_os = "dragonfly", 22533da5c369Sopenharmony_ci target_os = "freebsd", 22543da5c369Sopenharmony_ci target_os = "ios", 22553da5c369Sopenharmony_ci target_os = "macos", 22563da5c369Sopenharmony_ci target_os = "illumos", 22573da5c369Sopenharmony_ci target_os = "netbsd", 22583da5c369Sopenharmony_ci target_os = "openbsd" 22593da5c369Sopenharmony_ci ))] 22603da5c369Sopenharmony_ci #[cfg(feature = "net")] 22613da5c369Sopenharmony_ci SockAddr::Link(LinkAddr(ref addr)) => ( 22623da5c369Sopenharmony_ci // This cast is always allowed in C 22633da5c369Sopenharmony_ci unsafe { 22643da5c369Sopenharmony_ci &*(addr as *const libc::sockaddr_dl 22653da5c369Sopenharmony_ci as *const libc::sockaddr) 22663da5c369Sopenharmony_ci }, 22673da5c369Sopenharmony_ci mem::size_of_val(addr) as libc::socklen_t, 22683da5c369Sopenharmony_ci ), 22693da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 22703da5c369Sopenharmony_ci SockAddr::Vsock(VsockAddr(ref sa)) => ( 22713da5c369Sopenharmony_ci // This cast is always allowed in C 22723da5c369Sopenharmony_ci unsafe { 22733da5c369Sopenharmony_ci &*(sa as *const libc::sockaddr_vm as *const libc::sockaddr) 22743da5c369Sopenharmony_ci }, 22753da5c369Sopenharmony_ci mem::size_of_val(sa) as libc::socklen_t, 22763da5c369Sopenharmony_ci ), 22773da5c369Sopenharmony_ci } 22783da5c369Sopenharmony_ci } 22793da5c369Sopenharmony_ci} 22803da5c369Sopenharmony_ci 22813da5c369Sopenharmony_ci#[allow(deprecated)] 22823da5c369Sopenharmony_ciimpl fmt::Display for SockAddr { 22833da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 22843da5c369Sopenharmony_ci match *self { 22853da5c369Sopenharmony_ci #[cfg(feature = "net")] 22863da5c369Sopenharmony_ci SockAddr::Inet(ref inet) => inet.fmt(f), 22873da5c369Sopenharmony_ci SockAddr::Unix(ref unix) => unix.fmt(f), 22883da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 22893da5c369Sopenharmony_ci SockAddr::Netlink(ref nl) => nl.fmt(f), 22903da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 22913da5c369Sopenharmony_ci SockAddr::Alg(ref nl) => nl.fmt(f), 22923da5c369Sopenharmony_ci #[cfg(all( 22933da5c369Sopenharmony_ci feature = "ioctl", 22943da5c369Sopenharmony_ci any(target_os = "ios", target_os = "macos") 22953da5c369Sopenharmony_ci ))] 22963da5c369Sopenharmony_ci SockAddr::SysControl(ref sc) => sc.fmt(f), 22973da5c369Sopenharmony_ci #[cfg(any( 22983da5c369Sopenharmony_ci target_os = "android", 22993da5c369Sopenharmony_ci target_os = "dragonfly", 23003da5c369Sopenharmony_ci target_os = "freebsd", 23013da5c369Sopenharmony_ci target_os = "ios", 23023da5c369Sopenharmony_ci target_os = "linux", 23033da5c369Sopenharmony_ci target_os = "macos", 23043da5c369Sopenharmony_ci target_os = "netbsd", 23053da5c369Sopenharmony_ci target_os = "illumos", 23063da5c369Sopenharmony_ci target_os = "openbsd" 23073da5c369Sopenharmony_ci ))] 23083da5c369Sopenharmony_ci #[cfg(feature = "net")] 23093da5c369Sopenharmony_ci SockAddr::Link(ref ether_addr) => ether_addr.fmt(f), 23103da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 23113da5c369Sopenharmony_ci SockAddr::Vsock(ref svm) => svm.fmt(f), 23123da5c369Sopenharmony_ci } 23133da5c369Sopenharmony_ci } 23143da5c369Sopenharmony_ci} 23153da5c369Sopenharmony_ci 23163da5c369Sopenharmony_ci#[cfg(not(target_os = "fuchsia"))] 23173da5c369Sopenharmony_ci#[cfg(feature = "net")] 23183da5c369Sopenharmony_ci#[allow(deprecated)] 23193da5c369Sopenharmony_ciimpl private::SockaddrLikePriv for SockAddr {} 23203da5c369Sopenharmony_ci#[cfg(not(target_os = "fuchsia"))] 23213da5c369Sopenharmony_ci#[cfg(feature = "net")] 23223da5c369Sopenharmony_ci#[allow(deprecated)] 23233da5c369Sopenharmony_ciimpl SockaddrLike for SockAddr { 23243da5c369Sopenharmony_ci unsafe fn from_raw( 23253da5c369Sopenharmony_ci addr: *const libc::sockaddr, 23263da5c369Sopenharmony_ci _len: Option<libc::socklen_t>, 23273da5c369Sopenharmony_ci ) -> Option<Self> { 23283da5c369Sopenharmony_ci Self::from_libc_sockaddr(addr) 23293da5c369Sopenharmony_ci } 23303da5c369Sopenharmony_ci} 23313da5c369Sopenharmony_ci 23323da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 23333da5c369Sopenharmony_ci#[cfg_attr(docsrs, doc(cfg(all())))] 23343da5c369Sopenharmony_cipub mod netlink { 23353da5c369Sopenharmony_ci use super::*; 23363da5c369Sopenharmony_ci use crate::sys::socket::addr::AddressFamily; 23373da5c369Sopenharmony_ci use libc::{sa_family_t, sockaddr_nl}; 23383da5c369Sopenharmony_ci use std::{fmt, mem}; 23393da5c369Sopenharmony_ci 23403da5c369Sopenharmony_ci /// Address for the Linux kernel user interface device. 23413da5c369Sopenharmony_ci /// 23423da5c369Sopenharmony_ci /// # References 23433da5c369Sopenharmony_ci /// 23443da5c369Sopenharmony_ci /// [netlink(7)](https://man7.org/linux/man-pages/man7/netlink.7.html) 23453da5c369Sopenharmony_ci #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 23463da5c369Sopenharmony_ci #[repr(transparent)] 23473da5c369Sopenharmony_ci pub struct NetlinkAddr(pub(in super::super) sockaddr_nl); 23483da5c369Sopenharmony_ci 23493da5c369Sopenharmony_ci impl NetlinkAddr { 23503da5c369Sopenharmony_ci /// Construct a new socket address from its port ID and multicast groups 23513da5c369Sopenharmony_ci /// mask. 23523da5c369Sopenharmony_ci pub fn new(pid: u32, groups: u32) -> NetlinkAddr { 23533da5c369Sopenharmony_ci let mut addr: sockaddr_nl = unsafe { mem::zeroed() }; 23543da5c369Sopenharmony_ci addr.nl_family = AddressFamily::Netlink as sa_family_t; 23553da5c369Sopenharmony_ci addr.nl_pid = pid; 23563da5c369Sopenharmony_ci addr.nl_groups = groups; 23573da5c369Sopenharmony_ci 23583da5c369Sopenharmony_ci NetlinkAddr(addr) 23593da5c369Sopenharmony_ci } 23603da5c369Sopenharmony_ci 23613da5c369Sopenharmony_ci /// Return the socket's port ID. 23623da5c369Sopenharmony_ci pub const fn pid(&self) -> u32 { 23633da5c369Sopenharmony_ci self.0.nl_pid 23643da5c369Sopenharmony_ci } 23653da5c369Sopenharmony_ci 23663da5c369Sopenharmony_ci /// Return the socket's multicast groups mask 23673da5c369Sopenharmony_ci pub const fn groups(&self) -> u32 { 23683da5c369Sopenharmony_ci self.0.nl_groups 23693da5c369Sopenharmony_ci } 23703da5c369Sopenharmony_ci } 23713da5c369Sopenharmony_ci 23723da5c369Sopenharmony_ci impl private::SockaddrLikePriv for NetlinkAddr {} 23733da5c369Sopenharmony_ci impl SockaddrLike for NetlinkAddr { 23743da5c369Sopenharmony_ci unsafe fn from_raw( 23753da5c369Sopenharmony_ci addr: *const libc::sockaddr, 23763da5c369Sopenharmony_ci len: Option<libc::socklen_t>, 23773da5c369Sopenharmony_ci ) -> Option<Self> 23783da5c369Sopenharmony_ci where 23793da5c369Sopenharmony_ci Self: Sized, 23803da5c369Sopenharmony_ci { 23813da5c369Sopenharmony_ci if let Some(l) = len { 23823da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_nl>() as libc::socklen_t { 23833da5c369Sopenharmony_ci return None; 23843da5c369Sopenharmony_ci } 23853da5c369Sopenharmony_ci } 23863da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_NETLINK { 23873da5c369Sopenharmony_ci return None; 23883da5c369Sopenharmony_ci } 23893da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 23903da5c369Sopenharmony_ci } 23913da5c369Sopenharmony_ci } 23923da5c369Sopenharmony_ci 23933da5c369Sopenharmony_ci impl AsRef<libc::sockaddr_nl> for NetlinkAddr { 23943da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_nl { 23953da5c369Sopenharmony_ci &self.0 23963da5c369Sopenharmony_ci } 23973da5c369Sopenharmony_ci } 23983da5c369Sopenharmony_ci 23993da5c369Sopenharmony_ci impl fmt::Display for NetlinkAddr { 24003da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 24013da5c369Sopenharmony_ci write!(f, "pid: {} groups: {}", self.pid(), self.groups()) 24023da5c369Sopenharmony_ci } 24033da5c369Sopenharmony_ci } 24043da5c369Sopenharmony_ci} 24053da5c369Sopenharmony_ci 24063da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 24073da5c369Sopenharmony_ci#[cfg_attr(docsrs, doc(cfg(all())))] 24083da5c369Sopenharmony_cipub mod alg { 24093da5c369Sopenharmony_ci use super::*; 24103da5c369Sopenharmony_ci use libc::{c_char, sockaddr_alg, AF_ALG}; 24113da5c369Sopenharmony_ci use std::ffi::CStr; 24123da5c369Sopenharmony_ci use std::hash::{Hash, Hasher}; 24133da5c369Sopenharmony_ci use std::{fmt, mem, str}; 24143da5c369Sopenharmony_ci 24153da5c369Sopenharmony_ci /// Socket address for the Linux kernel crypto API 24163da5c369Sopenharmony_ci #[derive(Copy, Clone)] 24173da5c369Sopenharmony_ci #[repr(transparent)] 24183da5c369Sopenharmony_ci pub struct AlgAddr(pub(in super::super) sockaddr_alg); 24193da5c369Sopenharmony_ci 24203da5c369Sopenharmony_ci impl private::SockaddrLikePriv for AlgAddr {} 24213da5c369Sopenharmony_ci impl SockaddrLike for AlgAddr { 24223da5c369Sopenharmony_ci unsafe fn from_raw( 24233da5c369Sopenharmony_ci addr: *const libc::sockaddr, 24243da5c369Sopenharmony_ci l: Option<libc::socklen_t>, 24253da5c369Sopenharmony_ci ) -> Option<Self> 24263da5c369Sopenharmony_ci where 24273da5c369Sopenharmony_ci Self: Sized, 24283da5c369Sopenharmony_ci { 24293da5c369Sopenharmony_ci if let Some(l) = l { 24303da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_alg>() as libc::socklen_t 24313da5c369Sopenharmony_ci { 24323da5c369Sopenharmony_ci return None; 24333da5c369Sopenharmony_ci } 24343da5c369Sopenharmony_ci } 24353da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_ALG { 24363da5c369Sopenharmony_ci return None; 24373da5c369Sopenharmony_ci } 24383da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 24393da5c369Sopenharmony_ci } 24403da5c369Sopenharmony_ci } 24413da5c369Sopenharmony_ci 24423da5c369Sopenharmony_ci impl AsRef<libc::sockaddr_alg> for AlgAddr { 24433da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_alg { 24443da5c369Sopenharmony_ci &self.0 24453da5c369Sopenharmony_ci } 24463da5c369Sopenharmony_ci } 24473da5c369Sopenharmony_ci 24483da5c369Sopenharmony_ci // , PartialEq, Eq, Debug, Hash 24493da5c369Sopenharmony_ci impl PartialEq for AlgAddr { 24503da5c369Sopenharmony_ci fn eq(&self, other: &Self) -> bool { 24513da5c369Sopenharmony_ci let (inner, other) = (self.0, other.0); 24523da5c369Sopenharmony_ci ( 24533da5c369Sopenharmony_ci inner.salg_family, 24543da5c369Sopenharmony_ci &inner.salg_type[..], 24553da5c369Sopenharmony_ci inner.salg_feat, 24563da5c369Sopenharmony_ci inner.salg_mask, 24573da5c369Sopenharmony_ci &inner.salg_name[..], 24583da5c369Sopenharmony_ci ) == ( 24593da5c369Sopenharmony_ci other.salg_family, 24603da5c369Sopenharmony_ci &other.salg_type[..], 24613da5c369Sopenharmony_ci other.salg_feat, 24623da5c369Sopenharmony_ci other.salg_mask, 24633da5c369Sopenharmony_ci &other.salg_name[..], 24643da5c369Sopenharmony_ci ) 24653da5c369Sopenharmony_ci } 24663da5c369Sopenharmony_ci } 24673da5c369Sopenharmony_ci 24683da5c369Sopenharmony_ci impl Eq for AlgAddr {} 24693da5c369Sopenharmony_ci 24703da5c369Sopenharmony_ci impl Hash for AlgAddr { 24713da5c369Sopenharmony_ci fn hash<H: Hasher>(&self, s: &mut H) { 24723da5c369Sopenharmony_ci let inner = self.0; 24733da5c369Sopenharmony_ci ( 24743da5c369Sopenharmony_ci inner.salg_family, 24753da5c369Sopenharmony_ci &inner.salg_type[..], 24763da5c369Sopenharmony_ci inner.salg_feat, 24773da5c369Sopenharmony_ci inner.salg_mask, 24783da5c369Sopenharmony_ci &inner.salg_name[..], 24793da5c369Sopenharmony_ci ) 24803da5c369Sopenharmony_ci .hash(s); 24813da5c369Sopenharmony_ci } 24823da5c369Sopenharmony_ci } 24833da5c369Sopenharmony_ci 24843da5c369Sopenharmony_ci impl AlgAddr { 24853da5c369Sopenharmony_ci /// Construct an `AF_ALG` socket from its cipher name and type. 24863da5c369Sopenharmony_ci pub fn new(alg_type: &str, alg_name: &str) -> AlgAddr { 24873da5c369Sopenharmony_ci let mut addr: sockaddr_alg = unsafe { mem::zeroed() }; 24883da5c369Sopenharmony_ci addr.salg_family = AF_ALG as u16; 24893da5c369Sopenharmony_ci addr.salg_type[..alg_type.len()] 24903da5c369Sopenharmony_ci .copy_from_slice(alg_type.to_string().as_bytes()); 24913da5c369Sopenharmony_ci addr.salg_name[..alg_name.len()] 24923da5c369Sopenharmony_ci .copy_from_slice(alg_name.to_string().as_bytes()); 24933da5c369Sopenharmony_ci 24943da5c369Sopenharmony_ci AlgAddr(addr) 24953da5c369Sopenharmony_ci } 24963da5c369Sopenharmony_ci 24973da5c369Sopenharmony_ci /// Return the socket's cipher type, for example `hash` or `aead`. 24983da5c369Sopenharmony_ci pub fn alg_type(&self) -> &CStr { 24993da5c369Sopenharmony_ci unsafe { 25003da5c369Sopenharmony_ci CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char) 25013da5c369Sopenharmony_ci } 25023da5c369Sopenharmony_ci } 25033da5c369Sopenharmony_ci 25043da5c369Sopenharmony_ci /// Return the socket's cipher name, for example `sha1`. 25053da5c369Sopenharmony_ci pub fn alg_name(&self) -> &CStr { 25063da5c369Sopenharmony_ci unsafe { 25073da5c369Sopenharmony_ci CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char) 25083da5c369Sopenharmony_ci } 25093da5c369Sopenharmony_ci } 25103da5c369Sopenharmony_ci } 25113da5c369Sopenharmony_ci 25123da5c369Sopenharmony_ci impl fmt::Display for AlgAddr { 25133da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 25143da5c369Sopenharmony_ci write!( 25153da5c369Sopenharmony_ci f, 25163da5c369Sopenharmony_ci "type: {} alg: {}", 25173da5c369Sopenharmony_ci self.alg_name().to_string_lossy(), 25183da5c369Sopenharmony_ci self.alg_type().to_string_lossy() 25193da5c369Sopenharmony_ci ) 25203da5c369Sopenharmony_ci } 25213da5c369Sopenharmony_ci } 25223da5c369Sopenharmony_ci 25233da5c369Sopenharmony_ci impl fmt::Debug for AlgAddr { 25243da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 25253da5c369Sopenharmony_ci fmt::Display::fmt(self, f) 25263da5c369Sopenharmony_ci } 25273da5c369Sopenharmony_ci } 25283da5c369Sopenharmony_ci} 25293da5c369Sopenharmony_ci 25303da5c369Sopenharmony_cifeature! { 25313da5c369Sopenharmony_ci#![feature = "ioctl"] 25323da5c369Sopenharmony_ci#[cfg(any(target_os = "ios", target_os = "macos"))] 25333da5c369Sopenharmony_cipub mod sys_control { 25343da5c369Sopenharmony_ci use crate::sys::socket::addr::AddressFamily; 25353da5c369Sopenharmony_ci use libc::{self, c_uchar}; 25363da5c369Sopenharmony_ci use std::{fmt, mem, ptr}; 25373da5c369Sopenharmony_ci use std::os::unix::io::RawFd; 25383da5c369Sopenharmony_ci use crate::{Errno, Result}; 25393da5c369Sopenharmony_ci use super::{private, SockaddrLike}; 25403da5c369Sopenharmony_ci 25413da5c369Sopenharmony_ci // FIXME: Move type into `libc` 25423da5c369Sopenharmony_ci #[repr(C)] 25433da5c369Sopenharmony_ci #[derive(Clone, Copy)] 25443da5c369Sopenharmony_ci #[allow(missing_debug_implementations)] 25453da5c369Sopenharmony_ci pub struct ctl_ioc_info { 25463da5c369Sopenharmony_ci pub ctl_id: u32, 25473da5c369Sopenharmony_ci pub ctl_name: [c_uchar; MAX_KCTL_NAME], 25483da5c369Sopenharmony_ci } 25493da5c369Sopenharmony_ci 25503da5c369Sopenharmony_ci const CTL_IOC_MAGIC: u8 = b'N'; 25513da5c369Sopenharmony_ci const CTL_IOC_INFO: u8 = 3; 25523da5c369Sopenharmony_ci const MAX_KCTL_NAME: usize = 96; 25533da5c369Sopenharmony_ci 25543da5c369Sopenharmony_ci ioctl_readwrite!(ctl_info, CTL_IOC_MAGIC, CTL_IOC_INFO, ctl_ioc_info); 25553da5c369Sopenharmony_ci 25563da5c369Sopenharmony_ci /// Apple system control socket 25573da5c369Sopenharmony_ci /// 25583da5c369Sopenharmony_ci /// # References 25593da5c369Sopenharmony_ci /// 25603da5c369Sopenharmony_ci /// <https://developer.apple.com/documentation/kernel/sockaddr_ctl> 25613da5c369Sopenharmony_ci #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 25623da5c369Sopenharmony_ci #[repr(transparent)] 25633da5c369Sopenharmony_ci pub struct SysControlAddr(pub(in super::super) libc::sockaddr_ctl); 25643da5c369Sopenharmony_ci 25653da5c369Sopenharmony_ci impl private::SockaddrLikePriv for SysControlAddr {} 25663da5c369Sopenharmony_ci impl SockaddrLike for SysControlAddr { 25673da5c369Sopenharmony_ci unsafe fn from_raw(addr: *const libc::sockaddr, len: Option<libc::socklen_t>) 25683da5c369Sopenharmony_ci -> Option<Self> where Self: Sized 25693da5c369Sopenharmony_ci { 25703da5c369Sopenharmony_ci if let Some(l) = len { 25713da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_ctl>() as libc::socklen_t { 25723da5c369Sopenharmony_ci return None; 25733da5c369Sopenharmony_ci } 25743da5c369Sopenharmony_ci } 25753da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_SYSTEM { 25763da5c369Sopenharmony_ci return None; 25773da5c369Sopenharmony_ci } 25783da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 25793da5c369Sopenharmony_ci } 25803da5c369Sopenharmony_ci } 25813da5c369Sopenharmony_ci 25823da5c369Sopenharmony_ci impl AsRef<libc::sockaddr_ctl> for SysControlAddr { 25833da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_ctl { 25843da5c369Sopenharmony_ci &self.0 25853da5c369Sopenharmony_ci } 25863da5c369Sopenharmony_ci } 25873da5c369Sopenharmony_ci 25883da5c369Sopenharmony_ci impl SysControlAddr { 25893da5c369Sopenharmony_ci /// Construct a new `SysControlAddr` from its kernel unique identifier 25903da5c369Sopenharmony_ci /// and unit number. 25913da5c369Sopenharmony_ci pub const fn new(id: u32, unit: u32) -> SysControlAddr { 25923da5c369Sopenharmony_ci let addr = libc::sockaddr_ctl { 25933da5c369Sopenharmony_ci sc_len: mem::size_of::<libc::sockaddr_ctl>() as c_uchar, 25943da5c369Sopenharmony_ci sc_family: AddressFamily::System as c_uchar, 25953da5c369Sopenharmony_ci ss_sysaddr: libc::AF_SYS_CONTROL as u16, 25963da5c369Sopenharmony_ci sc_id: id, 25973da5c369Sopenharmony_ci sc_unit: unit, 25983da5c369Sopenharmony_ci sc_reserved: [0; 5] 25993da5c369Sopenharmony_ci }; 26003da5c369Sopenharmony_ci 26013da5c369Sopenharmony_ci SysControlAddr(addr) 26023da5c369Sopenharmony_ci } 26033da5c369Sopenharmony_ci 26043da5c369Sopenharmony_ci /// Construct a new `SysControlAddr` from its human readable name and 26053da5c369Sopenharmony_ci /// unit number. 26063da5c369Sopenharmony_ci pub fn from_name(sockfd: RawFd, name: &str, unit: u32) -> Result<SysControlAddr> { 26073da5c369Sopenharmony_ci if name.len() > MAX_KCTL_NAME { 26083da5c369Sopenharmony_ci return Err(Errno::ENAMETOOLONG); 26093da5c369Sopenharmony_ci } 26103da5c369Sopenharmony_ci 26113da5c369Sopenharmony_ci let mut ctl_name = [0; MAX_KCTL_NAME]; 26123da5c369Sopenharmony_ci ctl_name[..name.len()].clone_from_slice(name.as_bytes()); 26133da5c369Sopenharmony_ci let mut info = ctl_ioc_info { ctl_id: 0, ctl_name }; 26143da5c369Sopenharmony_ci 26153da5c369Sopenharmony_ci unsafe { ctl_info(sockfd, &mut info)?; } 26163da5c369Sopenharmony_ci 26173da5c369Sopenharmony_ci Ok(SysControlAddr::new(info.ctl_id, unit)) 26183da5c369Sopenharmony_ci } 26193da5c369Sopenharmony_ci 26203da5c369Sopenharmony_ci /// Return the kernel unique identifier 26213da5c369Sopenharmony_ci pub const fn id(&self) -> u32 { 26223da5c369Sopenharmony_ci self.0.sc_id 26233da5c369Sopenharmony_ci } 26243da5c369Sopenharmony_ci 26253da5c369Sopenharmony_ci /// Return the kernel controller private unit number. 26263da5c369Sopenharmony_ci pub const fn unit(&self) -> u32 { 26273da5c369Sopenharmony_ci self.0.sc_unit 26283da5c369Sopenharmony_ci } 26293da5c369Sopenharmony_ci } 26303da5c369Sopenharmony_ci 26313da5c369Sopenharmony_ci impl fmt::Display for SysControlAddr { 26323da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 26333da5c369Sopenharmony_ci fmt::Debug::fmt(self, f) 26343da5c369Sopenharmony_ci } 26353da5c369Sopenharmony_ci } 26363da5c369Sopenharmony_ci} 26373da5c369Sopenharmony_ci} 26383da5c369Sopenharmony_ci 26393da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))] 26403da5c369Sopenharmony_ci#[cfg_attr(docsrs, doc(cfg(all())))] 26413da5c369Sopenharmony_cimod datalink { 26423da5c369Sopenharmony_ci feature! { 26433da5c369Sopenharmony_ci #![feature = "net"] 26443da5c369Sopenharmony_ci use super::{fmt, mem, private, ptr, SockaddrLike}; 26453da5c369Sopenharmony_ci 26463da5c369Sopenharmony_ci /// Hardware Address 26473da5c369Sopenharmony_ci #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 26483da5c369Sopenharmony_ci #[repr(transparent)] 26493da5c369Sopenharmony_ci pub struct LinkAddr(pub(in super::super) libc::sockaddr_ll); 26503da5c369Sopenharmony_ci 26513da5c369Sopenharmony_ci impl LinkAddr { 26523da5c369Sopenharmony_ci /// Physical-layer protocol 26533da5c369Sopenharmony_ci pub fn protocol(&self) -> u16 { 26543da5c369Sopenharmony_ci self.0.sll_protocol 26553da5c369Sopenharmony_ci } 26563da5c369Sopenharmony_ci 26573da5c369Sopenharmony_ci /// Interface number 26583da5c369Sopenharmony_ci pub fn ifindex(&self) -> usize { 26593da5c369Sopenharmony_ci self.0.sll_ifindex as usize 26603da5c369Sopenharmony_ci } 26613da5c369Sopenharmony_ci 26623da5c369Sopenharmony_ci /// ARP hardware type 26633da5c369Sopenharmony_ci pub fn hatype(&self) -> u16 { 26643da5c369Sopenharmony_ci self.0.sll_hatype 26653da5c369Sopenharmony_ci } 26663da5c369Sopenharmony_ci 26673da5c369Sopenharmony_ci /// Packet type 26683da5c369Sopenharmony_ci pub fn pkttype(&self) -> u8 { 26693da5c369Sopenharmony_ci self.0.sll_pkttype 26703da5c369Sopenharmony_ci } 26713da5c369Sopenharmony_ci 26723da5c369Sopenharmony_ci /// Length of MAC address 26733da5c369Sopenharmony_ci pub fn halen(&self) -> usize { 26743da5c369Sopenharmony_ci self.0.sll_halen as usize 26753da5c369Sopenharmony_ci } 26763da5c369Sopenharmony_ci 26773da5c369Sopenharmony_ci /// Physical-layer address (MAC) 26783da5c369Sopenharmony_ci // Returns an Option just for cross-platform compatibility 26793da5c369Sopenharmony_ci pub fn addr(&self) -> Option<[u8; 6]> { 26803da5c369Sopenharmony_ci Some([ 26813da5c369Sopenharmony_ci self.0.sll_addr[0], 26823da5c369Sopenharmony_ci self.0.sll_addr[1], 26833da5c369Sopenharmony_ci self.0.sll_addr[2], 26843da5c369Sopenharmony_ci self.0.sll_addr[3], 26853da5c369Sopenharmony_ci self.0.sll_addr[4], 26863da5c369Sopenharmony_ci self.0.sll_addr[5], 26873da5c369Sopenharmony_ci ]) 26883da5c369Sopenharmony_ci } 26893da5c369Sopenharmony_ci } 26903da5c369Sopenharmony_ci 26913da5c369Sopenharmony_ci impl fmt::Display for LinkAddr { 26923da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 26933da5c369Sopenharmony_ci if let Some(addr) = self.addr() { 26943da5c369Sopenharmony_ci write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", 26953da5c369Sopenharmony_ci addr[0], 26963da5c369Sopenharmony_ci addr[1], 26973da5c369Sopenharmony_ci addr[2], 26983da5c369Sopenharmony_ci addr[3], 26993da5c369Sopenharmony_ci addr[4], 27003da5c369Sopenharmony_ci addr[5]) 27013da5c369Sopenharmony_ci } else { 27023da5c369Sopenharmony_ci Ok(()) 27033da5c369Sopenharmony_ci } 27043da5c369Sopenharmony_ci } 27053da5c369Sopenharmony_ci } 27063da5c369Sopenharmony_ci impl private::SockaddrLikePriv for LinkAddr {} 27073da5c369Sopenharmony_ci impl SockaddrLike for LinkAddr { 27083da5c369Sopenharmony_ci unsafe fn from_raw(addr: *const libc::sockaddr, 27093da5c369Sopenharmony_ci len: Option<libc::socklen_t>) 27103da5c369Sopenharmony_ci -> Option<Self> where Self: Sized 27113da5c369Sopenharmony_ci { 27123da5c369Sopenharmony_ci if let Some(l) = len { 27133da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_ll>() as libc::socklen_t { 27143da5c369Sopenharmony_ci return None; 27153da5c369Sopenharmony_ci } 27163da5c369Sopenharmony_ci } 27173da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_PACKET { 27183da5c369Sopenharmony_ci return None; 27193da5c369Sopenharmony_ci } 27203da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 27213da5c369Sopenharmony_ci } 27223da5c369Sopenharmony_ci } 27233da5c369Sopenharmony_ci 27243da5c369Sopenharmony_ci impl AsRef<libc::sockaddr_ll> for LinkAddr { 27253da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_ll { 27263da5c369Sopenharmony_ci &self.0 27273da5c369Sopenharmony_ci } 27283da5c369Sopenharmony_ci } 27293da5c369Sopenharmony_ci 27303da5c369Sopenharmony_ci } 27313da5c369Sopenharmony_ci} 27323da5c369Sopenharmony_ci 27333da5c369Sopenharmony_ci#[cfg(any( 27343da5c369Sopenharmony_ci target_os = "dragonfly", 27353da5c369Sopenharmony_ci target_os = "freebsd", 27363da5c369Sopenharmony_ci target_os = "ios", 27373da5c369Sopenharmony_ci target_os = "macos", 27383da5c369Sopenharmony_ci target_os = "illumos", 27393da5c369Sopenharmony_ci target_os = "netbsd", 27403da5c369Sopenharmony_ci target_os = "haiku", 27413da5c369Sopenharmony_ci target_os = "openbsd" 27423da5c369Sopenharmony_ci))] 27433da5c369Sopenharmony_ci#[cfg_attr(docsrs, doc(cfg(all())))] 27443da5c369Sopenharmony_cimod datalink { 27453da5c369Sopenharmony_ci feature! { 27463da5c369Sopenharmony_ci #![feature = "net"] 27473da5c369Sopenharmony_ci use super::{fmt, mem, private, ptr, SockaddrLike}; 27483da5c369Sopenharmony_ci 27493da5c369Sopenharmony_ci /// Hardware Address 27503da5c369Sopenharmony_ci #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 27513da5c369Sopenharmony_ci #[repr(transparent)] 27523da5c369Sopenharmony_ci pub struct LinkAddr(pub(in super::super) libc::sockaddr_dl); 27533da5c369Sopenharmony_ci 27543da5c369Sopenharmony_ci impl LinkAddr { 27553da5c369Sopenharmony_ci /// interface index, if != 0, system given index for interface 27563da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 27573da5c369Sopenharmony_ci pub fn ifindex(&self) -> usize { 27583da5c369Sopenharmony_ci self.0.sdl_index as usize 27593da5c369Sopenharmony_ci } 27603da5c369Sopenharmony_ci 27613da5c369Sopenharmony_ci /// Datalink type 27623da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 27633da5c369Sopenharmony_ci pub fn datalink_type(&self) -> u8 { 27643da5c369Sopenharmony_ci self.0.sdl_type 27653da5c369Sopenharmony_ci } 27663da5c369Sopenharmony_ci 27673da5c369Sopenharmony_ci /// MAC address start position 27683da5c369Sopenharmony_ci pub fn nlen(&self) -> usize { 27693da5c369Sopenharmony_ci self.0.sdl_nlen as usize 27703da5c369Sopenharmony_ci } 27713da5c369Sopenharmony_ci 27723da5c369Sopenharmony_ci /// link level address length 27733da5c369Sopenharmony_ci pub fn alen(&self) -> usize { 27743da5c369Sopenharmony_ci self.0.sdl_alen as usize 27753da5c369Sopenharmony_ci } 27763da5c369Sopenharmony_ci 27773da5c369Sopenharmony_ci /// link layer selector length 27783da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 27793da5c369Sopenharmony_ci pub fn slen(&self) -> usize { 27803da5c369Sopenharmony_ci self.0.sdl_slen as usize 27813da5c369Sopenharmony_ci } 27823da5c369Sopenharmony_ci 27833da5c369Sopenharmony_ci /// if link level address length == 0, 27843da5c369Sopenharmony_ci /// or `sdl_data` not be larger. 27853da5c369Sopenharmony_ci pub fn is_empty(&self) -> bool { 27863da5c369Sopenharmony_ci let nlen = self.nlen(); 27873da5c369Sopenharmony_ci let alen = self.alen(); 27883da5c369Sopenharmony_ci let data_len = self.0.sdl_data.len(); 27893da5c369Sopenharmony_ci 27903da5c369Sopenharmony_ci alen == 0 || nlen + alen >= data_len 27913da5c369Sopenharmony_ci } 27923da5c369Sopenharmony_ci 27933da5c369Sopenharmony_ci /// Physical-layer address (MAC) 27943da5c369Sopenharmony_ci // The cast is not unnecessary on all platforms. 27953da5c369Sopenharmony_ci #[allow(clippy::unnecessary_cast)] 27963da5c369Sopenharmony_ci pub fn addr(&self) -> Option<[u8; 6]> { 27973da5c369Sopenharmony_ci let nlen = self.nlen(); 27983da5c369Sopenharmony_ci let data = self.0.sdl_data; 27993da5c369Sopenharmony_ci 28003da5c369Sopenharmony_ci if self.is_empty() { 28013da5c369Sopenharmony_ci None 28023da5c369Sopenharmony_ci } else { 28033da5c369Sopenharmony_ci Some([ 28043da5c369Sopenharmony_ci data[nlen] as u8, 28053da5c369Sopenharmony_ci data[nlen + 1] as u8, 28063da5c369Sopenharmony_ci data[nlen + 2] as u8, 28073da5c369Sopenharmony_ci data[nlen + 3] as u8, 28083da5c369Sopenharmony_ci data[nlen + 4] as u8, 28093da5c369Sopenharmony_ci data[nlen + 5] as u8, 28103da5c369Sopenharmony_ci ]) 28113da5c369Sopenharmony_ci } 28123da5c369Sopenharmony_ci } 28133da5c369Sopenharmony_ci } 28143da5c369Sopenharmony_ci 28153da5c369Sopenharmony_ci impl fmt::Display for LinkAddr { 28163da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 28173da5c369Sopenharmony_ci if let Some(addr) = self.addr() { 28183da5c369Sopenharmony_ci write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", 28193da5c369Sopenharmony_ci addr[0], 28203da5c369Sopenharmony_ci addr[1], 28213da5c369Sopenharmony_ci addr[2], 28223da5c369Sopenharmony_ci addr[3], 28233da5c369Sopenharmony_ci addr[4], 28243da5c369Sopenharmony_ci addr[5]) 28253da5c369Sopenharmony_ci } else { 28263da5c369Sopenharmony_ci Ok(()) 28273da5c369Sopenharmony_ci } 28283da5c369Sopenharmony_ci } 28293da5c369Sopenharmony_ci } 28303da5c369Sopenharmony_ci impl private::SockaddrLikePriv for LinkAddr {} 28313da5c369Sopenharmony_ci impl SockaddrLike for LinkAddr { 28323da5c369Sopenharmony_ci unsafe fn from_raw(addr: *const libc::sockaddr, 28333da5c369Sopenharmony_ci len: Option<libc::socklen_t>) 28343da5c369Sopenharmony_ci -> Option<Self> where Self: Sized 28353da5c369Sopenharmony_ci { 28363da5c369Sopenharmony_ci if let Some(l) = len { 28373da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_dl>() as libc::socklen_t { 28383da5c369Sopenharmony_ci return None; 28393da5c369Sopenharmony_ci } 28403da5c369Sopenharmony_ci } 28413da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_LINK { 28423da5c369Sopenharmony_ci return None; 28433da5c369Sopenharmony_ci } 28443da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 28453da5c369Sopenharmony_ci } 28463da5c369Sopenharmony_ci } 28473da5c369Sopenharmony_ci 28483da5c369Sopenharmony_ci impl AsRef<libc::sockaddr_dl> for LinkAddr { 28493da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_dl { 28503da5c369Sopenharmony_ci &self.0 28513da5c369Sopenharmony_ci } 28523da5c369Sopenharmony_ci } 28533da5c369Sopenharmony_ci 28543da5c369Sopenharmony_ci } 28553da5c369Sopenharmony_ci} 28563da5c369Sopenharmony_ci 28573da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 28583da5c369Sopenharmony_ci#[cfg_attr(docsrs, doc(cfg(all())))] 28593da5c369Sopenharmony_cipub mod vsock { 28603da5c369Sopenharmony_ci use super::*; 28613da5c369Sopenharmony_ci use crate::sys::socket::addr::AddressFamily; 28623da5c369Sopenharmony_ci use libc::{sa_family_t, sockaddr_vm}; 28633da5c369Sopenharmony_ci use std::hash::{Hash, Hasher}; 28643da5c369Sopenharmony_ci use std::{fmt, mem}; 28653da5c369Sopenharmony_ci 28663da5c369Sopenharmony_ci /// Socket address for VMWare VSockets protocol 28673da5c369Sopenharmony_ci /// 28683da5c369Sopenharmony_ci /// # References 28693da5c369Sopenharmony_ci /// 28703da5c369Sopenharmony_ci /// [vsock(7)](https://man7.org/linux/man-pages/man7/vsock.7.html) 28713da5c369Sopenharmony_ci #[derive(Copy, Clone)] 28723da5c369Sopenharmony_ci #[repr(transparent)] 28733da5c369Sopenharmony_ci pub struct VsockAddr(pub(in super::super) sockaddr_vm); 28743da5c369Sopenharmony_ci 28753da5c369Sopenharmony_ci impl private::SockaddrLikePriv for VsockAddr {} 28763da5c369Sopenharmony_ci impl SockaddrLike for VsockAddr { 28773da5c369Sopenharmony_ci unsafe fn from_raw( 28783da5c369Sopenharmony_ci addr: *const libc::sockaddr, 28793da5c369Sopenharmony_ci len: Option<libc::socklen_t>, 28803da5c369Sopenharmony_ci ) -> Option<Self> 28813da5c369Sopenharmony_ci where 28823da5c369Sopenharmony_ci Self: Sized, 28833da5c369Sopenharmony_ci { 28843da5c369Sopenharmony_ci if let Some(l) = len { 28853da5c369Sopenharmony_ci if l != mem::size_of::<libc::sockaddr_vm>() as libc::socklen_t { 28863da5c369Sopenharmony_ci return None; 28873da5c369Sopenharmony_ci } 28883da5c369Sopenharmony_ci } 28893da5c369Sopenharmony_ci if (*addr).sa_family as i32 != libc::AF_VSOCK { 28903da5c369Sopenharmony_ci return None; 28913da5c369Sopenharmony_ci } 28923da5c369Sopenharmony_ci Some(Self(ptr::read_unaligned(addr as *const _))) 28933da5c369Sopenharmony_ci } 28943da5c369Sopenharmony_ci } 28953da5c369Sopenharmony_ci 28963da5c369Sopenharmony_ci impl AsRef<libc::sockaddr_vm> for VsockAddr { 28973da5c369Sopenharmony_ci fn as_ref(&self) -> &libc::sockaddr_vm { 28983da5c369Sopenharmony_ci &self.0 28993da5c369Sopenharmony_ci } 29003da5c369Sopenharmony_ci } 29013da5c369Sopenharmony_ci 29023da5c369Sopenharmony_ci impl PartialEq for VsockAddr { 29033da5c369Sopenharmony_ci fn eq(&self, other: &Self) -> bool { 29043da5c369Sopenharmony_ci let (inner, other) = (self.0, other.0); 29053da5c369Sopenharmony_ci (inner.svm_family, inner.svm_cid, inner.svm_port) 29063da5c369Sopenharmony_ci == (other.svm_family, other.svm_cid, other.svm_port) 29073da5c369Sopenharmony_ci } 29083da5c369Sopenharmony_ci } 29093da5c369Sopenharmony_ci 29103da5c369Sopenharmony_ci impl Eq for VsockAddr {} 29113da5c369Sopenharmony_ci 29123da5c369Sopenharmony_ci impl Hash for VsockAddr { 29133da5c369Sopenharmony_ci fn hash<H: Hasher>(&self, s: &mut H) { 29143da5c369Sopenharmony_ci let inner = self.0; 29153da5c369Sopenharmony_ci (inner.svm_family, inner.svm_cid, inner.svm_port).hash(s); 29163da5c369Sopenharmony_ci } 29173da5c369Sopenharmony_ci } 29183da5c369Sopenharmony_ci 29193da5c369Sopenharmony_ci /// VSOCK Address 29203da5c369Sopenharmony_ci /// 29213da5c369Sopenharmony_ci /// The address for AF_VSOCK socket is defined as a combination of a 29223da5c369Sopenharmony_ci /// 32-bit Context Identifier (CID) and a 32-bit port number. 29233da5c369Sopenharmony_ci impl VsockAddr { 29243da5c369Sopenharmony_ci /// Construct a `VsockAddr` from its raw fields. 29253da5c369Sopenharmony_ci pub fn new(cid: u32, port: u32) -> VsockAddr { 29263da5c369Sopenharmony_ci let mut addr: sockaddr_vm = unsafe { mem::zeroed() }; 29273da5c369Sopenharmony_ci addr.svm_family = AddressFamily::Vsock as sa_family_t; 29283da5c369Sopenharmony_ci addr.svm_cid = cid; 29293da5c369Sopenharmony_ci addr.svm_port = port; 29303da5c369Sopenharmony_ci 29313da5c369Sopenharmony_ci VsockAddr(addr) 29323da5c369Sopenharmony_ci } 29333da5c369Sopenharmony_ci 29343da5c369Sopenharmony_ci /// Context Identifier (CID) 29353da5c369Sopenharmony_ci pub fn cid(&self) -> u32 { 29363da5c369Sopenharmony_ci self.0.svm_cid 29373da5c369Sopenharmony_ci } 29383da5c369Sopenharmony_ci 29393da5c369Sopenharmony_ci /// Port number 29403da5c369Sopenharmony_ci pub fn port(&self) -> u32 { 29413da5c369Sopenharmony_ci self.0.svm_port 29423da5c369Sopenharmony_ci } 29433da5c369Sopenharmony_ci } 29443da5c369Sopenharmony_ci 29453da5c369Sopenharmony_ci impl fmt::Display for VsockAddr { 29463da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 29473da5c369Sopenharmony_ci write!(f, "cid: {} port: {}", self.cid(), self.port()) 29483da5c369Sopenharmony_ci } 29493da5c369Sopenharmony_ci } 29503da5c369Sopenharmony_ci 29513da5c369Sopenharmony_ci impl fmt::Debug for VsockAddr { 29523da5c369Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 29533da5c369Sopenharmony_ci fmt::Display::fmt(self, f) 29543da5c369Sopenharmony_ci } 29553da5c369Sopenharmony_ci } 29563da5c369Sopenharmony_ci} 29573da5c369Sopenharmony_ci 29583da5c369Sopenharmony_ci#[cfg(test)] 29593da5c369Sopenharmony_cimod tests { 29603da5c369Sopenharmony_ci use super::*; 29613da5c369Sopenharmony_ci 29623da5c369Sopenharmony_ci mod types { 29633da5c369Sopenharmony_ci use super::*; 29643da5c369Sopenharmony_ci 29653da5c369Sopenharmony_ci #[test] 29663da5c369Sopenharmony_ci fn test_ipv4addr_to_libc() { 29673da5c369Sopenharmony_ci let s = std::net::Ipv4Addr::new(1, 2, 3, 4); 29683da5c369Sopenharmony_ci let l = ipv4addr_to_libc(s); 29693da5c369Sopenharmony_ci assert_eq!(l.s_addr, u32::to_be(0x01020304)); 29703da5c369Sopenharmony_ci } 29713da5c369Sopenharmony_ci 29723da5c369Sopenharmony_ci #[test] 29733da5c369Sopenharmony_ci fn test_ipv6addr_to_libc() { 29743da5c369Sopenharmony_ci let s = std::net::Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8); 29753da5c369Sopenharmony_ci let l = ipv6addr_to_libc(&s); 29763da5c369Sopenharmony_ci assert_eq!( 29773da5c369Sopenharmony_ci l.s6_addr, 29783da5c369Sopenharmony_ci [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8] 29793da5c369Sopenharmony_ci ); 29803da5c369Sopenharmony_ci } 29813da5c369Sopenharmony_ci } 29823da5c369Sopenharmony_ci 29833da5c369Sopenharmony_ci mod link { 29843da5c369Sopenharmony_ci #![allow(clippy::cast_ptr_alignment)] 29853da5c369Sopenharmony_ci 29863da5c369Sopenharmony_ci #[cfg(any( 29873da5c369Sopenharmony_ci target_os = "ios", 29883da5c369Sopenharmony_ci target_os = "macos", 29893da5c369Sopenharmony_ci target_os = "illumos" 29903da5c369Sopenharmony_ci ))] 29913da5c369Sopenharmony_ci use super::super::super::socklen_t; 29923da5c369Sopenharmony_ci use super::*; 29933da5c369Sopenharmony_ci 29943da5c369Sopenharmony_ci /// Don't panic when trying to display an empty datalink address 29953da5c369Sopenharmony_ci #[cfg(any( 29963da5c369Sopenharmony_ci target_os = "dragonfly", 29973da5c369Sopenharmony_ci target_os = "freebsd", 29983da5c369Sopenharmony_ci target_os = "ios", 29993da5c369Sopenharmony_ci target_os = "macos", 30003da5c369Sopenharmony_ci target_os = "netbsd", 30013da5c369Sopenharmony_ci target_os = "openbsd" 30023da5c369Sopenharmony_ci ))] 30033da5c369Sopenharmony_ci #[test] 30043da5c369Sopenharmony_ci fn test_datalink_display() { 30053da5c369Sopenharmony_ci use super::super::LinkAddr; 30063da5c369Sopenharmony_ci use std::mem; 30073da5c369Sopenharmony_ci 30083da5c369Sopenharmony_ci let la = LinkAddr(libc::sockaddr_dl { 30093da5c369Sopenharmony_ci sdl_len: 56, 30103da5c369Sopenharmony_ci sdl_family: 18, 30113da5c369Sopenharmony_ci sdl_index: 5, 30123da5c369Sopenharmony_ci sdl_type: 24, 30133da5c369Sopenharmony_ci sdl_nlen: 3, 30143da5c369Sopenharmony_ci sdl_alen: 0, 30153da5c369Sopenharmony_ci sdl_slen: 0, 30163da5c369Sopenharmony_ci ..unsafe { mem::zeroed() } 30173da5c369Sopenharmony_ci }); 30183da5c369Sopenharmony_ci format!("{}", la); 30193da5c369Sopenharmony_ci } 30203da5c369Sopenharmony_ci 30213da5c369Sopenharmony_ci #[cfg(all( 30223da5c369Sopenharmony_ci any( 30233da5c369Sopenharmony_ci target_os = "android", 30243da5c369Sopenharmony_ci target_os = "fuchsia", 30253da5c369Sopenharmony_ci target_os = "linux" 30263da5c369Sopenharmony_ci ), 30273da5c369Sopenharmony_ci target_endian = "little" 30283da5c369Sopenharmony_ci ))] 30293da5c369Sopenharmony_ci #[test] 30303da5c369Sopenharmony_ci fn linux_loopback() { 30313da5c369Sopenharmony_ci #[repr(align(2))] 30323da5c369Sopenharmony_ci struct Raw([u8; 20]); 30333da5c369Sopenharmony_ci 30343da5c369Sopenharmony_ci let bytes = Raw([ 30353da5c369Sopenharmony_ci 17u8, 0, 0, 0, 1, 0, 0, 0, 4, 3, 0, 6, 1, 2, 3, 4, 5, 6, 0, 0, 30363da5c369Sopenharmony_ci ]); 30373da5c369Sopenharmony_ci let sa = bytes.0.as_ptr() as *const libc::sockaddr; 30383da5c369Sopenharmony_ci let len = None; 30393da5c369Sopenharmony_ci let sock_addr = 30403da5c369Sopenharmony_ci unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap(); 30413da5c369Sopenharmony_ci assert_eq!(sock_addr.family(), Some(AddressFamily::Packet)); 30423da5c369Sopenharmony_ci match sock_addr.as_link_addr() { 30433da5c369Sopenharmony_ci Some(dl) => assert_eq!(dl.addr(), Some([1, 2, 3, 4, 5, 6])), 30443da5c369Sopenharmony_ci None => panic!("Can't unwrap sockaddr storage"), 30453da5c369Sopenharmony_ci } 30463da5c369Sopenharmony_ci } 30473da5c369Sopenharmony_ci 30483da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 30493da5c369Sopenharmony_ci #[test] 30503da5c369Sopenharmony_ci fn macos_loopback() { 30513da5c369Sopenharmony_ci let bytes = 30523da5c369Sopenharmony_ci [20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0]; 30533da5c369Sopenharmony_ci let sa = bytes.as_ptr() as *const libc::sockaddr; 30543da5c369Sopenharmony_ci let len = Some(bytes.len() as socklen_t); 30553da5c369Sopenharmony_ci let sock_addr = 30563da5c369Sopenharmony_ci unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap(); 30573da5c369Sopenharmony_ci assert_eq!(sock_addr.family(), Some(AddressFamily::Link)); 30583da5c369Sopenharmony_ci match sock_addr.as_link_addr() { 30593da5c369Sopenharmony_ci Some(dl) => { 30603da5c369Sopenharmony_ci assert!(dl.addr().is_none()); 30613da5c369Sopenharmony_ci } 30623da5c369Sopenharmony_ci None => panic!("Can't unwrap sockaddr storage"), 30633da5c369Sopenharmony_ci } 30643da5c369Sopenharmony_ci } 30653da5c369Sopenharmony_ci 30663da5c369Sopenharmony_ci #[cfg(any(target_os = "ios", target_os = "macos"))] 30673da5c369Sopenharmony_ci #[test] 30683da5c369Sopenharmony_ci fn macos_tap() { 30693da5c369Sopenharmony_ci let bytes = [ 30703da5c369Sopenharmony_ci 20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35, 30713da5c369Sopenharmony_ci 76, -80, 30723da5c369Sopenharmony_ci ]; 30733da5c369Sopenharmony_ci let ptr = bytes.as_ptr(); 30743da5c369Sopenharmony_ci let sa = ptr as *const libc::sockaddr; 30753da5c369Sopenharmony_ci let len = Some(bytes.len() as socklen_t); 30763da5c369Sopenharmony_ci 30773da5c369Sopenharmony_ci let sock_addr = 30783da5c369Sopenharmony_ci unsafe { SockaddrStorage::from_raw(sa, len).unwrap() }; 30793da5c369Sopenharmony_ci assert_eq!(sock_addr.family(), Some(AddressFamily::Link)); 30803da5c369Sopenharmony_ci match sock_addr.as_link_addr() { 30813da5c369Sopenharmony_ci Some(dl) => { 30823da5c369Sopenharmony_ci assert_eq!(dl.addr(), Some([24u8, 101, 144, 221, 76, 176])) 30833da5c369Sopenharmony_ci } 30843da5c369Sopenharmony_ci None => panic!("Can't unwrap sockaddr storage"), 30853da5c369Sopenharmony_ci } 30863da5c369Sopenharmony_ci } 30873da5c369Sopenharmony_ci 30883da5c369Sopenharmony_ci #[cfg(target_os = "illumos")] 30893da5c369Sopenharmony_ci #[test] 30903da5c369Sopenharmony_ci fn illumos_tap() { 30913da5c369Sopenharmony_ci let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176]; 30923da5c369Sopenharmony_ci let ptr = bytes.as_ptr(); 30933da5c369Sopenharmony_ci let sa = ptr as *const libc::sockaddr; 30943da5c369Sopenharmony_ci let len = Some(bytes.len() as socklen_t); 30953da5c369Sopenharmony_ci let _sock_addr = unsafe { SockaddrStorage::from_raw(sa, len) }; 30963da5c369Sopenharmony_ci 30973da5c369Sopenharmony_ci assert!(_sock_addr.is_some()); 30983da5c369Sopenharmony_ci 30993da5c369Sopenharmony_ci let sock_addr = _sock_addr.unwrap(); 31003da5c369Sopenharmony_ci 31013da5c369Sopenharmony_ci assert_eq!(sock_addr.family().unwrap(), AddressFamily::Link); 31023da5c369Sopenharmony_ci 31033da5c369Sopenharmony_ci assert_eq!( 31043da5c369Sopenharmony_ci sock_addr.as_link_addr().unwrap().addr(), 31053da5c369Sopenharmony_ci Some([24u8, 101, 144, 221, 76, 176]) 31063da5c369Sopenharmony_ci ); 31073da5c369Sopenharmony_ci } 31083da5c369Sopenharmony_ci 31093da5c369Sopenharmony_ci #[test] 31103da5c369Sopenharmony_ci fn size() { 31113da5c369Sopenharmony_ci #[cfg(any( 31123da5c369Sopenharmony_ci target_os = "dragonfly", 31133da5c369Sopenharmony_ci target_os = "freebsd", 31143da5c369Sopenharmony_ci target_os = "ios", 31153da5c369Sopenharmony_ci target_os = "macos", 31163da5c369Sopenharmony_ci target_os = "netbsd", 31173da5c369Sopenharmony_ci target_os = "illumos", 31183da5c369Sopenharmony_ci target_os = "openbsd", 31193da5c369Sopenharmony_ci target_os = "haiku" 31203da5c369Sopenharmony_ci ))] 31213da5c369Sopenharmony_ci let l = mem::size_of::<libc::sockaddr_dl>(); 31223da5c369Sopenharmony_ci #[cfg(any( 31233da5c369Sopenharmony_ci target_os = "android", 31243da5c369Sopenharmony_ci target_os = "fuchsia", 31253da5c369Sopenharmony_ci target_os = "linux" 31263da5c369Sopenharmony_ci ))] 31273da5c369Sopenharmony_ci let l = mem::size_of::<libc::sockaddr_ll>(); 31283da5c369Sopenharmony_ci assert_eq!(LinkAddr::size() as usize, l); 31293da5c369Sopenharmony_ci } 31303da5c369Sopenharmony_ci } 31313da5c369Sopenharmony_ci 31323da5c369Sopenharmony_ci mod sockaddr_in { 31333da5c369Sopenharmony_ci use super::*; 31343da5c369Sopenharmony_ci use std::str::FromStr; 31353da5c369Sopenharmony_ci 31363da5c369Sopenharmony_ci #[test] 31373da5c369Sopenharmony_ci fn display() { 31383da5c369Sopenharmony_ci let s = "127.0.0.1:8080"; 31393da5c369Sopenharmony_ci let addr = SockaddrIn::from_str(s).unwrap(); 31403da5c369Sopenharmony_ci assert_eq!(s, format!("{}", addr)); 31413da5c369Sopenharmony_ci } 31423da5c369Sopenharmony_ci 31433da5c369Sopenharmony_ci #[test] 31443da5c369Sopenharmony_ci fn size() { 31453da5c369Sopenharmony_ci assert_eq!( 31463da5c369Sopenharmony_ci mem::size_of::<libc::sockaddr_in>(), 31473da5c369Sopenharmony_ci SockaddrIn::size() as usize 31483da5c369Sopenharmony_ci ); 31493da5c369Sopenharmony_ci } 31503da5c369Sopenharmony_ci } 31513da5c369Sopenharmony_ci 31523da5c369Sopenharmony_ci mod sockaddr_in6 { 31533da5c369Sopenharmony_ci use super::*; 31543da5c369Sopenharmony_ci use std::str::FromStr; 31553da5c369Sopenharmony_ci 31563da5c369Sopenharmony_ci #[test] 31573da5c369Sopenharmony_ci fn display() { 31583da5c369Sopenharmony_ci let s = "[1234:5678:90ab:cdef::1111:2222]:8080"; 31593da5c369Sopenharmony_ci let addr = SockaddrIn6::from_str(s).unwrap(); 31603da5c369Sopenharmony_ci assert_eq!(s, format!("{}", addr)); 31613da5c369Sopenharmony_ci } 31623da5c369Sopenharmony_ci 31633da5c369Sopenharmony_ci #[test] 31643da5c369Sopenharmony_ci fn size() { 31653da5c369Sopenharmony_ci assert_eq!( 31663da5c369Sopenharmony_ci mem::size_of::<libc::sockaddr_in6>(), 31673da5c369Sopenharmony_ci SockaddrIn6::size() as usize 31683da5c369Sopenharmony_ci ); 31693da5c369Sopenharmony_ci } 31703da5c369Sopenharmony_ci 31713da5c369Sopenharmony_ci #[test] 31723da5c369Sopenharmony_ci // Ensure that we can convert to-and-from std::net variants without change. 31733da5c369Sopenharmony_ci fn to_and_from() { 31743da5c369Sopenharmony_ci let s = "[1234:5678:90ab:cdef::1111:2222]:8080"; 31753da5c369Sopenharmony_ci let mut nix_sin6 = SockaddrIn6::from_str(s).unwrap(); 31763da5c369Sopenharmony_ci nix_sin6.0.sin6_flowinfo = 0x12345678; 31773da5c369Sopenharmony_ci nix_sin6.0.sin6_scope_id = 0x9abcdef0; 31783da5c369Sopenharmony_ci 31793da5c369Sopenharmony_ci let std_sin6 : std::net::SocketAddrV6 = nix_sin6.into(); 31803da5c369Sopenharmony_ci assert_eq!(nix_sin6, std_sin6.into()); 31813da5c369Sopenharmony_ci } 31823da5c369Sopenharmony_ci } 31833da5c369Sopenharmony_ci 31843da5c369Sopenharmony_ci mod sockaddr_storage { 31853da5c369Sopenharmony_ci use super::*; 31863da5c369Sopenharmony_ci 31873da5c369Sopenharmony_ci #[test] 31883da5c369Sopenharmony_ci fn from_sockaddr_un_named() { 31893da5c369Sopenharmony_ci let ua = UnixAddr::new("/var/run/mysock").unwrap(); 31903da5c369Sopenharmony_ci let ptr = ua.as_ptr() as *const libc::sockaddr; 31913da5c369Sopenharmony_ci let ss = unsafe { 31923da5c369Sopenharmony_ci SockaddrStorage::from_raw(ptr, Some(ua.len())) 31933da5c369Sopenharmony_ci }.unwrap(); 31943da5c369Sopenharmony_ci assert_eq!(ss.len(), ua.len()); 31953da5c369Sopenharmony_ci } 31963da5c369Sopenharmony_ci 31973da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 31983da5c369Sopenharmony_ci #[test] 31993da5c369Sopenharmony_ci fn from_sockaddr_un_abstract_named() { 32003da5c369Sopenharmony_ci let name = String::from("nix\0abstract\0test"); 32013da5c369Sopenharmony_ci let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap(); 32023da5c369Sopenharmony_ci let ptr = ua.as_ptr() as *const libc::sockaddr; 32033da5c369Sopenharmony_ci let ss = unsafe { 32043da5c369Sopenharmony_ci SockaddrStorage::from_raw(ptr, Some(ua.len())) 32053da5c369Sopenharmony_ci }.unwrap(); 32063da5c369Sopenharmony_ci assert_eq!(ss.len(), ua.len()); 32073da5c369Sopenharmony_ci } 32083da5c369Sopenharmony_ci 32093da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 32103da5c369Sopenharmony_ci #[test] 32113da5c369Sopenharmony_ci fn from_sockaddr_un_abstract_unnamed() { 32123da5c369Sopenharmony_ci let ua = UnixAddr::new_unnamed(); 32133da5c369Sopenharmony_ci let ptr = ua.as_ptr() as *const libc::sockaddr; 32143da5c369Sopenharmony_ci let ss = unsafe { 32153da5c369Sopenharmony_ci SockaddrStorage::from_raw(ptr, Some(ua.len())) 32163da5c369Sopenharmony_ci }.unwrap(); 32173da5c369Sopenharmony_ci assert_eq!(ss.len(), ua.len()); 32183da5c369Sopenharmony_ci } 32193da5c369Sopenharmony_ci } 32203da5c369Sopenharmony_ci 32213da5c369Sopenharmony_ci mod unixaddr { 32223da5c369Sopenharmony_ci use super::*; 32233da5c369Sopenharmony_ci 32243da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 32253da5c369Sopenharmony_ci #[test] 32263da5c369Sopenharmony_ci fn abstract_sun_path() { 32273da5c369Sopenharmony_ci let name = String::from("nix\0abstract\0test"); 32283da5c369Sopenharmony_ci let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap(); 32293da5c369Sopenharmony_ci 32303da5c369Sopenharmony_ci let sun_path1 = 32313da5c369Sopenharmony_ci unsafe { &(*addr.as_ptr()).sun_path[..addr.path_len()] }; 32323da5c369Sopenharmony_ci let sun_path2 = [ 32333da5c369Sopenharmony_ci 0, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 32343da5c369Sopenharmony_ci 116, 101, 115, 116, 32353da5c369Sopenharmony_ci ]; 32363da5c369Sopenharmony_ci assert_eq!(sun_path1, sun_path2); 32373da5c369Sopenharmony_ci } 32383da5c369Sopenharmony_ci 32393da5c369Sopenharmony_ci #[test] 32403da5c369Sopenharmony_ci fn size() { 32413da5c369Sopenharmony_ci assert_eq!( 32423da5c369Sopenharmony_ci mem::size_of::<libc::sockaddr_un>(), 32433da5c369Sopenharmony_ci UnixAddr::size() as usize 32443da5c369Sopenharmony_ci ); 32453da5c369Sopenharmony_ci } 32463da5c369Sopenharmony_ci } 32473da5c369Sopenharmony_ci} 3248