Skip to content

Commit 19e1899

Browse files
committed
Rework methods
1 parent 693649f commit 19e1899

File tree

6 files changed

+84
-104
lines changed

6 files changed

+84
-104
lines changed

src/backend/libc/net/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub(crate) mod ext;
88
target_os = "wasi"
99
)))]
1010
pub(crate) mod msghdr;
11-
#[cfg(all(target_os = "linux", feature = "alloc"))]
11+
#[cfg(target_os = "linux")]
1212
pub(crate) mod netdevice;
1313
pub(crate) mod read_sockaddr;
1414
pub(crate) mod send_recv;

src/backend/libc/net/netdevice.rs

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,55 @@
11
#![allow(unsafe_code)]
22

3+
#[cfg(feature = "alloc")]
34
use crate::alloc::string::String;
4-
use crate::alloc::string::ToString;
55
use crate::backend::io::syscalls::ioctl;
66
use crate::fd::AsFd;
7-
use crate::ffi::CStr;
8-
use crate::ffi::CString;
97
use crate::io;
108
use crate::net::netdevice::open_socket;
11-
use core::mem::MaybeUninit;
12-
use core::ptr::{addr_of, addr_of_mut};
13-
use libc::{c_char, ifreq, IFNAMSIZ, SIOCGIFINDEX, SIOCGIFNAME};
14-
15-
#[cfg(all(target_os = "linux", feature = "alloc"))]
16-
pub(crate) fn index_to_name(if_name: &str) -> io::Result<u32> {
17-
if if_name.len() >= IFNAMSIZ as usize {
9+
#[cfg(feature = "alloc")]
10+
use libc::SIOCGIFNAME;
11+
use libc::{__c_anonymous_ifr_ifru, ifreq, IFNAMSIZ, SIOCGIFINDEX};
12+
13+
#[cfg(target_os = "linux")]
14+
pub(crate) fn name_to_index(if_name: &str) -> io::Result<u32> {
15+
let if_name_bytes = if_name.as_bytes();
16+
if if_name_bytes.len() >= IFNAMSIZ as usize {
1817
return Err(io::Errno::NODEV);
1918
}
20-
let mut ifrn_name = [0; IFNAMSIZ as usize];
21-
let c_string_name = CString::new(if_name).map_err(|_cstr_err| io::Errno::INVAL)?;
22-
// Convert from CString to c_char array.
23-
c_string_name
24-
.as_bytes_with_nul()
25-
.iter()
26-
.map(|byte| *byte as c_char)
27-
.enumerate()
28-
.for_each(|(i, c_char_byte)| ifrn_name[i] = c_char_byte);
2919

30-
let mut uninit_ifreq = MaybeUninit::<ifreq>::uninit();
31-
let uninit_ifreq_ptr = uninit_ifreq.as_mut_ptr();
32-
unsafe {
33-
addr_of_mut!((*uninit_ifreq_ptr).ifr_name).write(ifrn_name);
34-
}
20+
let mut ifreq = ifreq {
21+
ifr_name: [0; 16],
22+
ifr_ifru: __c_anonymous_ifr_ifru { ifru_ifindex: 0 },
23+
};
24+
25+
let mut if_name_i8_iter = if_name_bytes.iter().map(|byte| *byte as i8);
26+
ifreq.ifr_name[..if_name_bytes.len()].fill_with(|| if_name_i8_iter.next().unwrap());
3527

3628
let fd = open_socket()?;
37-
unsafe { ioctl(fd.as_fd(), SIOCGIFINDEX as _, uninit_ifreq_ptr as _) }?;
38-
let index = unsafe { *addr_of!((*uninit_ifreq_ptr).ifr_ifru.ifru_ifindex) };
29+
unsafe { ioctl(fd.as_fd(), SIOCGIFINDEX, &mut ifreq as *mut ifreq as _) }?;
30+
let index = unsafe { ifreq.ifr_ifru.ifru_ifindex };
3931
Ok(index as u32)
4032
}
4133

4234
#[cfg(all(target_os = "linux", feature = "alloc"))]
43-
pub(crate) fn name_to_index(index: u32) -> io::Result<String> {
44-
let mut uninit_ifreq = MaybeUninit::<ifreq>::uninit();
45-
let uninit_ifreq_ptr = uninit_ifreq.as_mut_ptr();
46-
unsafe {
47-
addr_of_mut!((*uninit_ifreq_ptr).ifr_ifru.ifru_ifindex).write(index as _);
48-
}
35+
pub(crate) fn index_to_name(index: u32) -> io::Result<String> {
36+
let mut ifreq = ifreq {
37+
ifr_name: [0; 16],
38+
ifr_ifru: __c_anonymous_ifr_ifru {
39+
ifru_ifindex: index as _,
40+
},
41+
};
4942

5043
let fd = open_socket()?;
51-
unsafe { ioctl(fd.as_fd(), SIOCGIFNAME as _, uninit_ifreq_ptr as _) }?;
44+
unsafe { ioctl(fd.as_fd(), SIOCGIFNAME as _, &mut ifreq as *mut ifreq as _) }?;
5245

53-
let ifr_name = unsafe { *addr_of!((*uninit_ifreq_ptr).ifr_name) };
54-
let mut result_name = [0; IFNAMSIZ as usize];
55-
// Convert from c_char array to u8 array.
56-
ifr_name
46+
let Some(nul_byte) = ifreq.ifr_name.iter().position(|char| *char == 0) else {
47+
return Err(io::Errno::INVAL);
48+
};
49+
let name = ifreq.ifr_name[..nul_byte]
5750
.iter()
58-
.map(|v| *v as u8)
59-
.enumerate()
60-
.for_each(|(i, u8_byte)| result_name[i] = u8_byte);
61-
62-
let name = CStr::from_bytes_until_nul(&result_name).map_err(|_cstr_err| io::Errno::INVAL)?;
51+
.map(|v| *v as u8 as char)
52+
.collect();
6353

64-
Ok(name.to_string_lossy().to_string())
54+
Ok(name)
6555
}

src/backend/linux_raw/net/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub(crate) mod addr;
22
pub(crate) mod msghdr;
3-
#[cfg(all(target_os = "linux", feature = "alloc"))]
3+
#[cfg(target_os = "linux")]
44
pub(crate) mod netdevice;
55
pub(crate) mod read_sockaddr;
66
pub(crate) mod send_recv;
Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,58 @@
11
#![allow(unsafe_code)]
22

3+
#[cfg(feature = "alloc")]
34
use crate::alloc::string::String;
4-
use crate::alloc::string::ToString;
55
use crate::backend::io::syscalls::ioctl;
66
use crate::fd::AsFd;
7-
use crate::ffi::CStr;
8-
use crate::ffi::CString;
97
use crate::io;
108
use crate::net::netdevice::open_socket;
11-
use core::mem::MaybeUninit;
12-
use core::ptr::{addr_of, addr_of_mut};
13-
use linux_raw_sys::ctypes::c_char;
14-
use linux_raw_sys::ioctl::{SIOCGIFINDEX, SIOCGIFNAME};
15-
use linux_raw_sys::net::{ifreq, IFNAMSIZ};
16-
17-
#[cfg(all(target_os = "linux", feature = "alloc"))]
18-
pub(crate) fn index_to_name(if_name: &str) -> io::Result<u32> {
19-
if if_name.len() >= IFNAMSIZ as usize {
9+
use linux_raw_sys::ioctl::SIOCGIFINDEX;
10+
#[cfg(feature = "alloc")]
11+
use linux_raw_sys::ioctl::SIOCGIFNAME;
12+
use linux_raw_sys::net::{ifreq, ifreq__bindgen_ty_1, ifreq__bindgen_ty_2, IFNAMSIZ};
13+
14+
#[cfg(target_os = "linux")]
15+
pub(crate) fn name_to_index(if_name: &str) -> io::Result<u32> {
16+
let if_name_bytes = if_name.as_bytes();
17+
if if_name_bytes.len() >= IFNAMSIZ as usize {
2018
return Err(io::Errno::NODEV);
2119
}
22-
let mut ifrn_name = [0; IFNAMSIZ as usize];
23-
let c_string_name = CString::new(if_name).map_err(|_cstr_err| io::Errno::INVAL)?;
24-
// Convert from CString to c_char array.
25-
c_string_name
26-
.as_bytes_with_nul()
27-
.iter()
28-
.map(|byte| *byte as c_char)
29-
.enumerate()
30-
.for_each(|(i, c_char_byte)| ifrn_name[i] = c_char_byte);
3120

32-
let mut uninit_ifreq = MaybeUninit::<ifreq>::uninit();
33-
let uninit_ifreq_ptr = uninit_ifreq.as_mut_ptr();
34-
unsafe {
35-
addr_of_mut!((*uninit_ifreq_ptr).ifr_ifrn.ifrn_name).write(ifrn_name);
36-
}
21+
let mut ifreq = ifreq {
22+
ifr_ifrn: ifreq__bindgen_ty_1 { ifrn_name: [0; 16] },
23+
ifr_ifru: ifreq__bindgen_ty_2 { ifru_ivalue: 0 },
24+
};
25+
unsafe { ifreq.ifr_ifrn.ifrn_name[..if_name_bytes.len()].copy_from_slice(if_name_bytes) };
3726

3827
let fd = open_socket()?;
39-
unsafe { ioctl(fd.as_fd(), SIOCGIFINDEX, uninit_ifreq_ptr as _) }?;
40-
let index = unsafe { *addr_of!((*uninit_ifreq_ptr).ifr_ifru.ifru_ivalue) };
28+
unsafe { ioctl(fd.as_fd(), SIOCGIFINDEX, &mut ifreq as *mut ifreq as _) }?;
29+
let index = unsafe { ifreq.ifr_ifru.ifru_ivalue };
4130
Ok(index as u32)
4231
}
4332

4433
#[cfg(all(target_os = "linux", feature = "alloc"))]
45-
pub(crate) fn name_to_index(index: u32) -> io::Result<String> {
46-
let mut uninit_ifreq = MaybeUninit::<ifreq>::uninit();
47-
let uninit_ifreq_ptr = uninit_ifreq.as_mut_ptr();
48-
unsafe {
49-
addr_of_mut!((*uninit_ifreq_ptr).ifr_ifru.ifru_ivalue).write(index as _);
50-
}
34+
pub(crate) fn index_to_name(index: u32) -> io::Result<String> {
35+
let mut ifreq = ifreq {
36+
ifr_ifrn: ifreq__bindgen_ty_1 { ifrn_name: [0; 16] },
37+
ifr_ifru: ifreq__bindgen_ty_2 {
38+
ifru_ivalue: index as _,
39+
},
40+
};
5141

5242
let fd = open_socket()?;
53-
unsafe { ioctl(fd.as_fd(), SIOCGIFNAME, uninit_ifreq_ptr as _) }?;
43+
unsafe { ioctl(fd.as_fd(), SIOCGIFNAME, &mut ifreq as *mut ifreq as _) }?;
44+
45+
let Some(nul_byte) = unsafe { ifreq.ifr_ifrn.ifrn_name }
46+
.iter()
47+
.position(|char| *char == 0)
48+
else {
49+
return Err(io::Errno::INVAL);
50+
};
5451

55-
let ifrn_name = unsafe { *addr_of!((*uninit_ifreq_ptr).ifr_ifrn.ifrn_name) };
56-
let mut result_name = [0; IFNAMSIZ as usize];
57-
// Convert from c_char array to u8 array.
58-
ifrn_name
52+
let name = unsafe { ifreq.ifr_ifrn.ifrn_name }[..nul_byte]
5953
.iter()
60-
.map(|v| *v as u8)
61-
.enumerate()
62-
.for_each(|(i, u8_byte)| result_name[i] = u8_byte);
54+
.map(|v| *v as char)
55+
.collect();
6356

64-
let name = CStr::from_bytes_until_nul(&result_name).map_err(|_cstr_err| io::Errno::INVAL)?;
65-
Ok(name.to_string_lossy().to_string())
57+
Ok(name)
6658
}

src/net/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ mod types;
1616
#[cfg(windows)]
1717
mod wsa;
1818

19-
// Currently limited to feature = "alloc" as it only contains methods requiring alloc at this time.
20-
#[cfg(all(target_os = "linux", feature = "alloc"))]
19+
#[cfg(target_os = "linux")]
2120
pub mod netdevice;
2221
pub mod sockopt;
2322

src/net/netdevice.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@
55
//!
66
//! [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
77
8+
#[cfg(feature = "alloc")]
89
use crate::alloc::string::String;
910
use crate::fd::OwnedFd;
1011
use crate::io;
1112
use crate::io::Errno;
1213
use crate::net::{socket, AddressFamily, SocketType};
1314

1415
/// Creates a socket used to communicate with the kernel in the ioctl calls.
15-
// Currently limited to feature = "alloc" as it is only used by methods
16-
// requiring alloc at this time.
17-
#[cfg(all(target_os = "linux", feature = "alloc"))]
16+
#[cfg(target_os = "linux")]
1817
pub(crate) fn open_socket() -> io::Result<OwnedFd> {
1918
if let Ok(fd) = socket(AddressFamily::UNIX, SocketType::DGRAM, None) {
2019
Ok(fd)
@@ -35,9 +34,9 @@ pub(crate) fn open_socket() -> io::Result<OwnedFd> {
3534
/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html
3635
#[inline]
3736
#[doc(alias = "SIOCGIFINDEX")]
38-
#[cfg(all(target_os = "linux", feature = "alloc"))]
39-
pub fn index_to_name(if_name: &str) -> io::Result<u32> {
40-
crate::backend::net::netdevice::index_to_name(if_name)
37+
#[cfg(target_os = "linux")]
38+
pub fn name_to_index(if_name: &str) -> io::Result<u32> {
39+
crate::backend::net::netdevice::name_to_index(if_name)
4140
}
4241

4342
/// `ioctl(fd, SIOCGIFNAME, ifreq)`—Returns the interface name for a given index.
@@ -49,37 +48,37 @@ pub fn index_to_name(if_name: &str) -> io::Result<u32> {
4948
#[inline]
5049
#[doc(alias = "SIOCGIFNAME")]
5150
#[cfg(all(target_os = "linux", feature = "alloc"))]
52-
pub fn name_to_index(index: u32) -> io::Result<String> {
53-
crate::backend::net::netdevice::name_to_index(index)
51+
pub fn index_to_name(index: u32) -> io::Result<String> {
52+
crate::backend::net::netdevice::index_to_name(index)
5453
}
5554

5655
#[cfg(test)]
5756
mod tests {
5857
use crate::backend::net::netdevice::{index_to_name, name_to_index};
5958

6059
#[test]
61-
#[cfg(all(target_os = "linux", feature = "alloc"))]
62-
fn test_index_to_name() {
60+
#[cfg(target_os = "linux")]
61+
fn test_name_to_index() {
6362
let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex")
6463
.unwrap()
6564
.as_str()
6665
.split_at(1)
6766
.0
6867
.parse::<u32>()
6968
.unwrap();
70-
assert_eq!(Ok(loopback_index), index_to_name("lo"));
69+
assert_eq!(Ok(loopback_index), name_to_index("lo"));
7170
}
7271

7372
#[test]
7473
#[cfg(all(target_os = "linux", feature = "alloc"))]
75-
fn test_name_to_index() {
74+
fn test_index_to_name() {
7675
let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex")
7776
.unwrap()
7877
.as_str()
7978
.split_at(1)
8079
.0
8180
.parse::<u32>()
8281
.unwrap();
83-
assert_eq!(Ok("lo".to_owned()), name_to_index(loopback_index));
82+
assert_eq!(Ok("lo".to_owned()), index_to_name(loopback_index));
8483
}
8584
}

0 commit comments

Comments
 (0)