ifstructs/
lib.rs

1extern crate libc;
2#[macro_use]
3extern crate cfg_if;
4
5#[cfg(test)]
6#[macro_use]
7extern crate nix;
8
9#[macro_use]
10mod macros;
11
12use std::{io, mem};
13
14cfg_if! {
15    if #[cfg(any(target_os = "linux",
16                 target_os = "android",
17                 target_os = "fuchsia"))] {
18        mod notbsd;
19        pub use self::notbsd::*;
20    } else if #[cfg(any(target_os = "macos",
21                        target_os = "ios",
22                        target_os = "freebsd",
23                        target_os = "dragonfly",
24                        target_os = "openbsd",
25                        target_os = "netbsd",
26                        target_os = "bitrig"))] {
27        mod bsd;
28        pub use self::bsd::*;
29    } else {
30        // Unknown target_os
31    }
32}
33
34impl ifreq {
35    pub fn from_name(name: &str) -> io::Result<ifreq> {
36        let mut req: ifreq = unsafe { mem::zeroed() };
37        req.set_name(name)?;
38        Ok(req)
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    use std::env;
46    use std::io;
47
48    #[test]
49    fn test_get_iface_flags() {
50        #[cfg(any(target_os = "linux", target_os = "android"))]
51        let request_code = 0x8913; // #define SIOCGIFFLAGS	0x8913		/* get flags			*/
52        #[cfg(not(any(target_os = "linux", target_os = "android")))]
53        let request_code = request_code_readwrite!(b'i', 17, mem::size_of::<ifreq>());
54
55        #[cfg(any(target_os = "macos", target_os = "ios"))]
56        let default_iface = "lo0";
57        #[cfg(not(any(target_os = "macos", target_os = "ios")))]
58        let default_iface = "lo";
59
60        let iface_name = env::var("TEST_IFACE").unwrap_or(default_iface.to_owned());
61
62        let mut req = ifreq::from_name(&iface_name).unwrap();
63
64        let sock = unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0) };
65        if sock < 0 {
66            panic!("Socket error {:?}", io::Error::last_os_error());
67        }
68
69        let res = unsafe { libc::ioctl(sock, request_code, &mut req) };
70        if res < 0 {
71            panic!(
72                "SIOCGIFFLAGS failed with error on device '{}': {:?}",
73                iface_name,
74                io::Error::last_os_error()
75            );
76        }
77
78        let flags = req.get_flags();
79
80        assert_ne!(i64::from(flags) & i64::from(libc::IFF_UP), 0);
81    }
82}