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 }
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; #[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}