1 //! Low-level Linux network device access
2 //!
3 //! The methods in this module take a socket's file descriptor to communicate with
4 //! the kernel in their ioctl call:
5 //! - glibc uses an `AF_UNIX`, `AF_INET`, or `AF_INET6` socket.
6 //! The address family itself does not matter and glibc tries the next address family if socket creation with one fails.
7 //! - Android (bionic) uses an `AF_INET` socket.
8 //! - Both create the socket with `SOCK_DGRAM|SOCK_CLOEXEC` type/flag.
9 //! - The [man-pages] specify, that the ioctl calls "can be used on any socket's file descriptor regardless of the
10 //! family or type".
11 //!
12 //! # References
13 //! - [Linux]
14 //!
15 //! [man-pages]: https://man7.org/linux/man-pages/man7/netdevice.7.html
16 //! [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
17
18 #[cfg(feature = "alloc")]
19 use crate::alloc::string::String;
20 use crate::fd::AsFd;
21 use crate::io;
22
23 /// `ioctl(fd, SIOCGIFINDEX, ifreq)`—Returns the interface index for a given name.
24 ///
25 /// See the [module-level documentation] for information about `fd` usage.
26 ///
27 /// # References
28 /// - [Linux]
29 ///
30 /// [module-level documentation]: self
31 /// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
32 #[inline]
33 #[doc(alias = "SIOCGIFINDEX")]
name_to_index(fd: impl AsFd, if_name: &str) -> io::Result<u32>34 pub fn name_to_index(fd: impl AsFd, if_name: &str) -> io::Result<u32> {
35 crate::backend::net::netdevice::name_to_index(fd, if_name)
36 }
37
38 /// `ioctl(fd, SIOCGIFNAME, ifreq)`—Returns the interface name for a given index.
39 ///
40 /// See the [module-level documentation] for information about `fd` usage.
41 ///
42 /// # References
43 /// - [Linux]
44 ///
45 /// [module-level documentation]: self
46 /// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
47 #[inline]
48 #[doc(alias = "SIOCGIFNAME")]
49 #[cfg(feature = "alloc")]
index_to_name(fd: impl AsFd, index: u32) -> io::Result<String>50 pub fn index_to_name(fd: impl AsFd, index: u32) -> io::Result<String> {
51 crate::backend::net::netdevice::index_to_name(fd, index)
52 }
53
54 #[cfg(test)]
55 mod tests {
56 use crate::backend::net::netdevice::{index_to_name, name_to_index};
57 use crate::net::{AddressFamily, SocketFlags, SocketType};
58
59 #[test]
test_name_to_index()60 fn test_name_to_index() {
61 let fd = crate::net::socket_with(
62 AddressFamily::INET,
63 SocketType::DGRAM,
64 SocketFlags::CLOEXEC,
65 None,
66 )
67 .unwrap();
68
69 let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex")
70 .unwrap()
71 .as_str()
72 .split_at(1)
73 .0
74 .parse::<u32>()
75 .unwrap();
76 assert_eq!(Ok(loopback_index), name_to_index(fd, "lo"));
77 }
78
79 #[test]
80 #[cfg(feature = "alloc")]
test_index_to_name()81 fn test_index_to_name() {
82 let fd = crate::net::socket_with(
83 AddressFamily::INET,
84 SocketType::DGRAM,
85 SocketFlags::CLOEXEC,
86 None,
87 )
88 .unwrap();
89
90 let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex")
91 .unwrap()
92 .as_str()
93 .split_at(1)
94 .0
95 .parse::<u32>()
96 .unwrap();
97 assert_eq!(Ok("lo".to_owned()), index_to_name(fd, loopback_index));
98 }
99 }
100