13da5c369Sopenharmony_ci//! Network interface name resolution.
23da5c369Sopenharmony_ci//!
33da5c369Sopenharmony_ci//! Uses Linux and/or POSIX functions to resolve interface names like "eth0"
43da5c369Sopenharmony_ci//! or "socan1" into device numbers.
53da5c369Sopenharmony_ci
63da5c369Sopenharmony_ciuse crate::{Error, NixPath, Result};
73da5c369Sopenharmony_ciuse libc::c_uint;
83da5c369Sopenharmony_ci
93da5c369Sopenharmony_ci/// Resolve an interface into a interface number.
103da5c369Sopenharmony_cipub fn if_nametoindex<P: ?Sized + NixPath>(name: &P) -> Result<c_uint> {
113da5c369Sopenharmony_ci    let if_index = name
123da5c369Sopenharmony_ci        .with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?;
133da5c369Sopenharmony_ci
143da5c369Sopenharmony_ci    if if_index == 0 {
153da5c369Sopenharmony_ci        Err(Error::last())
163da5c369Sopenharmony_ci    } else {
173da5c369Sopenharmony_ci        Ok(if_index)
183da5c369Sopenharmony_ci    }
193da5c369Sopenharmony_ci}
203da5c369Sopenharmony_ci
213da5c369Sopenharmony_cilibc_bitflags!(
223da5c369Sopenharmony_ci    /// Standard interface flags, used by `getifaddrs`
233da5c369Sopenharmony_ci    pub struct InterfaceFlags: libc::c_int {
243da5c369Sopenharmony_ci        /// Interface is running. (see
253da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
263da5c369Sopenharmony_ci        IFF_UP;
273da5c369Sopenharmony_ci        /// Valid broadcast address set. (see
283da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
293da5c369Sopenharmony_ci        IFF_BROADCAST;
303da5c369Sopenharmony_ci        /// Internal debugging flag. (see
313da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
323da5c369Sopenharmony_ci        #[cfg(not(target_os = "haiku"))]
333da5c369Sopenharmony_ci        IFF_DEBUG;
343da5c369Sopenharmony_ci        /// Interface is a loopback interface. (see
353da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
363da5c369Sopenharmony_ci        IFF_LOOPBACK;
373da5c369Sopenharmony_ci        /// Interface is a point-to-point link. (see
383da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
393da5c369Sopenharmony_ci        IFF_POINTOPOINT;
403da5c369Sopenharmony_ci        /// Avoid use of trailers. (see
413da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
423da5c369Sopenharmony_ci        #[cfg(any(target_os = "android",
433da5c369Sopenharmony_ci                  target_os = "fuchsia",
443da5c369Sopenharmony_ci                  target_os = "ios",
453da5c369Sopenharmony_ci                  target_os = "linux",
463da5c369Sopenharmony_ci                  target_os = "macos",
473da5c369Sopenharmony_ci                  target_os = "netbsd",
483da5c369Sopenharmony_ci                  target_os = "illumos",
493da5c369Sopenharmony_ci                  target_os = "solaris"))]
503da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
513da5c369Sopenharmony_ci        IFF_NOTRAILERS;
523da5c369Sopenharmony_ci        /// Interface manages own routes.
533da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly"))]
543da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
553da5c369Sopenharmony_ci        IFF_SMART;
563da5c369Sopenharmony_ci        /// Resources allocated. (see
573da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
583da5c369Sopenharmony_ci        #[cfg(any(target_os = "android",
593da5c369Sopenharmony_ci                  target_os = "dragonfly",
603da5c369Sopenharmony_ci                  target_os = "freebsd",
613da5c369Sopenharmony_ci                  target_os = "fuchsia",
623da5c369Sopenharmony_ci                  target_os = "illumos",
633da5c369Sopenharmony_ci                  target_os = "ios",
643da5c369Sopenharmony_ci                  target_os = "linux",
653da5c369Sopenharmony_ci                  target_os = "macos",
663da5c369Sopenharmony_ci                  target_os = "netbsd",
673da5c369Sopenharmony_ci                  target_os = "openbsd",
683da5c369Sopenharmony_ci                  target_os = "solaris"))]
693da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
703da5c369Sopenharmony_ci        IFF_RUNNING;
713da5c369Sopenharmony_ci        /// No arp protocol, L2 destination address not set. (see
723da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
733da5c369Sopenharmony_ci        IFF_NOARP;
743da5c369Sopenharmony_ci        /// Interface is in promiscuous mode. (see
753da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
763da5c369Sopenharmony_ci        IFF_PROMISC;
773da5c369Sopenharmony_ci        /// Receive all multicast packets. (see
783da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
793da5c369Sopenharmony_ci        IFF_ALLMULTI;
803da5c369Sopenharmony_ci        /// Master of a load balancing bundle. (see
813da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
823da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
833da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
843da5c369Sopenharmony_ci        IFF_MASTER;
853da5c369Sopenharmony_ci        /// transmission in progress, tx hardware queue is full
863da5c369Sopenharmony_ci        #[cfg(any(target_os = "freebsd",
873da5c369Sopenharmony_ci                  target_os = "macos",
883da5c369Sopenharmony_ci                  target_os = "netbsd",
893da5c369Sopenharmony_ci                  target_os = "openbsd",
903da5c369Sopenharmony_ci                  target_os = "ios"))]
913da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
923da5c369Sopenharmony_ci        IFF_OACTIVE;
933da5c369Sopenharmony_ci        /// Protocol code on board.
943da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
953da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
963da5c369Sopenharmony_ci        IFF_INTELLIGENT;
973da5c369Sopenharmony_ci        /// Slave of a load balancing bundle. (see
983da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
993da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
1003da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1013da5c369Sopenharmony_ci        IFF_SLAVE;
1023da5c369Sopenharmony_ci        /// Can't hear own transmissions.
1033da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly",
1043da5c369Sopenharmony_ci                  target_os = "freebsd",
1053da5c369Sopenharmony_ci                  target_os = "macos",
1063da5c369Sopenharmony_ci                  target_os = "netbsd",
1073da5c369Sopenharmony_ci                  target_os = "openbsd"))]
1083da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1093da5c369Sopenharmony_ci        IFF_SIMPLEX;
1103da5c369Sopenharmony_ci        /// Supports multicast. (see
1113da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
1123da5c369Sopenharmony_ci        IFF_MULTICAST;
1133da5c369Sopenharmony_ci        /// Per link layer defined bit.
1143da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly",
1153da5c369Sopenharmony_ci                  target_os = "freebsd",
1163da5c369Sopenharmony_ci                  target_os = "macos",
1173da5c369Sopenharmony_ci                  target_os = "netbsd",
1183da5c369Sopenharmony_ci                  target_os = "openbsd",
1193da5c369Sopenharmony_ci                  target_os = "ios"))]
1203da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1213da5c369Sopenharmony_ci        IFF_LINK0;
1223da5c369Sopenharmony_ci        /// Multicast using broadcast.
1233da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
1243da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1253da5c369Sopenharmony_ci        IFF_MULTI_BCAST;
1263da5c369Sopenharmony_ci        /// Is able to select media type via ifmap. (see
1273da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
1283da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
1293da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1303da5c369Sopenharmony_ci        IFF_PORTSEL;
1313da5c369Sopenharmony_ci        /// Per link layer defined bit.
1323da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly",
1333da5c369Sopenharmony_ci                  target_os = "freebsd",
1343da5c369Sopenharmony_ci                  target_os = "macos",
1353da5c369Sopenharmony_ci                  target_os = "netbsd",
1363da5c369Sopenharmony_ci                  target_os = "openbsd",
1373da5c369Sopenharmony_ci                  target_os = "ios"))]
1383da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1393da5c369Sopenharmony_ci        IFF_LINK1;
1403da5c369Sopenharmony_ci        /// Non-unique address.
1413da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
1423da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1433da5c369Sopenharmony_ci        IFF_UNNUMBERED;
1443da5c369Sopenharmony_ci        /// Auto media selection active. (see
1453da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
1463da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
1473da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1483da5c369Sopenharmony_ci        IFF_AUTOMEDIA;
1493da5c369Sopenharmony_ci        /// Per link layer defined bit.
1503da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly",
1513da5c369Sopenharmony_ci                  target_os = "freebsd",
1523da5c369Sopenharmony_ci                  target_os = "macos",
1533da5c369Sopenharmony_ci                  target_os = "netbsd",
1543da5c369Sopenharmony_ci                  target_os = "openbsd",
1553da5c369Sopenharmony_ci                  target_os = "ios"))]
1563da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1573da5c369Sopenharmony_ci        IFF_LINK2;
1583da5c369Sopenharmony_ci        /// Use alternate physical connection.
1593da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly",
1603da5c369Sopenharmony_ci                  target_os = "freebsd",
1613da5c369Sopenharmony_ci                  target_os = "macos",
1623da5c369Sopenharmony_ci                  target_os = "ios"))]
1633da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1643da5c369Sopenharmony_ci        IFF_ALTPHYS;
1653da5c369Sopenharmony_ci        /// DHCP controls interface.
1663da5c369Sopenharmony_ci        #[cfg(any(target_os = "solaris", target_os = "illumos"))]
1673da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1683da5c369Sopenharmony_ci        IFF_DHCPRUNNING;
1693da5c369Sopenharmony_ci        /// The addresses are lost when the interface goes down. (see
1703da5c369Sopenharmony_ci        /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
1713da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
1723da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1733da5c369Sopenharmony_ci        IFF_DYNAMIC;
1743da5c369Sopenharmony_ci        /// Do not advertise.
1753da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
1763da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1773da5c369Sopenharmony_ci        IFF_PRIVATE;
1783da5c369Sopenharmony_ci        /// Driver signals L1 up. Volatile.
1793da5c369Sopenharmony_ci        #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
1803da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1813da5c369Sopenharmony_ci        IFF_LOWER_UP;
1823da5c369Sopenharmony_ci        /// Interface is in polling mode.
1833da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly"))]
1843da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1853da5c369Sopenharmony_ci        IFF_POLLING_COMPAT;
1863da5c369Sopenharmony_ci        /// Unconfigurable using ioctl(2).
1873da5c369Sopenharmony_ci        #[cfg(any(target_os = "freebsd"))]
1883da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1893da5c369Sopenharmony_ci        IFF_CANTCONFIG;
1903da5c369Sopenharmony_ci        /// Do not transmit packets.
1913da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
1923da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1933da5c369Sopenharmony_ci        IFF_NOXMIT;
1943da5c369Sopenharmony_ci        /// Driver signals dormant. Volatile.
1953da5c369Sopenharmony_ci        #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
1963da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
1973da5c369Sopenharmony_ci        IFF_DORMANT;
1983da5c369Sopenharmony_ci        /// User-requested promisc mode.
1993da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
2003da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2013da5c369Sopenharmony_ci        IFF_PPROMISC;
2023da5c369Sopenharmony_ci        /// Just on-link subnet.
2033da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2043da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2053da5c369Sopenharmony_ci        IFF_NOLOCAL;
2063da5c369Sopenharmony_ci        /// Echo sent packets. Volatile.
2073da5c369Sopenharmony_ci        #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
2083da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2093da5c369Sopenharmony_ci        IFF_ECHO;
2103da5c369Sopenharmony_ci        /// User-requested monitor mode.
2113da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
2123da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2133da5c369Sopenharmony_ci        IFF_MONITOR;
2143da5c369Sopenharmony_ci        /// Address is deprecated.
2153da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2163da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2173da5c369Sopenharmony_ci        IFF_DEPRECATED;
2183da5c369Sopenharmony_ci        /// Static ARP.
2193da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
2203da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2213da5c369Sopenharmony_ci        IFF_STATICARP;
2223da5c369Sopenharmony_ci        /// Address from stateless addrconf.
2233da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2243da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2253da5c369Sopenharmony_ci        IFF_ADDRCONF;
2263da5c369Sopenharmony_ci        /// Interface is in polling mode.
2273da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly"))]
2283da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2293da5c369Sopenharmony_ci        IFF_NPOLLING;
2303da5c369Sopenharmony_ci        /// Router on interface.
2313da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2323da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2333da5c369Sopenharmony_ci        IFF_ROUTER;
2343da5c369Sopenharmony_ci        /// Interface is in polling mode.
2353da5c369Sopenharmony_ci        #[cfg(any(target_os = "dragonfly"))]
2363da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2373da5c369Sopenharmony_ci        IFF_IDIRECT;
2383da5c369Sopenharmony_ci        /// Interface is winding down
2393da5c369Sopenharmony_ci        #[cfg(any(target_os = "freebsd"))]
2403da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2413da5c369Sopenharmony_ci        IFF_DYING;
2423da5c369Sopenharmony_ci        /// No NUD on interface.
2433da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2443da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2453da5c369Sopenharmony_ci        IFF_NONUD;
2463da5c369Sopenharmony_ci        /// Interface is being renamed
2473da5c369Sopenharmony_ci        #[cfg(any(target_os = "freebsd"))]
2483da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2493da5c369Sopenharmony_ci        IFF_RENAMING;
2503da5c369Sopenharmony_ci        /// Anycast address.
2513da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2523da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2533da5c369Sopenharmony_ci        IFF_ANYCAST;
2543da5c369Sopenharmony_ci        /// Don't exchange routing info.
2553da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2563da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2573da5c369Sopenharmony_ci        IFF_NORTEXCH;
2583da5c369Sopenharmony_ci        /// Do not provide packet information
2593da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
2603da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2613da5c369Sopenharmony_ci        IFF_NO_PI as libc::c_int;
2623da5c369Sopenharmony_ci        /// TUN device (no Ethernet headers)
2633da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
2643da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2653da5c369Sopenharmony_ci        IFF_TUN as libc::c_int;
2663da5c369Sopenharmony_ci        /// TAP device
2673da5c369Sopenharmony_ci        #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
2683da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2693da5c369Sopenharmony_ci        IFF_TAP as libc::c_int;
2703da5c369Sopenharmony_ci        /// IPv4 interface.
2713da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2723da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2733da5c369Sopenharmony_ci        IFF_IPV4;
2743da5c369Sopenharmony_ci        /// IPv6 interface.
2753da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2763da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2773da5c369Sopenharmony_ci        IFF_IPV6;
2783da5c369Sopenharmony_ci        /// in.mpathd test address
2793da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2803da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2813da5c369Sopenharmony_ci        IFF_NOFAILOVER;
2823da5c369Sopenharmony_ci        /// Interface has failed
2833da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2843da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2853da5c369Sopenharmony_ci        IFF_FAILED;
2863da5c369Sopenharmony_ci        /// Interface is a hot-spare
2873da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2883da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2893da5c369Sopenharmony_ci        IFF_STANDBY;
2903da5c369Sopenharmony_ci        /// Functioning but not used
2913da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2923da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2933da5c369Sopenharmony_ci        IFF_INACTIVE;
2943da5c369Sopenharmony_ci        /// Interface is offline
2953da5c369Sopenharmony_ci        #[cfg(any(target_os = "illumos", target_os = "solaris"))]
2963da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
2973da5c369Sopenharmony_ci        IFF_OFFLINE;
2983da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
2993da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3003da5c369Sopenharmony_ci        IFF_COS_ENABLED;
3013da5c369Sopenharmony_ci        /// Prefer as source addr.
3023da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
3033da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3043da5c369Sopenharmony_ci        IFF_PREFERRED;
3053da5c369Sopenharmony_ci        /// RFC3041
3063da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
3073da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3083da5c369Sopenharmony_ci        IFF_TEMPORARY;
3093da5c369Sopenharmony_ci        /// MTU set with SIOCSLIFMTU
3103da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
3113da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3123da5c369Sopenharmony_ci        IFF_FIXEDMTU;
3133da5c369Sopenharmony_ci        /// Cannot send / receive packets
3143da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
3153da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3163da5c369Sopenharmony_ci        IFF_VIRTUAL;
3173da5c369Sopenharmony_ci        /// Local address in use
3183da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
3193da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3203da5c369Sopenharmony_ci        IFF_DUPLICATE;
3213da5c369Sopenharmony_ci        /// IPMP IP interface
3223da5c369Sopenharmony_ci        #[cfg(target_os = "solaris")]
3233da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
3243da5c369Sopenharmony_ci        IFF_IPMP;
3253da5c369Sopenharmony_ci    }
3263da5c369Sopenharmony_ci);
3273da5c369Sopenharmony_ci
3283da5c369Sopenharmony_ci#[cfg(any(
3293da5c369Sopenharmony_ci    target_os = "dragonfly",
3303da5c369Sopenharmony_ci    target_os = "freebsd",
3313da5c369Sopenharmony_ci    target_os = "fuchsia",
3323da5c369Sopenharmony_ci    target_os = "ios",
3333da5c369Sopenharmony_ci    target_os = "linux",
3343da5c369Sopenharmony_ci    target_os = "macos",
3353da5c369Sopenharmony_ci    target_os = "netbsd",
3363da5c369Sopenharmony_ci    target_os = "openbsd",
3373da5c369Sopenharmony_ci))]
3383da5c369Sopenharmony_ci#[cfg_attr(docsrs, doc(cfg(all())))]
3393da5c369Sopenharmony_cimod if_nameindex {
3403da5c369Sopenharmony_ci    use super::*;
3413da5c369Sopenharmony_ci
3423da5c369Sopenharmony_ci    use std::ffi::CStr;
3433da5c369Sopenharmony_ci    use std::fmt;
3443da5c369Sopenharmony_ci    use std::marker::PhantomData;
3453da5c369Sopenharmony_ci    use std::ptr::NonNull;
3463da5c369Sopenharmony_ci
3473da5c369Sopenharmony_ci    /// A network interface. Has a name like "eth0" or "wlp4s0" or "wlan0", as well as an index
3483da5c369Sopenharmony_ci    /// (1, 2, 3, etc) that identifies it in the OS's networking stack.
3493da5c369Sopenharmony_ci    #[allow(missing_copy_implementations)]
3503da5c369Sopenharmony_ci    #[repr(transparent)]
3513da5c369Sopenharmony_ci    pub struct Interface(libc::if_nameindex);
3523da5c369Sopenharmony_ci
3533da5c369Sopenharmony_ci    impl Interface {
3543da5c369Sopenharmony_ci        /// Obtain the index of this interface.
3553da5c369Sopenharmony_ci        pub fn index(&self) -> c_uint {
3563da5c369Sopenharmony_ci            self.0.if_index
3573da5c369Sopenharmony_ci        }
3583da5c369Sopenharmony_ci
3593da5c369Sopenharmony_ci        /// Obtain the name of this interface.
3603da5c369Sopenharmony_ci        pub fn name(&self) -> &CStr {
3613da5c369Sopenharmony_ci            unsafe { CStr::from_ptr(self.0.if_name) }
3623da5c369Sopenharmony_ci        }
3633da5c369Sopenharmony_ci    }
3643da5c369Sopenharmony_ci
3653da5c369Sopenharmony_ci    impl fmt::Debug for Interface {
3663da5c369Sopenharmony_ci        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3673da5c369Sopenharmony_ci            f.debug_struct("Interface")
3683da5c369Sopenharmony_ci                .field("index", &self.index())
3693da5c369Sopenharmony_ci                .field("name", &self.name())
3703da5c369Sopenharmony_ci                .finish()
3713da5c369Sopenharmony_ci        }
3723da5c369Sopenharmony_ci    }
3733da5c369Sopenharmony_ci
3743da5c369Sopenharmony_ci    /// A list of the network interfaces available on this system. Obtained from [`if_nameindex()`].
3753da5c369Sopenharmony_ci    pub struct Interfaces {
3763da5c369Sopenharmony_ci        ptr: NonNull<libc::if_nameindex>,
3773da5c369Sopenharmony_ci    }
3783da5c369Sopenharmony_ci
3793da5c369Sopenharmony_ci    impl Interfaces {
3803da5c369Sopenharmony_ci        /// Iterate over the interfaces in this list.
3813da5c369Sopenharmony_ci        #[inline]
3823da5c369Sopenharmony_ci        pub fn iter(&self) -> InterfacesIter<'_> {
3833da5c369Sopenharmony_ci            self.into_iter()
3843da5c369Sopenharmony_ci        }
3853da5c369Sopenharmony_ci
3863da5c369Sopenharmony_ci        /// Convert this to a slice of interfaces. Note that the underlying interfaces list is
3873da5c369Sopenharmony_ci        /// null-terminated, so calling this calculates the length. If random access isn't needed,
3883da5c369Sopenharmony_ci        /// [`Interfaces::iter()`] should be used instead.
3893da5c369Sopenharmony_ci        pub fn to_slice(&self) -> &[Interface] {
3903da5c369Sopenharmony_ci            let ifs = self.ptr.as_ptr() as *const Interface;
3913da5c369Sopenharmony_ci            let len = self.iter().count();
3923da5c369Sopenharmony_ci            unsafe { std::slice::from_raw_parts(ifs, len) }
3933da5c369Sopenharmony_ci        }
3943da5c369Sopenharmony_ci    }
3953da5c369Sopenharmony_ci
3963da5c369Sopenharmony_ci    impl Drop for Interfaces {
3973da5c369Sopenharmony_ci        fn drop(&mut self) {
3983da5c369Sopenharmony_ci            unsafe { libc::if_freenameindex(self.ptr.as_ptr()) };
3993da5c369Sopenharmony_ci        }
4003da5c369Sopenharmony_ci    }
4013da5c369Sopenharmony_ci
4023da5c369Sopenharmony_ci    impl fmt::Debug for Interfaces {
4033da5c369Sopenharmony_ci        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4043da5c369Sopenharmony_ci            self.to_slice().fmt(f)
4053da5c369Sopenharmony_ci        }
4063da5c369Sopenharmony_ci    }
4073da5c369Sopenharmony_ci
4083da5c369Sopenharmony_ci    impl<'a> IntoIterator for &'a Interfaces {
4093da5c369Sopenharmony_ci        type IntoIter = InterfacesIter<'a>;
4103da5c369Sopenharmony_ci        type Item = &'a Interface;
4113da5c369Sopenharmony_ci        #[inline]
4123da5c369Sopenharmony_ci        fn into_iter(self) -> Self::IntoIter {
4133da5c369Sopenharmony_ci            InterfacesIter {
4143da5c369Sopenharmony_ci                ptr: self.ptr.as_ptr(),
4153da5c369Sopenharmony_ci                _marker: PhantomData,
4163da5c369Sopenharmony_ci            }
4173da5c369Sopenharmony_ci        }
4183da5c369Sopenharmony_ci    }
4193da5c369Sopenharmony_ci
4203da5c369Sopenharmony_ci    /// An iterator over the interfaces in an [`Interfaces`].
4213da5c369Sopenharmony_ci    #[derive(Debug)]
4223da5c369Sopenharmony_ci    pub struct InterfacesIter<'a> {
4233da5c369Sopenharmony_ci        ptr: *const libc::if_nameindex,
4243da5c369Sopenharmony_ci        _marker: PhantomData<&'a Interfaces>,
4253da5c369Sopenharmony_ci    }
4263da5c369Sopenharmony_ci
4273da5c369Sopenharmony_ci    impl<'a> Iterator for InterfacesIter<'a> {
4283da5c369Sopenharmony_ci        type Item = &'a Interface;
4293da5c369Sopenharmony_ci        #[inline]
4303da5c369Sopenharmony_ci        fn next(&mut self) -> Option<Self::Item> {
4313da5c369Sopenharmony_ci            unsafe {
4323da5c369Sopenharmony_ci                if (*self.ptr).if_index == 0 {
4333da5c369Sopenharmony_ci                    None
4343da5c369Sopenharmony_ci                } else {
4353da5c369Sopenharmony_ci                    let ret = &*(self.ptr as *const Interface);
4363da5c369Sopenharmony_ci                    self.ptr = self.ptr.add(1);
4373da5c369Sopenharmony_ci                    Some(ret)
4383da5c369Sopenharmony_ci                }
4393da5c369Sopenharmony_ci            }
4403da5c369Sopenharmony_ci        }
4413da5c369Sopenharmony_ci    }
4423da5c369Sopenharmony_ci
4433da5c369Sopenharmony_ci    /// Retrieve a list of the network interfaces available on the local system.
4443da5c369Sopenharmony_ci    ///
4453da5c369Sopenharmony_ci    /// ```
4463da5c369Sopenharmony_ci    /// let interfaces = nix::net::if_::if_nameindex().unwrap();
4473da5c369Sopenharmony_ci    /// for iface in &interfaces {
4483da5c369Sopenharmony_ci    ///     println!("Interface #{} is called {}", iface.index(), iface.name().to_string_lossy());
4493da5c369Sopenharmony_ci    /// }
4503da5c369Sopenharmony_ci    /// ```
4513da5c369Sopenharmony_ci    pub fn if_nameindex() -> Result<Interfaces> {
4523da5c369Sopenharmony_ci        unsafe {
4533da5c369Sopenharmony_ci            let ifs = libc::if_nameindex();
4543da5c369Sopenharmony_ci            let ptr = NonNull::new(ifs).ok_or_else(Error::last)?;
4553da5c369Sopenharmony_ci            Ok(Interfaces { ptr })
4563da5c369Sopenharmony_ci        }
4573da5c369Sopenharmony_ci    }
4583da5c369Sopenharmony_ci}
4593da5c369Sopenharmony_ci#[cfg(any(
4603da5c369Sopenharmony_ci    target_os = "dragonfly",
4613da5c369Sopenharmony_ci    target_os = "freebsd",
4623da5c369Sopenharmony_ci    target_os = "fuchsia",
4633da5c369Sopenharmony_ci    target_os = "ios",
4643da5c369Sopenharmony_ci    target_os = "linux",
4653da5c369Sopenharmony_ci    target_os = "macos",
4663da5c369Sopenharmony_ci    target_os = "netbsd",
4673da5c369Sopenharmony_ci    target_os = "openbsd",
4683da5c369Sopenharmony_ci))]
4693da5c369Sopenharmony_cipub use if_nameindex::*;
470