19
19
use crate :: fd:: AsFd ;
20
20
use crate :: io;
21
21
#[ cfg( feature = "alloc" ) ]
22
- use alloc:: string:: String ;
22
+ use alloc:: { borrow :: ToOwned , string:: String } ;
23
23
24
24
/// `ioctl(fd, SIOCGIFINDEX, ifreq)`—Returns the interface index for a given
25
25
/// name.
@@ -42,6 +42,8 @@ pub fn name_to_index<Fd: AsFd>(fd: Fd, if_name: &str) -> io::Result<u32> {
42
42
///
43
43
/// See the [module-level documentation] for information about `fd` usage.
44
44
///
45
+ /// See also [`index_to_name_inlined`] which does not require `alloc` feature.
46
+ ///
45
47
/// # References
46
48
/// - [Linux]
47
49
///
@@ -52,12 +54,84 @@ pub fn name_to_index<Fd: AsFd>(fd: Fd, if_name: &str) -> io::Result<u32> {
52
54
#[ cfg( feature = "alloc" ) ]
53
55
#[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
54
56
pub fn index_to_name < Fd : AsFd > ( fd : Fd , index : u32 ) -> io:: Result < String > {
55
- crate :: backend:: net:: netdevice:: index_to_name ( fd. as_fd ( ) , index)
57
+ let ( len, ifrn_name) = crate :: backend:: net:: netdevice:: index_to_name ( fd. as_fd ( ) , index) ?;
58
+
59
+ core:: str:: from_utf8 ( & ifrn_name[ ..len] )
60
+ . map_err ( |_| io:: Errno :: ILSEQ )
61
+ . map ( ToOwned :: to_owned)
62
+ }
63
+
64
+ /// `ioctl(fd, SIOCGIFNAME, ifreq)`—Returns the interface name for a given
65
+ /// index.
66
+ ///
67
+ /// See the [module-level documentation] for information about `fd` usage.
68
+ ///
69
+ /// # References
70
+ /// - [Linux]
71
+ ///
72
+ /// [module-level documentation]: self
73
+ /// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
74
+ #[ inline]
75
+ #[ doc( alias = "SIOCGIFNAME" ) ]
76
+ pub fn index_to_name_inlined < Fd : AsFd > ( fd : Fd , index : u32 ) -> io:: Result < InlinedName > {
77
+ let ( len, ifrn_name) = crate :: backend:: net:: netdevice:: index_to_name ( fd. as_fd ( ) , index) ?;
78
+
79
+ // Check if the name is valid UTF-8.
80
+ core:: str:: from_utf8 ( & ifrn_name[ ..len] )
81
+ . map_err ( |_| io:: Errno :: ILSEQ )
82
+ . map ( |_| InlinedName {
83
+ len,
84
+ name : ifrn_name,
85
+ } )
86
+ }
87
+
88
+ /// The inlined interface name.
89
+ #[ derive( Debug , Copy , Clone , Eq , PartialEq , Hash ) ]
90
+ pub struct InlinedName {
91
+ len : usize ,
92
+ name : [ u8 ; 16 ] ,
93
+ }
94
+
95
+ impl InlinedName {
96
+ /// Returns the str representation of the inlined name.
97
+ pub fn as_str ( & self ) -> & str {
98
+ self . as_ref ( )
99
+ }
100
+
101
+ /// Returns the bytes representation of the inlined name.
102
+ pub fn as_bytes ( & self ) -> & [ u8 ] {
103
+ self . as_ref ( )
104
+ }
105
+ }
106
+
107
+ impl AsRef < [ u8 ] > for InlinedName {
108
+ fn as_ref ( & self ) -> & [ u8 ] {
109
+ & self . name [ ..self . len ]
110
+ }
111
+ }
112
+
113
+ impl AsRef < str > for InlinedName {
114
+ fn as_ref ( & self ) -> & str {
115
+ // SAFETY: `InlinedName` is constructed with valid UTF-8.
116
+ core:: str:: from_utf8 ( & self . name [ ..self . len ] ) . unwrap ( )
117
+ }
118
+ }
119
+
120
+ impl core:: borrow:: Borrow < str > for InlinedName {
121
+ fn borrow ( & self ) -> & str {
122
+ self . as_ref ( )
123
+ }
124
+ }
125
+
126
+ impl core:: fmt:: Display for InlinedName {
127
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
128
+ self . as_str ( ) . fmt ( f)
129
+ }
56
130
}
57
131
58
132
#[ cfg( test) ]
59
133
mod tests {
60
- use crate :: backend :: net :: netdevice :: { index_to_name, name_to_index} ;
134
+ use super :: { index_to_name, index_to_name_inlined , name_to_index} ;
61
135
use crate :: fd:: AsFd ;
62
136
use crate :: net:: { AddressFamily , SocketFlags , SocketType } ;
63
137
@@ -81,6 +155,31 @@ mod tests {
81
155
assert_eq ! ( Ok ( loopback_index) , name_to_index( fd. as_fd( ) , "lo" ) ) ;
82
156
}
83
157
158
+ #[ test]
159
+ fn test_index_to_name_inlined ( ) {
160
+ let fd = crate :: net:: socket_with (
161
+ AddressFamily :: INET ,
162
+ SocketType :: DGRAM ,
163
+ SocketFlags :: CLOEXEC ,
164
+ None ,
165
+ )
166
+ . unwrap ( ) ;
167
+
168
+ let loopback_index = std:: fs:: read_to_string ( "/sys/class/net/lo/ifindex" )
169
+ . unwrap ( )
170
+ . as_str ( )
171
+ . split_at ( 1 )
172
+ . 0
173
+ . parse :: < u32 > ( )
174
+ . unwrap ( ) ;
175
+ assert_eq ! (
176
+ "lo" ,
177
+ index_to_name_inlined( fd. as_fd( ) , loopback_index)
178
+ . unwrap( )
179
+ . as_str( ) ,
180
+ ) ;
181
+ }
182
+
84
183
#[ test]
85
184
#[ cfg( feature = "alloc" ) ]
86
185
fn test_index_to_name ( ) {
0 commit comments