1use crate::device::DeviceType;
2use crate::device::net::net_device::NetDevice;
3use crate::println;
4use crate::sync::SpinLock;
5use alloc::string::{String, ToString};
6use alloc::sync::Arc;
7use alloc::vec::Vec;
8use lazy_static::lazy_static;
9use smoltcp::iface::Interface;
10use smoltcp::time::Instant;
11use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
12
13pub struct NetworkInterfaceManager {
15 interfaces: Vec<Arc<NetworkInterface>>,
16}
17
18impl NetworkInterfaceManager {
19 pub fn new() -> Self {
21 Self {
22 interfaces: Vec::new(),
23 }
24 }
25
26 pub fn add_interface(&mut self, interface: Arc<NetworkInterface>) {
28 self.interfaces.push(interface);
29 }
30
31 pub fn get_interfaces(&self) -> &[Arc<NetworkInterface>] {
33 &self.interfaces
34 }
35
36 pub fn find_interface_by_name(&self, name: &str) -> Option<&Arc<NetworkInterface>> {
38 self.interfaces.iter().find(|iface| iface.name() == name)
39 }
40}
41
42lazy_static! {
43 pub static ref NETWORK_INTERFACE_MANAGER: SpinLock<NetworkInterfaceManager> =
45 SpinLock::new(NetworkInterfaceManager::new());
46}
47
48pub struct SmoltcpInterface {
50 device_adapter: NetDeviceAdapter,
51 iface: Interface,
52}
53
54impl SmoltcpInterface {
55 fn new(device: Arc<dyn NetDevice>, mac_address: EthernetAddress) -> Self {
57 let mut device_adapter = NetDeviceAdapter::new(device);
58
59 let config =
60 smoltcp::iface::Config::new(smoltcp::wire::HardwareAddress::Ethernet(mac_address));
61 let iface = Interface::new(
62 config,
63 &mut device_adapter,
64 smoltcp::time::Instant::from_millis(0),
65 );
66
67 Self {
68 device_adapter,
69 iface,
70 }
71 }
72
73 pub fn poll(
82 &mut self,
83 timestamp: Instant,
84 sockets: &mut smoltcp::iface::SocketSet,
85 ) -> smoltcp::iface::PollResult {
86 self.iface
87 .poll(timestamp, &mut self.device_adapter, sockets)
88 }
89
90 pub fn interface_mut(&mut self) -> &mut Interface {
92 &mut self.iface
93 }
94
95 pub fn interface(&self) -> &Interface {
97 &self.iface
98 }
99
100 pub fn device_adapter_mut(&mut self) -> &mut NetDeviceAdapter {
102 &mut self.device_adapter
103 }
104
105 pub fn into_interface(self) -> Interface {
107 self.iface
108 }
109}
110
111pub struct NetworkInterface {
113 name: String,
114 mac_address: EthernetAddress,
115 device: Arc<dyn NetDevice>,
116 ip_addresses: SpinLock<Vec<IpCidr>>,
117 ipv4_gateway: SpinLock<Option<Ipv4Address>>,
118 interrupt_enabled: SpinLock<bool>,
119 last_interrupt_time: SpinLock<Instant>,
120}
121
122impl NetworkInterface {
123 pub fn new(name: String, device: Arc<dyn NetDevice>) -> Self {
125 let mac_address = EthernetAddress(device.mac_address());
126 Self {
127 name,
128 mac_address,
129 device,
130 ip_addresses: SpinLock::new(Vec::new()),
131 ipv4_gateway: SpinLock::new(None),
132 interrupt_enabled: SpinLock::new(true),
133 last_interrupt_time: SpinLock::new(Instant::from_millis(0)),
134 }
135 }
136
137 pub fn name(&self) -> &str {
139 &self.name
140 }
141
142 pub fn mac_address(&self) -> EthernetAddress {
144 self.mac_address
145 }
146
147 pub fn device(&self) -> &Arc<dyn NetDevice> {
149 &self.device
150 }
151
152 pub fn add_ip_address(&self, ip_cidr: IpCidr) {
154 let mut ip_addresses = self.ip_addresses.lock();
155 if !ip_addresses.contains(&ip_cidr) {
156 ip_addresses.push(ip_cidr);
157 }
158 }
159
160 pub fn ip_addresses(&self) -> Vec<IpCidr> {
162 self.ip_addresses.lock().clone()
163 }
164
165 pub fn set_ipv4_gateway(&self, gateway: Option<Ipv4Address>) {
167 *self.ipv4_gateway.lock() = gateway;
168 }
169
170 pub fn ipv4_gateway(&self) -> Option<Ipv4Address> {
172 *self.ipv4_gateway.lock()
173 }
174
175 pub fn enable_interrupt(&self) {
177 *self.interrupt_enabled.lock() = true;
178 println!("Interrupt enabled for interface {}", self.name());
179 }
180
181 pub fn disable_interrupt(&self) {
183 *self.interrupt_enabled.lock() = false;
184 println!("Interrupt disabled for interface {}", self.name());
185 }
186
187 pub fn is_interrupt_enabled(&self) -> bool {
189 *self.interrupt_enabled.lock()
190 }
191
192 pub fn update_interrupt_time(&self) {
194 *self.last_interrupt_time.lock() =
197 Instant::from_millis(self.last_interrupt_time.lock().total_millis() + 1);
198 }
199
200 pub fn create_smoltcp_interface(&self) -> SmoltcpInterface {
205 let mut smoltcp_iface = SmoltcpInterface::new(self.device.clone(), self.mac_address());
207
208 for ip_cidr in self.ip_addresses.lock().iter() {
210 smoltcp_iface.interface_mut().update_ip_addrs(|addrs| {
211 addrs.push(*ip_cidr);
212 });
213 }
214
215 if let Some(gateway) = self.ipv4_gateway() {
217 smoltcp_iface
218 .interface_mut()
219 .routes_mut()
220 .add_default_ipv4_route(gateway)
221 .ok();
222 }
223
224 smoltcp_iface
225 }
226}
227
228pub struct NetDeviceAdapter {
230 device: Arc<dyn NetDevice>,
231 rx_buffer: [u8; 2048],
232}
233
234impl NetDeviceAdapter {
235 pub fn new(device: Arc<dyn NetDevice>) -> Self {
237 Self {
238 device,
239 rx_buffer: [0; 2048],
240 }
241 }
242}
243
244impl smoltcp::phy::Device for NetDeviceAdapter {
246 type RxToken<'a> = NetRxToken<'a>;
247 type TxToken<'a> = NetTxToken<'a>;
248
249 fn receive(
250 &mut self,
251 _timestamp: smoltcp::time::Instant,
252 ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
253 match self.device.receive(&mut self.rx_buffer) {
255 Ok(size) if size > 0 => Some((
256 NetRxToken {
257 buffer: &self.rx_buffer[..size],
258 },
259 NetTxToken {
260 device: &self.device,
261 },
262 )),
263 _ => None,
264 }
265 }
266
267 fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
268 Some(NetTxToken {
269 device: &self.device,
270 })
271 }
272
273 fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities {
274 let mut caps = smoltcp::phy::DeviceCapabilities::default();
275 caps.max_transmission_unit = self.device.mtu() as usize;
276 caps.medium = smoltcp::phy::Medium::Ethernet;
277 caps.max_burst_size = Some(1);
278 caps
279 }
280}
281pub struct NetRxToken<'a> {
283 buffer: &'a [u8],
284}
285
286impl smoltcp::phy::RxToken for NetRxToken<'_> {
287 fn consume<R, F>(self, f: F) -> R
288 where
289 F: FnOnce(&[u8]) -> R,
290 {
291 f(self.buffer)
292 }
293
294 fn meta(&self) -> smoltcp::phy::PacketMeta {
295 smoltcp::phy::PacketMeta::default()
296 }
297}
298
299pub struct NetTxToken<'a> {
301 device: &'a Arc<dyn NetDevice>,
302}
303
304impl smoltcp::phy::TxToken for NetTxToken<'_> {
305 fn consume<R, F>(self, len: usize, f: F) -> R
306 where
307 F: FnOnce(&mut [u8]) -> R,
308 {
309 let mut buffer = alloc::vec![0; len];
311 let result = f(&mut buffer);
312
313 if let Err(_) = self.device.send(&buffer) {
315 }
318
319 result
320 }
321
322 fn set_meta(&mut self, _meta: smoltcp::phy::PacketMeta) {}
323}
324
325impl crate::device::Driver for NetworkInterface {
327 fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
328 if !self.is_interrupt_enabled() {
330 return false;
331 }
332
333 if let Some(irq_num) = irq {
335 println!(
336 "Network interface {} received interrupt on IRQ {}",
337 self.name(),
338 irq_num
339 );
340 } else {
341 println!(
342 "Network interface {} received interrupt without IRQ number",
343 self.name()
344 );
345 }
346
347 self.update_interrupt_time();
349
350 let mut buffer = [0u8; 2048];
352 match self.device.receive(&mut buffer) {
353 Ok(size) if size > 0 => {
354 println!(
355 "Received {} bytes of data on interface {}",
356 size,
357 self.name()
358 );
359 crate::kernel::syscall::io::wake_poll_waiters();
361 true
362 }
363 Err(e) => {
364 println!("Error receiving data: {:?}", e);
365 true }
367 _ => {
368 true
370 }
371 }
372 }
373
374 fn device_type(&self) -> DeviceType {
375 DeviceType::Net
376 }
377
378 fn get_id(&self) -> alloc::string::String {
379 self.name.clone()
380 }
381
382 fn as_net(&self) -> Option<&dyn crate::device::net::net_device::NetDevice> {
383 Some(self.device.as_ref())
384 }
385
386 fn as_net_arc(self: Arc<Self>) -> Option<Arc<dyn crate::device::net::net_device::NetDevice>> {
387 Some(self.device.clone())
388 }
389
390 fn as_block(&self) -> Option<&dyn crate::device::block::BlockDriver> {
391 None
392 }
393
394 fn as_rtc(&self) -> Option<&dyn crate::device::rtc::RtcDriver> {
395 None
396 }
397}