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