can use tap to receive packages

This commit is contained in:
Samuka007 2025-04-22 13:43:47 +08:00
parent 48ab5e9b25
commit c9f35158b2
8 changed files with 306 additions and 84 deletions

202
Cargo.lock generated
View File

@ -2,12 +2,71 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "allocator-api2" name = "allocator-api2"
version = "0.2.21" version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.98" version = "1.0.98"
@ -25,6 +84,7 @@ name = "berkeley-socket"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"env_logger",
"hashbrown", "hashbrown",
"lazy_static", "lazy_static",
"libc", "libc",
@ -33,6 +93,7 @@ dependencies = [
"netsock", "netsock",
"num-derive", "num-derive",
"num-traits", "num-traits",
"scopeguard",
"smoltcp", "smoltcp",
"spin", "spin",
] ]
@ -67,6 +128,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]] [[package]]
name = "defmt" name = "defmt"
version = "0.3.100" version = "0.3.100"
@ -108,6 +175,29 @@ dependencies = [
"thiserror 2.0.12", "thiserror 2.0.12",
] ]
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.2" version = "1.0.2"
@ -150,6 +240,36 @@ dependencies = [
"stable_deref_trait", "stable_deref_trait",
] ]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jiff"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a064218214dc6a10fbae5ec5fa888d80c45d611aba169222fc272072bf7aef6"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
]
[[package]]
name = "jiff-static"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "199b7932d97e325aff3a7030e141eafe7f2c6268e1d1b24859b753a627f45254"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@ -190,6 +310,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "netlink-packet-core" name = "netlink-packet-core"
version = "0.7.0" version = "0.7.0"
@ -277,12 +403,33 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.15" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]] [[package]]
name = "proc-macro-error-attr2" name = "proc-macro-error-attr2"
version = "2.0.0" version = "2.0.0"
@ -323,12 +470,61 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.15.0" version = "1.15.0"
@ -422,6 +618,12 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"

View File

@ -26,3 +26,5 @@ log = "*"
netsock = "0.3.0" netsock = "0.3.0"
libc = "0.2.172" libc = "0.2.172"
lazy_static = "1.5.0" lazy_static = "1.5.0"
scopeguard = "1.2.0"
env_logger = "0.11.8"

View File

@ -46,6 +46,7 @@ pub fn start_network_polling_thread() -> io::Result<thread::JoinHandle<()>> {
// Process events // Process events
for event in events.iter().take(num_events as usize) { for event in events.iter().take(num_events as usize) {
log::trace!("epoll_wait returned {} events", num_events);
let fd = event.u64 as RawFd; let fd = event.u64 as RawFd;
if let Some(&device_id) = fd_to_device_id.get(&fd) { if let Some(&device_id) = fd_to_device_id.get(&fd) {
@ -56,11 +57,11 @@ pub fn start_network_polling_thread() -> io::Result<thread::JoinHandle<()>> {
} }
} }
// Also poll all devices periodically regardless of events // // Also poll all devices periodically regardless of events
// This ensures timers and other internal state are updated // // This ensures timers and other internal state are updated
for device in NET_DEVICES.read().values() { // for device in NET_DEVICES.read().values() {
device.poll(); // device.poll();
} // }
// Small sleep to prevent CPU hogging // Small sleep to prevent CPU hogging
thread::sleep(Duration::from_millis(1)); thread::sleep(Duration::from_millis(1));
@ -90,6 +91,7 @@ fn update_watched_devices(epoll_fd: RawFd, fd_to_device_id: &mut HashMap<RawFd,
if result == 0 { if result == 0 {
fd_to_device_id.insert(tap_fd, id); fd_to_device_id.insert(tap_fd, id);
log::trace!("Added device fd {} to epoll", tap_fd);
} else { } else {
log::error!( log::error!(
"Failed to add device fd {} to epoll: {:?}", "Failed to add device fd {} to epoll: {:?}",

View File

@ -1,20 +1,15 @@
use std::io; use std::{io, mem};
pub mod tap; pub mod tap;
pub use tap::TapDesc; pub use tap::TapDesc;
pub mod irq; pub mod irq;
#[repr(C)] use libc::ifreq;
#[derive(Debug)]
struct ifreq {
ifr_name: [libc::c_char; libc::IF_NAMESIZE],
ifr_data: libc::c_int, /* ifr_ifindex or ifr_mtu */
}
fn ifreq_for(name: &str) -> ifreq { fn ifreq_for(name: &str) -> ifreq {
let mut ifreq = ifreq { let mut ifreq = ifreq {
ifr_name: [0; libc::IF_NAMESIZE], ifr_name: [0; libc::IFNAMSIZ],
ifr_data: 0, ifr_ifru: unsafe { mem::zeroed() },
}; };
for (i, byte) in name.as_bytes().iter().enumerate() { for (i, byte) in name.as_bytes().iter().enumerate() {
ifreq.ifr_name[i] = *byte as libc::c_char ifreq.ifr_name[i] = *byte as libc::c_char
@ -24,15 +19,14 @@ fn ifreq_for(name: &str) -> ifreq {
fn ifreq_ioctl( fn ifreq_ioctl(
lower: libc::c_int, lower: libc::c_int,
ifreq: &mut ifreq,
cmd: libc::c_ulong, cmd: libc::c_ulong,
) -> io::Result<libc::c_int> { ifreq: &mut ifreq,
) -> io::Result<i32> {
unsafe { unsafe {
let res = libc::ioctl(lower, cmd as _, ifreq as *mut ifreq); let res = libc::ioctl(lower, cmd as _, ifreq as *mut ifreq);
if res == -1 { if res == -1 {
return Err(io::Error::last_os_error()); return Err(io::Error::last_os_error());
} }
Ok(res)
} }
Ok(ifreq.ifr_data)
} }

View File

@ -1,4 +1,5 @@
use super::*; use super::*;
use scopeguard::defer;
use smoltcp::{phy::Medium, wire::EthernetFrame}; use smoltcp::{phy::Medium, wire::EthernetFrame};
use std::io; use std::io;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
@ -7,6 +8,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
pub struct TapDesc { pub struct TapDesc {
lower: libc::c_int, lower: libc::c_int,
mtu: usize, mtu: usize,
mac: smoltcp::wire::EthernetAddress,
} }
impl AsRawFd for TapDesc { impl AsRawFd for TapDesc {
@ -29,27 +31,23 @@ impl TapDesc {
}; };
let mut ifreq = ifreq_for(name); let mut ifreq = ifreq_for(name);
Self::attach_interface_ifreq(lower, medium, &mut ifreq)?; Self::attach_interface_ifreq(lower, &mut ifreq)?;
log::trace!("Successfully attach interface: {}", name);
let mtu = Self::mtu_ifreq(medium, &mut ifreq)?; let mtu = Self::mtu_ifreq(medium, &mut ifreq)?;
log::trace!("Successfully get MTU: {}", mtu);
let mac = Self::mac_ifreq(&mut ifreq)?;
log::trace!("Successfully get MAC: {}", mac);
Ok(TapDesc { lower, mtu }) Ok(TapDesc { lower, mtu, mac })
} }
pub fn from_fd(fd: RawFd, mtu: usize) -> io::Result<TapDesc> { // pub fn from_fd(fd: RawFd, mtu: usize) -> io::Result<TapDesc> {
Ok(TapDesc { lower: fd, mtu }) // Ok(TapDesc { lower: fd, mtu })
} // }
fn attach_interface_ifreq( fn attach_interface_ifreq(lower: libc::c_int, ifr: &mut ifreq) -> io::Result<()> {
lower: libc::c_int, ifr.ifr_ifru.ifru_flags = (libc::IFF_TAP | libc::IFF_NO_PI) as libc::c_short;
medium: Medium, ifreq_ioctl(lower, libc::TUNSETIFF, ifr).map(|_| ())
ifr: &mut ifreq,
) -> io::Result<()> {
let mode = match medium {
Medium::Ip => libc::IFF_TUN,
Medium::Ethernet => libc::IFF_TAP,
};
ifr.ifr_data = mode | libc::IFF_NO_PI;
ifreq_ioctl(lower, ifr, libc::TUNSETIFF).map(|_| ())
} }
fn mtu_ifreq(medium: Medium, ifr: &mut ifreq) -> io::Result<usize> { fn mtu_ifreq(medium: Medium, ifr: &mut ifreq) -> io::Result<usize> {
@ -60,15 +58,13 @@ impl TapDesc {
} }
lower lower
}; };
defer!(unsafe {
let ip_mtu = ifreq_ioctl(lower, ifr, libc::SIOCGIFMTU).map(|mtu| mtu as usize);
unsafe {
libc::close(lower); libc::close(lower);
} });
// Propagate error after close, to ensure we always close. let _ = ifreq_ioctl(lower, libc::SIOCGIFMTU, ifr)?;
let ip_mtu = ip_mtu?;
let ip_mtu = unsafe { ifr.ifr_ifru.ifru_mtu } as usize;
// SIOCGIFMTU returns the IP MTU (typically 1500 bytes.) // SIOCGIFMTU returns the IP MTU (typically 1500 bytes.)
// smoltcp counts the entire Ethernet packet in the MTU, so add the Ethernet header size to it. // smoltcp counts the entire Ethernet packet in the MTU, so add the Ethernet header size to it.
@ -81,6 +77,31 @@ impl TapDesc {
Ok(mtu) Ok(mtu)
} }
fn mac_ifreq(ifr: &mut ifreq) -> io::Result<smoltcp::wire::EthernetAddress> {
let lower = unsafe {
let lower = libc::socket(libc::AF_INET, libc::SOCK_DGRAM, libc::IPPROTO_IP);
if lower == -1 {
return Err(io::Error::last_os_error());
}
lower
};
defer!(unsafe {
libc::close(lower);
});
let mac = smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
unsafe {
ifr.ifr_ifru.ifru_hwaddr.sa_family = libc::ARPHRD_ETHER as u16;
ifr.ifr_ifru.ifru_hwaddr.sa_data[..6]
.copy_from_slice(&[0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
}
let _ = ifreq_ioctl(lower, libc::SIOCSIFHWADDR, ifr)?;
Ok(mac)
}
pub fn interface_mtu(&self) -> io::Result<usize> { pub fn interface_mtu(&self) -> io::Result<usize> {
Ok(self.mtu) Ok(self.mtu)
} }
@ -135,7 +156,6 @@ pub struct TapDevice {
lower: Rc<RefCell<crate::driver::TapDesc>>, lower: Rc<RefCell<crate::driver::TapDesc>>,
mtu: usize, mtu: usize,
medium: Medium, medium: Medium,
mac: smoltcp::wire::EthernetAddress,
} }
impl AsRawFd for TapDevice { impl AsRawFd for TapDevice {
@ -153,46 +173,28 @@ impl TapDevice {
pub fn new(name: &str, medium: Medium) -> io::Result<TapDevice> { pub fn new(name: &str, medium: Medium) -> io::Result<TapDevice> {
let lower = crate::driver::TapDesc::new(name, medium)?; let lower = crate::driver::TapDesc::new(name, medium)?;
let mtu = lower.interface_mtu()?; let mtu = lower.interface_mtu()?;
let mac = smoltcp::wire::EthernetAddress::from_bytes(&[
0x02,
0x00,
0x00,
std::random::random::<u8>(),
std::random::random::<u8>(),
std::random::random::<u8>(),
]);
Ok(TapDevice { Ok(TapDevice {
lower: Rc::new(RefCell::new(lower)), lower: Rc::new(RefCell::new(lower)),
mtu, mtu,
medium, medium,
mac,
}) })
} }
/// Attaches to a TUN/TAP interface specified by file descriptor `fd`. // /// Attaches to a TUN/TAP interface specified by file descriptor `fd`.
/// // ///
/// On platforms like Android, a file descriptor to a tun interface is exposed. // /// On platforms like Android, a file descriptor to a tun interface is exposed.
/// On these platforms, a TunTapInterface cannot be instantiated with a name. // /// On these platforms, a TunTapInterface cannot be instantiated with a name.
pub fn from_fd(fd: RawFd, medium: Medium, mtu: usize) -> io::Result<TapDevice> { // pub fn from_fd(fd: RawFd, medium: Medium, mtu: usize) -> io::Result<TapDevice> {
let lower = crate::driver::TapDesc::from_fd(fd, mtu)?; // let lower = crate::driver::TapDesc::from_fd(fd, mtu)?;
let mac = smoltcp::wire::EthernetAddress::from_bytes(&[ // Ok(TapDevice {
0x02, // lower: Rc::new(RefCell::new(lower)),
0x00, // mtu,
0x00, // medium,
std::random::random::<u8>(), // })
std::random::random::<u8>(), // }
std::random::random::<u8>(),
]);
Ok(TapDevice {
lower: Rc::new(RefCell::new(lower)),
mtu,
medium,
mac,
})
}
pub fn mac(&self) -> smoltcp::wire::EthernetAddress { pub fn mac(&self) -> smoltcp::wire::EthernetAddress {
self.mac self.lower.borrow().mac
} }
} }

View File

@ -1,4 +1,4 @@
use std::{ops::DerefMut, sync::Arc, time::Instant}; use std::{ops::DerefMut, os::fd::AsRawFd, sync::Arc, time::Instant};
use smoltcp::{ use smoltcp::{
iface::{Config, Interface}, iface::{Config, Interface},
@ -59,4 +59,8 @@ impl Iface for TapIface {
let reference = guard.deref_mut(); let reference = guard.deref_mut();
self.common.poll(reference); self.common.poll(reference);
} }
fn raw_fd(&self) -> Option<std::os::unix::io::RawFd> {
Some(self.inner.lock().as_raw_fd())
}
} }

View File

@ -1,26 +1,44 @@
use std::sync::Arc; use std::{net::Ipv4Addr, sync::Arc};
use berkeley_socket::{ use berkeley_socket::{
driver::{irq::start_network_polling_thread, tap::TapDevice}, interface::tap::TapIface, posix::SOCK, socket::{endpoint::Endpoint, inet::{common::NET_DEVICES, syscall::Inet}, Family} driver::{irq::start_network_polling_thread, tap::TapDevice}, interface::{tap::TapIface, Iface}, posix::SOCK, socket::{endpoint::Endpoint, inet::{common::NET_DEVICES, syscall::Inet}, Family}
}; };
use smoltcp::wire::{IpAddress, IpEndpoint}; use smoltcp::wire::{IpAddress, IpEndpoint, Ipv4Cidr, IpCidr};
use spin::Mutex; use spin::Mutex;
fn main() { fn main() {
env_logger::init();
let device = TapDevice::new("tap0", smoltcp::phy::Medium::Ethernet).unwrap(); let device = TapDevice::new("tap0", smoltcp::phy::Medium::Ethernet).unwrap();
let iface = Arc::new(TapIface::new(Arc::new(Mutex::new(device)))); let iface_inner = TapIface::new(Arc::new(Mutex::new(device)));
let ip_cidr = IpCidr::Ipv4(Ipv4Cidr::new(
Ipv4Addr::new(192, 168, 213, 2),
24
));
let ip_cidr = vec![ip_cidr];
iface_inner.update_ip_addrs(&ip_cidr).unwrap();
let iface = Arc::new(iface_inner);
NET_DEVICES.write().insert(0, iface); NET_DEVICES.write().insert(0, iface);
scopeguard::defer!({
NET_DEVICES.write().clear();
});
let _ = start_network_polling_thread(); let _ = start_network_polling_thread();
// TODO: add socket tests
let socket = Inet::socket(SOCK::Datagram, 0).unwrap(); let socket = Inet::socket(SOCK::Datagram, 0).unwrap();
socket.bind(Endpoint::Ip( socket.bind(Endpoint::Ip(
IpEndpoint::new( IpEndpoint::new(
IpAddress::v4(192, 168, 199, 1), IpAddress::v4(192, 168, 213, 2),
1234, 1234,
) )
)).unwrap(); )).unwrap();
let mut buffer = [0u8; 1024]; let mut buffer = [0u8; 1024];
socket.read(&mut buffer).unwrap();
socket.write(&buffer).unwrap(); loop {
let len = socket.read(&mut buffer).unwrap();
log::info!("Received {} bytes: {}", len, String::from_utf8_lossy(&buffer[..len]));
}
} }

View File

@ -21,8 +21,6 @@ pub enum Types {
} }
lazy_static::lazy_static! { lazy_static::lazy_static! {
/// # 所有网络接口的列表
/// 这个列表在中断上下文会使用到因此需要irqsave
pub static ref NET_DEVICES: RwLock<BTreeMap<usize, Arc<dyn Iface>>> = RwLock::new(BTreeMap::new()); pub static ref NET_DEVICES: RwLock<BTreeMap<usize, Arc<dyn Iface>>> = RwLock::new(BTreeMap::new());
} }