Nothing to see here, move along
at main 1676 lines 58 kB view raw
1#![no_std] 2#![no_main] 3 4mod device; 5mod stack; 6 7use device::PacketDevice; 8use lancer_core::dns::{ 9 DNS_TYPE_A, DNS_TYPE_PTR, build_mdns_a_response, build_mdns_ptr_response, dns_name_eq, 10 dns_skip_name, 11}; 12use lancer_core::net_config::NetConfig; 13use lancer_core::packet_ring::{PacketRingReader, PacketRingWriter}; 14use lancer_core::sync_unsafe::SyncUnsafe; 15use lancer_user::syscall; 16use smoltcp::socket::{dhcpv4, dns, icmp, udp}; 17use smoltcp::time::Duration; 18use smoltcp::time::Instant; 19use smoltcp::wire::{DnsQueryType, IpAddress, IpCidr, IpListenEndpoint, Ipv4Address, Ipv6Address}; 20use stack::{MAX_SHELL_SOCKETS, MAX_UDP_SOCKETS}; 21 22const PACKET_RING_BASE_SLOT: u64 = 64; 23const PACKET_RING_FRAME_COUNT: u64 = 16; 24const NOTIF_SLOT: u64 = 3; 25const DRIVER_NOTIF_SLOT: u64 = 4; 26const SHELL_RING_BASE_SLOT: u64 = 96; 27const SHELL_RING_FRAME_COUNT: u64 = 4; 28const SHELL_NOTIF_SLOT: u64 = 6; 29const INIT_RING_BASE_SLOT: u64 = 128; 30const INIT_RING_FRAME_COUNT: u64 = 2; 31const INIT_NOTIF_SLOT: u64 = 8; 32 33const RING_BASE_VADDR: u64 = 0x4000_0000; 34const RING_HALF_SIZE: usize = 32768; 35 36const SHELL_RING_BASE: u64 = 0x5000_0000; 37const SHELL_RING_HALF: usize = 8192; 38 39const INIT_RING_BASE: u64 = 0x6000_0000; 40const INIT_RING_HALF: usize = 4096; 41 42const ECHO_PORT: u16 = 7; 43const SHELL_PORT: u16 = 22; 44 45const MAC: [u8; 6] = [0x52, 0x54, 0x00, 0x12, 0x34, 0x56]; 46 47const NOTIFY_BIT_RX: u64 = 1; 48const NOTIFY_BIT_TX: u64 = 2; 49 50const MSG_DATA: u8 = 0; 51const MSG_CONNECT: u8 = 1; 52const MSG_DISCONNECT: u8 = 2; 53const MSG_DNS_QUERY: u8 = 3; 54const MSG_DNS_RESULT: u8 = 4; 55const MSG_PING_REQUEST: u8 = 5; 56const MSG_PING_RESULT: u8 = 6; 57const MSG_PING_DONE: u8 = 7; 58const MSG_UDP_BIND: u8 = 8; 59const MSG_UDP_SEND: u8 = 9; 60const MSG_UDP_RECV: u8 = 10; 61const MSG_UDP_CLOSE: u8 = 11; 62const MSG_UDP_BOUND: u8 = 12; 63const MSG_DNS_QUERY6: u8 = 13; 64const MSG_DNS_RESULT6: u8 = 14; 65const MSG_PING_REQUEST6: u8 = 15; 66const MSG_IFCONFIG_REQUEST: u8 = 16; 67const MSG_IFCONFIG_RESULT: u8 = 17; 68const MSG_ARP_REQUEST: u8 = 18; 69const MSG_ARP_ENTRY: u8 = 19; 70const MSG_ARP_DONE: u8 = 20; 71const MSG_NETSTAT_REQUEST: u8 = 21; 72const MSG_NETSTAT_ENTRY: u8 = 22; 73const MSG_NETSTAT_ENTRY_UDP: u8 = 23; 74const MSG_NETSTAT_DONE: u8 = 24; 75const MSG_MCAST_JOIN: u8 = 25; 76const MSG_MCAST_LEAVE: u8 = 26; 77const MSG_MCAST_RESULT: u8 = 27; 78 79const MAX_PENDING_DNS: usize = 4; 80const MAX_PINGS: usize = 8; 81const PING_IDENT: u16 = 0x4C41; 82const PING_TIMEOUT_MS: i64 = 2000; 83const PING_INTERVAL_MS: i64 = 1000; 84 85#[derive(Clone, Copy, PartialEq, Eq)] 86enum RingSource { 87 Shell, 88 Init, 89} 90 91struct PendingPing { 92 conn_id: u8, 93 target: IpAddress, 94 total: u8, 95 sent: u8, 96 received: u8, 97 next_send_ms: i64, 98 send_times: [i64; MAX_PINGS], 99 replied_mask: u8, 100 timeout_mask: u8, 101 send_failures: u8, 102 ring_source: RingSource, 103} 104 105static mut PENDING_PING: Option<PendingPing> = None; 106 107struct PendingDns { 108 conn_id: u8, 109 handle: dns::QueryHandle, 110 is_v6: bool, 111 ring_source: RingSource, 112} 113 114static mut PENDING_DNS: [Option<PendingDns>; MAX_PENDING_DNS] = [const { None }; MAX_PENDING_DNS]; 115static mut UDP_RING_SOURCE: [RingSource; MAX_UDP_SOCKETS] = [RingSource::Shell; MAX_UDP_SOCKETS]; 116 117fn log_ip(prefix: &str, a: u8, b: u8, c: u8, d: u8) { 118 lancer_user::show!(net, "{}{}.{}.{}.{}", prefix, a, b, c, d); 119} 120 121fn send_router_solicitation(tx: &PacketRingWriter, mac: &[u8; 6]) { 122 let mut frame = [0u8; 70]; 123 124 frame[0..6].copy_from_slice(&[0x33, 0x33, 0x00, 0x00, 0x00, 0x02]); 125 frame[6..12].copy_from_slice(mac); 126 frame[12] = 0x86; 127 frame[13] = 0xDD; 128 129 frame[14] = 0x60; 130 let payload_len: u16 = 16; 131 frame[18] = (payload_len >> 8) as u8; 132 frame[19] = payload_len as u8; 133 frame[20] = 58; 134 frame[21] = 255; 135 136 let src_addr = stack::eui64_link_local_bytes(mac); 137 frame[22..38].copy_from_slice(&src_addr); 138 frame[38..54].copy_from_slice(&[0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02]); 139 140 frame[54] = 133; 141 frame[55] = 0; 142 frame[56] = 0; 143 frame[57] = 0; 144 frame[58..62].copy_from_slice(&[0; 4]); 145 146 frame[62] = 1; 147 frame[63] = 1; 148 frame[64..70].copy_from_slice(mac); 149 150 let cksum = icmpv6_checksum(&frame[22..38], &frame[38..54], &frame[54..70]); 151 frame[56] = (cksum >> 8) as u8; 152 frame[57] = cksum as u8; 153 154 tx.try_push(&frame[..70]); 155 lancer_user::show!(net, "sent router solicitation"); 156} 157 158fn icmpv6_checksum(src: &[u8], dst: &[u8], icmpv6: &[u8]) -> u16 { 159 let mut sum = 0u32; 160 161 let add_u16 = |sum: &mut u32, hi: u8, lo: u8| { 162 *sum += ((hi as u32) << 8) | lo as u32; 163 }; 164 165 (0..8).for_each(|i| { 166 add_u16(&mut sum, src[i * 2], src[i * 2 + 1]); 167 add_u16(&mut sum, dst[i * 2], dst[i * 2 + 1]); 168 }); 169 170 let upper_len = icmpv6.len() as u32; 171 sum += upper_len; 172 sum += 58u32; 173 174 let mut i = 0usize; 175 core::iter::from_fn(|| match i + 1 < icmpv6.len() { 176 true => { 177 add_u16(&mut sum, icmpv6[i], icmpv6[i + 1]); 178 i += 2; 179 Some(()) 180 } 181 false => None, 182 }) 183 .count(); 184 if i < icmpv6.len() { 185 add_u16(&mut sum, icmpv6[i], 0); 186 } 187 188 sum = (sum >> 16) + (sum & 0xFFFF); 189 sum += sum >> 16; 190 !(sum as u16) 191} 192 193static mut SLAAC_CONFIGURED: bool = false; 194static NET_CONFIG: SyncUnsafe<NetConfig> = SyncUnsafe::new(NetConfig::empty()); 195 196fn configure_slaac(net: &mut stack::NetStack, slaac: &device::SlaacInfo) { 197 let already = unsafe { (&raw const SLAAC_CONFIGURED).read() }; 198 if already { 199 return; 200 } 201 202 let iid = eui64_interface_id(&MAC); 203 204 let mut addr_bytes = [0u8; 16]; 205 addr_bytes.copy_from_slice(&slaac.prefix); 206 let prefix_bits = slaac.prefix_len as usize; 207 (prefix_bits / 8..16).for_each(|i| { 208 let bit_start = match i == prefix_bits / 8 { 209 true => prefix_bits % 8, 210 false => 0, 211 }; 212 match bit_start == 0 { 213 true => addr_bytes[i] = iid[i], 214 false => { 215 let host_mask = 0xFFu8 >> bit_start; 216 addr_bytes[i] = (addr_bytes[i] & !host_mask) | (iid[i] & host_mask); 217 } 218 } 219 }); 220 221 let ipv6_addr = Ipv6Address::from_octets(addr_bytes); 222 net.iface.update_ip_addrs(|addrs| { 223 let has_global = addrs.iter().any(|a| match a { 224 IpCidr::Ipv6(cidr) => !cidr.address().is_unicast_link_local(), 225 _ => false, 226 }); 227 match has_global { 228 true => {} 229 false => { 230 let _ = addrs.push(IpCidr::Ipv6(smoltcp::wire::Ipv6Cidr::new( 231 ipv6_addr, 232 slaac.prefix_len, 233 ))); 234 } 235 } 236 }); 237 238 let router = Ipv6Address::from_octets(slaac.router); 239 let _ = net.iface.routes_mut().add_default_ipv6_route(router); 240 241 unsafe { (&raw mut SLAAC_CONFIGURED).write(true) }; 242 let cfg = unsafe { NET_CONFIG.as_mut_unchecked() }; 243 cfg.set_ipv6_global(addr_bytes, slaac.prefix_len); 244 lancer_user::show!(net, "slaac global ipv6 configured"); 245} 246 247fn eui64_interface_id(mac: &[u8; 6]) -> [u8; 16] { 248 let mut iid = [0u8; 16]; 249 iid[8] = mac[0] ^ 0x02; 250 iid[9] = mac[1]; 251 iid[10] = mac[2]; 252 iid[11] = 0xFF; 253 iid[12] = 0xFE; 254 iid[13] = mac[3]; 255 iid[14] = mac[4]; 256 iid[15] = mac[5]; 257 iid 258} 259 260fn handle_dhcp_event(net: &mut stack::NetStack, ever_configured: &mut bool) { 261 let event = { 262 let dhcp = net.sockets.get_mut::<dhcpv4::Socket>(net.dhcp_handle); 263 dhcp.poll() 264 }; 265 266 match event { 267 Some(dhcpv4::Event::Configured(config)) => { 268 *ever_configured = true; 269 let addr = config.address; 270 net.iface.update_ip_addrs(|addrs| { 271 match addrs.iter_mut().find(|a| matches!(a, IpCidr::Ipv4(_))) { 272 Some(slot) => *slot = IpCidr::Ipv4(addr), 273 None => { 274 let _ = addrs.push(IpCidr::Ipv4(addr)); 275 } 276 } 277 }); 278 279 if let Some(router) = config.router { 280 let _ = net.iface.routes_mut().add_default_ipv4_route(router); 281 let octets = router.octets(); 282 log_ip("DHCP: gateway ", octets[0], octets[1], octets[2], octets[3]); 283 } 284 285 let octets = addr.address().octets(); 286 log_ip( 287 "DHCP: acquired ", 288 octets[0], 289 octets[1], 290 octets[2], 291 octets[3], 292 ); 293 294 let mut dns_addrs: [IpAddress; 3] = [IpAddress::v4(0, 0, 0, 0); 3]; 295 let dns_count = config.dns_servers.len().min(3); 296 let mut dns_octets = [[0u8; 4]; 3]; 297 (0..dns_count).for_each(|i| { 298 dns_addrs[i] = IpAddress::Ipv4(config.dns_servers[i]); 299 dns_octets[i] = config.dns_servers[i].octets(); 300 let o = dns_octets[i]; 301 log_ip("DHCP: dns ", o[0], o[1], o[2], o[3]); 302 }); 303 304 let gw_octets = config.router.map(|r| r.octets()); 305 306 let dns = net.sockets.get_mut::<dns::Socket>(net.dns_handle); 307 dns.update_servers(&dns_addrs[..dns_count]); 308 309 let cfg = unsafe { NET_CONFIG.as_mut_unchecked() }; 310 cfg.set_ipv4(octets, addr.prefix_len()); 311 if let Some(gw) = gw_octets { 312 cfg.set_gateway(gw); 313 } 314 cfg.set_dns(&dns_octets, dns_count as u8); 315 } 316 Some(dhcpv4::Event::Deconfigured) if *ever_configured => { 317 lancer_user::show!(net, "dhcp lease lost"); 318 net.iface.update_ip_addrs(|addrs| { 319 if let Some(idx) = (0..addrs.len()).find(|&i| matches!(addrs[i], IpCidr::Ipv4(_))) { 320 addrs.swap_remove(idx); 321 } 322 }); 323 net.iface.routes_mut().remove_default_ipv4_route(); 324 let cfg = unsafe { NET_CONFIG.as_mut_unchecked() }; 325 cfg.clear_ipv4(); 326 } 327 _ => {} 328 } 329} 330 331fn tx_for_source<'a>( 332 source: RingSource, 333 shell_tx: &'a PacketRingWriter, 334 init_tx: Option<&'a PacketRingWriter>, 335) -> &'a PacketRingWriter { 336 match source { 337 RingSource::Shell => shell_tx, 338 RingSource::Init => init_tx.expect("init ring required for Init-sourced request"), 339 } 340} 341 342#[allow(clippy::deref_addrof)] 343fn poll_pending_dns( 344 net: &mut stack::NetStack, 345 shell_tx: &PacketRingWriter, 346 init_tx: Option<&PacketRingWriter>, 347) -> (bool, bool) { 348 let pending: &mut [Option<PendingDns>; MAX_PENDING_DNS] = 349 unsafe { &mut *(&raw mut PENDING_DNS) }; 350 let mut any_shell = false; 351 let mut any_init = false; 352 353 pending.iter_mut().for_each(|slot| { 354 let should_clear = match slot { 355 Some(pd) => { 356 let tx = tx_for_source(pd.ring_source, shell_tx, init_tx); 357 let dns = net.sockets.get_mut::<dns::Socket>(net.dns_handle); 358 match dns.get_query_result(pd.handle) { 359 Ok(addrs) => { 360 match pd.is_v6 { 361 false => { 362 let v4 = addrs.iter().find_map(|a| match a { 363 IpAddress::Ipv4(v4) => Some(v4.octets()), 364 _ => None, 365 }); 366 let mut msg = [0u8; 8]; 367 msg[0] = pd.conn_id; 368 msg[1] = MSG_DNS_RESULT; 369 match v4 { 370 Some(octets) => { 371 msg[2] = 0; 372 msg[3] = octets[0]; 373 msg[4] = octets[1]; 374 msg[5] = octets[2]; 375 msg[6] = octets[3]; 376 let _ = tx.try_push(&msg[..7]); 377 } 378 None => { 379 msg[2] = 2; 380 let _ = tx.try_push(&msg[..3]); 381 } 382 } 383 } 384 true => { 385 let v6 = addrs.iter().find_map(|a| match a { 386 IpAddress::Ipv6(v6) => Some(v6.octets()), 387 _ => None, 388 }); 389 let mut msg = [0u8; 20]; 390 msg[0] = pd.conn_id; 391 msg[1] = MSG_DNS_RESULT6; 392 match v6 { 393 Some(octets) => { 394 msg[2] = 0; 395 msg[3..19].copy_from_slice(&octets); 396 let _ = tx.try_push(&msg[..19]); 397 } 398 None => { 399 msg[2] = 2; 400 let _ = tx.try_push(&msg[..3]); 401 } 402 } 403 } 404 } 405 match pd.ring_source { 406 RingSource::Shell => any_shell = true, 407 RingSource::Init => any_init = true, 408 } 409 true 410 } 411 Err(dns::GetQueryResultError::Pending) => false, 412 Err(dns::GetQueryResultError::Failed) => { 413 let result_type = match pd.is_v6 { 414 true => MSG_DNS_RESULT6, 415 false => MSG_DNS_RESULT, 416 }; 417 let msg = [pd.conn_id, result_type, 2]; 418 let _ = tx.try_push(&msg); 419 match pd.ring_source { 420 RingSource::Shell => any_shell = true, 421 RingSource::Init => any_init = true, 422 } 423 true 424 } 425 } 426 } 427 None => false, 428 }; 429 if should_clear { 430 *slot = None; 431 } 432 }); 433 434 (any_shell, any_init) 435} 436 437#[allow(clippy::deref_addrof)] 438fn handle_dns_query( 439 net: &mut stack::NetStack, 440 tx: &PacketRingWriter, 441 conn_id: u8, 442 hostname_bytes: &[u8], 443 is_v6: bool, 444 source: RingSource, 445) { 446 let result_type = match is_v6 { 447 false => MSG_DNS_RESULT, 448 true => MSG_DNS_RESULT6, 449 }; 450 let name = match core::str::from_utf8(hostname_bytes) { 451 Ok(s) => s, 452 Err(_) => { 453 let msg = [conn_id, result_type, 2]; 454 let _ = tx.try_push(&msg); 455 return; 456 } 457 }; 458 459 let query_type = match is_v6 { 460 false => DnsQueryType::A, 461 true => DnsQueryType::Aaaa, 462 }; 463 let dns = net.sockets.get_mut::<dns::Socket>(net.dns_handle); 464 match dns.start_query(net.iface.context(), name, query_type) { 465 Ok(handle) => { 466 let pending: &mut [Option<PendingDns>; MAX_PENDING_DNS] = 467 unsafe { &mut *(&raw mut PENDING_DNS) }; 468 match pending.iter_mut().find(|s| s.is_none()) { 469 Some(slot) => { 470 *slot = Some(PendingDns { 471 conn_id, 472 handle, 473 is_v6, 474 ring_source: source, 475 }); 476 } 477 None => { 478 dns.cancel_query(handle); 479 let msg = [conn_id, result_type, 2]; 480 let _ = tx.try_push(&msg); 481 } 482 } 483 } 484 Err(_) => { 485 let msg = [conn_id, result_type, 2]; 486 let _ = tx.try_push(&msg); 487 } 488 } 489} 490 491fn icmp_checksum(data: &[u8]) -> u16 { 492 let mut sum = 0u32; 493 let mut i = 0usize; 494 core::iter::from_fn(|| match i + 1 < data.len() { 495 true => { 496 sum += ((data[i] as u32) << 8) | (data[i + 1] as u32); 497 i += 2; 498 Some(()) 499 } 500 false => None, 501 }) 502 .count(); 503 if i < data.len() { 504 sum += (data[i] as u32) << 8; 505 } 506 sum = (sum >> 16) + (sum & 0xFFFF); 507 sum += sum >> 16; 508 !(sum as u16) 509} 510 511#[allow(clippy::deref_addrof)] 512fn ping_send(net: &mut stack::NetStack, now_ms: i64) { 513 let pending: &mut Option<PendingPing> = unsafe { &mut *(&raw mut PENDING_PING) }; 514 let pp = match pending.as_mut() { 515 Some(pp) => pp, 516 None => return, 517 }; 518 519 if pp.sent >= pp.total || now_ms < pp.next_send_ms { 520 return; 521 } 522 523 let seq = pp.sent as u16; 524 let icmp_type = match pp.target { 525 IpAddress::Ipv4(_) => 8u8, 526 IpAddress::Ipv6(_) => 128u8, 527 }; 528 529 let mut packet = [0u8; 12]; 530 packet[0] = icmp_type; 531 packet[1] = 0; 532 packet[4] = (PING_IDENT >> 8) as u8; 533 packet[5] = PING_IDENT as u8; 534 packet[6] = (seq >> 8) as u8; 535 packet[7] = seq as u8; 536 let ts = now_ms as u32; 537 packet[8] = (ts >> 24) as u8; 538 packet[9] = (ts >> 16) as u8; 539 packet[10] = (ts >> 8) as u8; 540 packet[11] = ts as u8; 541 542 match pp.target { 543 IpAddress::Ipv4(_) => { 544 let cksum = icmp_checksum(&packet); 545 packet[2] = (cksum >> 8) as u8; 546 packet[3] = cksum as u8; 547 } 548 IpAddress::Ipv6(_) => {} 549 } 550 551 let socket = net.sockets.get_mut::<icmp::Socket>(net.icmp_handle); 552 match socket.send_slice(&packet, pp.target) { 553 Ok(()) => { 554 pp.send_failures = 0; 555 pp.send_times[pp.sent as usize] = now_ms; 556 pp.sent += 1; 557 pp.next_send_ms = now_ms + PING_INTERVAL_MS; 558 } 559 Err(_) => { 560 pp.send_failures += 1; 561 match pp.send_failures >= 4 { 562 true => { 563 pp.send_failures = 0; 564 pp.send_times[pp.sent as usize] = 0; 565 pp.sent += 1; 566 pp.next_send_ms = now_ms + PING_INTERVAL_MS; 567 } 568 false => { 569 pp.next_send_ms = now_ms + 200; 570 } 571 } 572 } 573 } 574} 575 576#[allow(clippy::deref_addrof)] 577fn ping_recv( 578 net: &mut stack::NetStack, 579 shell_tx: &PacketRingWriter, 580 init_tx: Option<&PacketRingWriter>, 581 now_ms: i64, 582) -> (bool, bool) { 583 let pending: &mut Option<PendingPing> = unsafe { &mut *(&raw mut PENDING_PING) }; 584 let pp = match pending.as_mut() { 585 Some(pp) => pp, 586 None => return (false, false), 587 }; 588 589 let tx = tx_for_source(pp.ring_source, shell_tx, init_tx); 590 let socket = net.sockets.get_mut::<icmp::Socket>(net.icmp_handle); 591 let mut buf = [0u8; 64]; 592 let mut any_result = false; 593 594 core::iter::from_fn(|| match socket.recv_slice(&mut buf) { 595 Ok((len, _addr)) if len >= 8 => { 596 let typ = buf[0]; 597 let ident = ((buf[4] as u16) << 8) | buf[5] as u16; 598 let seq = ((buf[6] as u16) << 8) | buf[7] as u16; 599 600 let reply_type = match pp.target { 601 IpAddress::Ipv4(_) => 0u8, 602 IpAddress::Ipv6(_) => 129u8, 603 }; 604 if typ == reply_type && ident == PING_IDENT && seq < pp.sent as u16 { 605 let seq_idx = seq as u8; 606 if pp.replied_mask & (1 << seq_idx) == 0 { 607 pp.replied_mask |= 1 << seq_idx; 608 pp.received += 1; 609 let rtt = (now_ms - pp.send_times[seq_idx as usize]).max(0) as u16; 610 let msg = [ 611 pp.conn_id, 612 MSG_PING_RESULT, 613 seq_idx, 614 0, 615 (rtt >> 8) as u8, 616 rtt as u8, 617 ]; 618 let _ = tx.try_push(&msg); 619 any_result = true; 620 } 621 } 622 Some(()) 623 } 624 _ => None, 625 }) 626 .take(4) 627 .count(); 628 629 match any_result { 630 true => match pp.ring_source { 631 RingSource::Shell => (true, false), 632 RingSource::Init => (false, true), 633 }, 634 false => (false, false), 635 } 636} 637 638#[allow(clippy::deref_addrof)] 639fn ping_timeout( 640 shell_tx: &PacketRingWriter, 641 init_tx: Option<&PacketRingWriter>, 642 now_ms: i64, 643) -> (bool, bool) { 644 let pending: &mut Option<PendingPing> = unsafe { &mut *(&raw mut PENDING_PING) }; 645 let pp = match pending.as_mut() { 646 Some(pp) => pp, 647 None => return (false, false), 648 }; 649 650 let tx = tx_for_source(pp.ring_source, shell_tx, init_tx); 651 let mut any_timeout = false; 652 (0..pp.sent).for_each(|seq| { 653 let mask = 1u8 << seq; 654 if pp.replied_mask & mask != 0 || pp.timeout_mask & mask != 0 { 655 return; 656 } 657 if now_ms - pp.send_times[seq as usize] > PING_TIMEOUT_MS { 658 pp.timeout_mask |= mask; 659 let msg = [pp.conn_id, MSG_PING_RESULT, seq, 1, 0, 0]; 660 let _ = tx.try_push(&msg); 661 any_timeout = true; 662 } 663 }); 664 665 match any_timeout { 666 true => match pp.ring_source { 667 RingSource::Shell => (true, false), 668 RingSource::Init => (false, true), 669 }, 670 false => (false, false), 671 } 672} 673 674#[allow(clippy::deref_addrof)] 675fn ping_check_done( 676 shell_tx: &PacketRingWriter, 677 init_tx: Option<&PacketRingWriter>, 678) -> (bool, bool) { 679 let pending: &mut Option<PendingPing> = unsafe { &mut *(&raw mut PENDING_PING) }; 680 let pp = match pending.as_ref() { 681 Some(pp) => pp, 682 None => return (false, false), 683 }; 684 685 let all_accounted = pp.sent == pp.total 686 && (pp.replied_mask | pp.timeout_mask) == ((1u16 << pp.total) - 1) as u8; 687 688 match all_accounted { 689 true => { 690 let source = pp.ring_source; 691 let tx = tx_for_source(source, shell_tx, init_tx); 692 let msg = [pp.conn_id, MSG_PING_DONE, pp.received, pp.total]; 693 let _ = tx.try_push(&msg); 694 *pending = None; 695 match source { 696 RingSource::Shell => (true, false), 697 RingSource::Init => (false, true), 698 } 699 } 700 false => (false, false), 701 } 702} 703 704#[allow(clippy::deref_addrof)] 705fn handle_ping_request( 706 tx: &PacketRingWriter, 707 conn_id: u8, 708 data: &[u8], 709 now_ms: i64, 710 source: RingSource, 711) { 712 let pending: &mut Option<PendingPing> = unsafe { &mut *(&raw mut PENDING_PING) }; 713 if pending.is_some() { 714 let msg = [conn_id, MSG_PING_DONE, 0, 0]; 715 let _ = tx.try_push(&msg); 716 return; 717 } 718 719 if data.len() < 5 { 720 let msg = [conn_id, MSG_PING_DONE, 0, 0]; 721 let _ = tx.try_push(&msg); 722 return; 723 } 724 725 let target = IpAddress::Ipv4(Ipv4Address::new(data[0], data[1], data[2], data[3])); 726 let count = data[4].clamp(1, MAX_PINGS as u8); 727 728 *pending = Some(PendingPing { 729 conn_id, 730 target, 731 total: count, 732 sent: 0, 733 received: 0, 734 next_send_ms: now_ms, 735 send_times: [0i64; MAX_PINGS], 736 replied_mask: 0, 737 timeout_mask: 0, 738 send_failures: 0, 739 ring_source: source, 740 }); 741} 742 743#[allow(clippy::deref_addrof)] 744fn handle_ping_request6( 745 tx: &PacketRingWriter, 746 conn_id: u8, 747 data: &[u8], 748 now_ms: i64, 749 source: RingSource, 750) { 751 let pending: &mut Option<PendingPing> = unsafe { &mut *(&raw mut PENDING_PING) }; 752 if pending.is_some() { 753 let msg = [conn_id, MSG_PING_DONE, 0, 0]; 754 let _ = tx.try_push(&msg); 755 return; 756 } 757 758 if data.len() < 17 { 759 let msg = [conn_id, MSG_PING_DONE, 0, 0]; 760 let _ = tx.try_push(&msg); 761 return; 762 } 763 764 let mut addr_bytes = [0u8; 16]; 765 addr_bytes.copy_from_slice(&data[..16]); 766 let target = IpAddress::Ipv6(Ipv6Address::from_octets(addr_bytes)); 767 let count = data[16].clamp(1, MAX_PINGS as u8); 768 769 *pending = Some(PendingPing { 770 conn_id, 771 target, 772 total: count, 773 sent: 0, 774 received: 0, 775 next_send_ms: now_ms, 776 send_times: [0i64; MAX_PINGS], 777 replied_mask: 0, 778 timeout_mask: 0, 779 send_failures: 0, 780 ring_source: source, 781 }); 782} 783 784#[allow(clippy::deref_addrof)] 785fn handle_udp_bind( 786 net: &mut stack::NetStack, 787 tx: &PacketRingWriter, 788 conn_id: u8, 789 data: &[u8], 790 source: RingSource, 791) { 792 if data.len() < 2 || (conn_id as usize) >= MAX_UDP_SOCKETS { 793 let msg = [conn_id, MSG_UDP_BOUND, 1]; 794 let _ = tx.try_push(&msg); 795 return; 796 } 797 798 let udp_sources: &mut [RingSource; MAX_UDP_SOCKETS] = 799 unsafe { &mut *(&raw mut UDP_RING_SOURCE) }; 800 udp_sources[conn_id as usize] = source; 801 802 let port = ((data[0] as u16) << 8) | data[1] as u16; 803 let socket = net 804 .sockets 805 .get_mut::<udp::Socket>(net.udp_handles[conn_id as usize]); 806 socket.close(); 807 match socket.bind(IpListenEndpoint { addr: None, port }) { 808 Ok(()) => { 809 lancer_user::show!(net, "udp bind ok"); 810 let msg = [conn_id, MSG_UDP_BOUND, 0]; 811 let _ = tx.try_push(&msg); 812 } 813 Err(_) => { 814 let msg = [conn_id, MSG_UDP_BOUND, 1]; 815 let _ = tx.try_push(&msg); 816 } 817 } 818} 819 820#[allow(clippy::deref_addrof)] 821fn handle_udp_send(net: &mut stack::NetStack, conn_id: u8, data: &[u8], source: RingSource) { 822 if data.len() < 7 || (conn_id as usize) >= MAX_UDP_SOCKETS { 823 return; 824 } 825 826 let udp_sources: &mut [RingSource; MAX_UDP_SOCKETS] = 827 unsafe { &mut *(&raw mut UDP_RING_SOURCE) }; 828 udp_sources[conn_id as usize] = source; 829 830 let ip = Ipv4Address::new(data[0], data[1], data[2], data[3]); 831 let port = ((data[4] as u16) << 8) | data[5] as u16; 832 let payload = &data[6..]; 833 834 let socket = net 835 .sockets 836 .get_mut::<udp::Socket>(net.udp_handles[conn_id as usize]); 837 if !socket.is_open() { 838 let ephemeral = 49152 + conn_id as u16; 839 let _ = socket.bind(IpListenEndpoint { 840 addr: None, 841 port: ephemeral, 842 }); 843 } 844 let _ = socket.send_slice(payload, (IpAddress::Ipv4(ip), port)); 845} 846 847fn handle_udp_close(net: &mut stack::NetStack, conn_id: u8) { 848 if (conn_id as usize) >= MAX_UDP_SOCKETS { 849 return; 850 } 851 let socket = net 852 .sockets 853 .get_mut::<udp::Socket>(net.udp_handles[conn_id as usize]); 854 socket.close(); 855} 856 857#[allow(clippy::deref_addrof)] 858fn poll_udp_recv( 859 net: &mut stack::NetStack, 860 shell_tx: &PacketRingWriter, 861 init_tx: Option<&PacketRingWriter>, 862) -> (bool, bool) { 863 let udp_sources: &[RingSource; MAX_UDP_SOCKETS] = unsafe { &*(&raw const UDP_RING_SOURCE) }; 864 let mut any_shell = false; 865 let mut any_init = false; 866 (0..MAX_UDP_SOCKETS).for_each(|i| { 867 let socket = net.sockets.get_mut::<udp::Socket>(net.udp_handles[i]); 868 if socket.is_open() && socket.can_recv() { 869 lancer_user::show!(net, "udp socket has data"); 870 } 871 let tx = tx_for_source(udp_sources[i], shell_tx, init_tx); 872 let source = udp_sources[i]; 873 let mut buf = [0u8; 128]; 874 core::iter::from_fn(|| match socket.can_recv() { 875 true => match socket.recv_slice(&mut buf[8..126]) { 876 Ok((len, endpoint)) => { 877 match endpoint.endpoint.addr { 878 IpAddress::Ipv4(ip) => { 879 let o = ip.octets(); 880 let port = endpoint.endpoint.port; 881 buf[0] = i as u8; 882 buf[1] = MSG_UDP_RECV; 883 buf[2] = o[0]; 884 buf[3] = o[1]; 885 buf[4] = o[2]; 886 buf[5] = o[3]; 887 buf[6] = (port >> 8) as u8; 888 buf[7] = port as u8; 889 let _ = tx.try_push(&buf[..8 + len]); 890 match source { 891 RingSource::Shell => any_shell = true, 892 RingSource::Init => any_init = true, 893 } 894 } 895 IpAddress::Ipv6(_) => {} 896 } 897 Some(()) 898 } 899 Err(_) => None, 900 }, 901 false => None, 902 }) 903 .take(4) 904 .count(); 905 }); 906 (any_shell, any_init) 907} 908 909fn handle_ifconfig_request(tx: &PacketRingWriter, conn_id: u8) { 910 let cfg: &NetConfig = unsafe { NET_CONFIG.as_ref_unchecked() }; 911 let mut msg = [0u8; 64]; 912 msg[0] = conn_id; 913 msg[1] = MSG_IFCONFIG_RESULT; 914 let n = cfg.serialize(&mut msg[2..]); 915 let _ = tx.try_push(&msg[..2 + n]); 916} 917 918fn handle_arp_request(tx: &PacketRingWriter, conn_id: u8, now_ms: i64) { 919 let table = device::arp_table(); 920 table.iter().filter(|e| e.valid).for_each(|entry| { 921 let age_secs = ((now_ms - entry.timestamp_ms) / 1000).max(0) as u16; 922 let mut msg = [0u8; 14]; 923 msg[0] = conn_id; 924 msg[1] = MSG_ARP_ENTRY; 925 msg[2..6].copy_from_slice(&entry.ip); 926 msg[6..12].copy_from_slice(&entry.mac); 927 msg[12] = (age_secs >> 8) as u8; 928 msg[13] = age_secs as u8; 929 let _ = tx.try_push(&msg); 930 }); 931 let done = [conn_id, MSG_ARP_DONE]; 932 let _ = tx.try_push(&done); 933} 934 935fn handle_netstat_request(net: &mut stack::NetStack, tx: &PacketRingWriter, conn_id: u8) { 936 let encode_tcp = 937 |socket: &smoltcp::socket::tcp::Socket, msg: &mut [u8; 20], conn: u8| -> usize { 938 msg[0] = conn; 939 msg[1] = MSG_NETSTAT_ENTRY; 940 msg[2] = 6; 941 msg[3] = match socket.state() { 942 smoltcp::socket::tcp::State::Closed => 0, 943 smoltcp::socket::tcp::State::Listen => 1, 944 smoltcp::socket::tcp::State::SynSent => 2, 945 smoltcp::socket::tcp::State::SynReceived => 3, 946 smoltcp::socket::tcp::State::Established => 4, 947 smoltcp::socket::tcp::State::FinWait1 => 5, 948 smoltcp::socket::tcp::State::FinWait2 => 6, 949 smoltcp::socket::tcp::State::CloseWait => 7, 950 smoltcp::socket::tcp::State::Closing => 8, 951 smoltcp::socket::tcp::State::LastAck => 9, 952 smoltcp::socket::tcp::State::TimeWait => 10, 953 }; 954 let (lip, lport) = match socket.local_endpoint() { 955 Some(ep) => { 956 let ip = match ep.addr { 957 IpAddress::Ipv4(a) => a.octets(), 958 _ => [0; 4], 959 }; 960 (ip, ep.port) 961 } 962 None => { 963 let listen = socket.listen_endpoint(); 964 let ip = match listen.addr { 965 Some(IpAddress::Ipv4(a)) => a.octets(), 966 _ => [0; 4], 967 }; 968 (ip, listen.port) 969 } 970 }; 971 msg[4..8].copy_from_slice(&lip); 972 msg[8] = (lport >> 8) as u8; 973 msg[9] = lport as u8; 974 let remote = socket.remote_endpoint(); 975 let rip = match remote { 976 Some(ep) => match ep.addr { 977 IpAddress::Ipv4(a) => a.octets(), 978 _ => [0; 4], 979 }, 980 None => [0; 4], 981 }; 982 let rport = remote.map_or(0u16, |ep| ep.port); 983 msg[10..14].copy_from_slice(&rip); 984 msg[14] = (rport >> 8) as u8; 985 msg[15] = rport as u8; 986 let sq = socket.send_queue() as u16; 987 let rq = socket.recv_queue() as u16; 988 msg[16] = (sq >> 8) as u8; 989 msg[17] = sq as u8; 990 msg[18] = (rq >> 8) as u8; 991 msg[19] = rq as u8; 992 20 993 }; 994 995 let mut msg = [0u8; 20]; 996 997 let echo_sock = net 998 .sockets 999 .get_mut::<smoltcp::socket::tcp::Socket>(net.tcp_handle); 1000 let len = encode_tcp(echo_sock, &mut msg, conn_id); 1001 let _ = tx.try_push(&msg[..len]); 1002 1003 net.shell_handles.iter().for_each(|&h| { 1004 let sock = net.sockets.get_mut::<smoltcp::socket::tcp::Socket>(h); 1005 let len = encode_tcp(sock, &mut msg, conn_id); 1006 let _ = tx.try_push(&msg[..len]); 1007 }); 1008 1009 net.udp_handles.iter().for_each(|&h| { 1010 let sock = net.sockets.get_mut::<udp::Socket>(h); 1011 let port = sock.endpoint().port; 1012 if port != 0 { 1013 let rq = sock.payload_recv_capacity() as u16; 1014 let mut umsg = [0u8; 6]; 1015 umsg[0] = conn_id; 1016 umsg[1] = MSG_NETSTAT_ENTRY_UDP; 1017 umsg[2] = (port >> 8) as u8; 1018 umsg[3] = port as u8; 1019 umsg[4] = (rq >> 8) as u8; 1020 umsg[5] = rq as u8; 1021 let _ = tx.try_push(&umsg); 1022 } 1023 }); 1024 1025 let done = [conn_id, MSG_NETSTAT_DONE]; 1026 let _ = tx.try_push(&done); 1027} 1028 1029fn is_multicast_addr(octet: u8) -> bool { 1030 (224..=239).contains(&octet) 1031} 1032 1033fn handle_mcast_join(net: &mut stack::NetStack, tx: &PacketRingWriter, conn_id: u8, data: &[u8]) { 1034 let status = match data.len() >= 4 && is_multicast_addr(data[0]) { 1035 true => { 1036 let addr = Ipv4Address::new(data[0], data[1], data[2], data[3]); 1037 match net.iface.join_multicast_group(addr) { 1038 Ok(()) => 0u8, 1039 Err(_) => 1u8, 1040 } 1041 } 1042 false => 1u8, 1043 }; 1044 let msg = [conn_id, MSG_MCAST_RESULT, status]; 1045 let _ = tx.try_push(&msg); 1046} 1047 1048fn handle_mcast_leave(net: &mut stack::NetStack, tx: &PacketRingWriter, conn_id: u8, data: &[u8]) { 1049 let status = match data.len() >= 4 && is_multicast_addr(data[0]) { 1050 true => { 1051 let addr = Ipv4Address::new(data[0], data[1], data[2], data[3]); 1052 match net.iface.leave_multicast_group(addr) { 1053 Ok(()) => 0u8, 1054 Err(_) => 1u8, 1055 } 1056 } 1057 false => 1u8, 1058 }; 1059 let msg = [conn_id, MSG_MCAST_RESULT, status]; 1060 let _ = tx.try_push(&msg); 1061} 1062 1063#[derive(Clone, Copy, PartialEq, Eq)] 1064enum MdnsName { 1065 LancerLocal, 1066 LancerTcpLocal, 1067 Unknown, 1068} 1069 1070const MDNS_MULTICAST_DEST: (IpAddress, u16) = 1071 (IpAddress::Ipv4(Ipv4Address::new(224, 0, 0, 251)), 5353); 1072 1073fn poll_mdns(net: &mut stack::NetStack) { 1074 let cfg: &NetConfig = unsafe { NET_CONFIG.as_ref_unchecked() }; 1075 let ip = cfg.ipv4; 1076 if ip == [0, 0, 0, 0] { 1077 return; 1078 } 1079 1080 let mdns_handle = net.mdns_handle; 1081 let socket = net.sockets.get_mut::<udp::Socket>(mdns_handle); 1082 let mut recv_buf = [0u8; 1500]; 1083 let mut resp_buf = [0u8; 1500]; 1084 1085 core::iter::from_fn(|| match socket.can_recv() { 1086 true => match socket.recv_slice(&mut recv_buf) { 1087 Ok((len, endpoint)) if len >= 12 => { 1088 let flags = ((recv_buf[2] as u16) << 8) | recv_buf[3] as u16; 1089 let is_query = flags & 0x8000 == 0; 1090 let qdcount = ((recv_buf[4] as u16) << 8) | recv_buf[5] as u16; 1091 1092 if is_query && qdcount >= 1 { 1093 let mut qpos = 12usize; 1094 let wire = &recv_buf[..len]; 1095 (0..qdcount.min(16)).for_each(|_| { 1096 if qpos >= len { 1097 return; 1098 } 1099 let lancer_local: &[&[u8]] = &[b"lancer", b"local"]; 1100 let svc_local: &[&[u8]] = &[b"_lancer", b"_tcp", b"local"]; 1101 1102 let (name, after_name) = match dns_name_eq(wire, qpos, lancer_local) { 1103 Some(end) => (MdnsName::LancerLocal, end), 1104 None => match dns_name_eq(wire, qpos, svc_local) { 1105 Some(end) => (MdnsName::LancerTcpLocal, end), 1106 None => match dns_skip_name(wire, qpos) { 1107 Some(end) => (MdnsName::Unknown, end), 1108 None => { 1109 qpos = len; 1110 return; 1111 } 1112 }, 1113 }, 1114 }; 1115 1116 match after_name + 4 <= len { 1117 true => { 1118 let qtype = ((recv_buf[after_name] as u16) << 8) 1119 | recv_buf[after_name + 1] as u16; 1120 let qclass = ((recv_buf[after_name + 2] as u16) << 8) 1121 | recv_buf[after_name + 3] as u16; 1122 let qu_bit = qclass & 0x8000 != 0; 1123 qpos = after_name + 4; 1124 1125 let resp_len = match (name, qtype) { 1126 (MdnsName::LancerLocal, DNS_TYPE_A) 1127 | (MdnsName::LancerLocal, 255) => { 1128 build_mdns_a_response(&mut resp_buf, ip).unwrap_or(0) 1129 } 1130 (MdnsName::LancerTcpLocal, DNS_TYPE_PTR) 1131 | (MdnsName::LancerTcpLocal, 255) => { 1132 build_mdns_ptr_response(&mut resp_buf, ip, SHELL_PORT) 1133 .unwrap_or(0) 1134 } 1135 _ => 0, 1136 }; 1137 1138 if resp_len > 0 { 1139 let dest = match qu_bit { 1140 true => (endpoint.endpoint.addr, endpoint.endpoint.port), 1141 false => MDNS_MULTICAST_DEST, 1142 }; 1143 let _ = socket.send_slice(&resp_buf[..resp_len], dest); 1144 } 1145 } 1146 false => { 1147 qpos = len; 1148 } 1149 } 1150 }); 1151 } 1152 Some(()) 1153 } 1154 _ => None, 1155 }, 1156 false => None, 1157 }) 1158 .take(4) 1159 .count(); 1160} 1161 1162#[unsafe(no_mangle)] 1163pub extern "C" fn lancer_main() -> ! { 1164 lancer_user::show!(net, "starting"); 1165 1166 if !(0..PACKET_RING_FRAME_COUNT).all(|i| syscall::frame_map(PACKET_RING_BASE_SLOT + i, RING_BASE_VADDR + i * 4096, 1) >= 0) { 1167 lancer_user::show!(net, error, "packet ring frame_map failed"); 1168 syscall::exit(); 1169 } 1170 1171 let rx_ring_base = RING_BASE_VADDR as *mut u8; 1172 let tx_ring_base = (RING_BASE_VADDR + RING_HALF_SIZE as u64) as *mut u8; 1173 1174 let rx_reader = unsafe { PacketRingReader::attach(rx_ring_base, RING_HALF_SIZE) }; 1175 let tx_writer = unsafe { PacketRingWriter::init(tx_ring_base, RING_HALF_SIZE, 2048) }; 1176 1177 let mut dev = PacketDevice { 1178 rx: rx_reader, 1179 tx: tx_writer, 1180 }; 1181 1182 if !(0..SHELL_RING_FRAME_COUNT).all(|i| syscall::frame_map(SHELL_RING_BASE_SLOT + i, SHELL_RING_BASE + i * 4096, 1) >= 0) { 1183 lancer_user::show!(net, error, "shell ring frame_map failed"); 1184 syscall::exit(); 1185 } 1186 1187 let shell_tx_base = SHELL_RING_BASE as *mut u8; 1188 let shell_rx_base = (SHELL_RING_BASE + SHELL_RING_HALF as u64) as *mut u8; 1189 1190 let shell_tx = unsafe { PacketRingWriter::init(shell_tx_base, SHELL_RING_HALF, 128) }; 1191 let _ = unsafe { PacketRingWriter::init(shell_rx_base, SHELL_RING_HALF, 128) }; 1192 let shell_rx = unsafe { PacketRingReader::attach(shell_rx_base, SHELL_RING_HALF) }; 1193 1194 lancer_user::show!(net, "shell ring mapped"); 1195 1196 let has_init_ring = (0..INIT_RING_FRAME_COUNT).all(|i| syscall::frame_map(INIT_RING_BASE_SLOT + i, INIT_RING_BASE + i * 4096, 1) >= 0); 1197 let (init_tx, init_rx) = match has_init_ring { 1198 true => { 1199 let itx_base = INIT_RING_BASE as *mut u8; 1200 let irx_base = (INIT_RING_BASE + INIT_RING_HALF as u64) as *mut u8; 1201 let itx = unsafe { PacketRingWriter::init(itx_base, INIT_RING_HALF, 128) }; 1202 let _ = unsafe { PacketRingWriter::init(irx_base, INIT_RING_HALF, 128) }; 1203 let irx = unsafe { PacketRingReader::attach(irx_base, INIT_RING_HALF) }; 1204 lancer_user::show!(net, "init ring mapped"); 1205 (Some(itx), Some(irx)) 1206 } 1207 false => { 1208 lancer_user::show!(net, "init ring not available"); 1209 (None, None) 1210 } 1211 }; 1212 1213 let now_ms = match syscall::clock_monotonic_ms() { 1214 ms if ms >= 0 => ms, 1215 _ => 0, 1216 }; 1217 let now = Instant::from_millis(now_ms); 1218 1219 let mut net = stack::create(&mut dev, MAC, now); 1220 1221 if stack::MDNS_JOIN_FAILED.load(core::sync::atomic::Ordering::Relaxed) { 1222 lancer_user::show!(net, warn, "failed to join mdns multicast group"); 1223 } 1224 1225 let cfg = unsafe { NET_CONFIG.as_mut_unchecked() }; 1226 cfg.set_mac(MAC); 1227 cfg.set_ipv6_link_local(stack::eui64_link_local_bytes(&MAC)); 1228 1229 lancer_user::show!(net, "interface up, ipv6 link-local + awaiting dhcpv4"); 1230 1231 send_router_solicitation(&dev.tx, &MAC); 1232 1233 { 1234 let socket = net 1235 .sockets 1236 .get_mut::<smoltcp::socket::tcp::Socket>(net.tcp_handle); 1237 match socket.listen(ECHO_PORT) { 1238 Ok(()) => {} 1239 Err(_) => { 1240 lancer_user::show!(net, warn, "echo listen failed"); 1241 } 1242 } 1243 } 1244 lancer_user::show!(net, "tcp echo listening on :7"); 1245 1246 let shell_handles = net.shell_handles; 1247 { 1248 let socket = net 1249 .sockets 1250 .get_mut::<smoltcp::socket::tcp::Socket>(shell_handles[0]); 1251 match socket.listen(SHELL_PORT) { 1252 Ok(()) => {} 1253 Err(_) => { 1254 lancer_user::show!(net, warn, "shell listen failed"); 1255 } 1256 } 1257 } 1258 lancer_user::show!(net, "tcp shell listening on :22"); 1259 1260 let mut echo_buf = [0u8; 1024]; 1261 let mut shell_ring_buf = [0u8; 128]; 1262 let mut init_ring_buf = [0u8; 128]; 1263 let mut pkt_buf = [0u8; 128]; 1264 let mut shell_connected = [false; MAX_SHELL_SOCKETS]; 1265 let mut dhcp_configured = false; 1266 let init_tx_ref = init_tx.as_ref(); 1267 1268 loop { 1269 let now_ms = syscall::clock_monotonic_ms().max(0); 1270 let now = Instant::from_millis(now_ms); 1271 1272 net.iface.poll(now, &mut dev, &mut net.sockets); 1273 1274 handle_dhcp_event(&mut net, &mut dhcp_configured); 1275 1276 if let Some(slaac) = device::take_slaac_prefix() { 1277 configure_slaac(&mut net, &slaac); 1278 } 1279 1280 poll_mdns(&mut net); 1281 1282 let (dns_shell, dns_init) = poll_pending_dns(&mut net, &shell_tx, init_tx_ref); 1283 1284 ping_send(&mut net, now_ms); 1285 let (pr_shell, pr_init) = ping_recv(&mut net, &shell_tx, init_tx_ref, now_ms); 1286 let (pt_shell, pt_init) = ping_timeout(&shell_tx, init_tx_ref, now_ms); 1287 let (pd_shell, pd_init) = ping_check_done(&shell_tx, init_tx_ref); 1288 let (ur_shell, ur_init) = poll_udp_recv(&mut net, &shell_tx, init_tx_ref); 1289 1290 { 1291 let socket = net 1292 .sockets 1293 .get_mut::<smoltcp::socket::tcp::Socket>(net.tcp_handle); 1294 1295 if socket.may_recv() && socket.may_send() { 1296 match socket.recv_slice(&mut echo_buf) { 1297 Ok(n) if n > 0 => { 1298 let _ = socket.send_slice(&echo_buf[..n]); 1299 } 1300 _ => {} 1301 } 1302 } 1303 1304 let needs_relisten = match socket.state() { 1305 smoltcp::socket::tcp::State::CloseWait => { 1306 socket.close(); 1307 false 1308 } 1309 smoltcp::socket::tcp::State::TimeWait 1310 | smoltcp::socket::tcp::State::LastAck 1311 | smoltcp::socket::tcp::State::Closing 1312 | smoltcp::socket::tcp::State::FinWait1 1313 | smoltcp::socket::tcp::State::FinWait2 1314 | smoltcp::socket::tcp::State::Closed => true, 1315 _ => false, 1316 }; 1317 1318 if needs_relisten { 1319 socket.abort(); 1320 let _ = socket.listen(ECHO_PORT); 1321 } 1322 } 1323 1324 let mut any_shell_notify = dns_shell || pr_shell || pt_shell || pd_shell || ur_shell; 1325 let mut any_init_notify = dns_init || pr_init || pt_init || pd_init || ur_init; 1326 1327 (0..MAX_SHELL_SOCKETS).for_each(|i| { 1328 let socket = net 1329 .sockets 1330 .get_mut::<smoltcp::socket::tcp::Socket>(shell_handles[i]); 1331 1332 let fully_open = socket.may_send() && socket.may_recv(); 1333 1334 if fully_open && !shell_connected[i] { 1335 shell_connected[i] = true; 1336 let ctrl = [i as u8, MSG_CONNECT]; 1337 if shell_tx.try_push(&ctrl) { 1338 any_shell_notify = true; 1339 } 1340 } 1341 1342 if !fully_open && shell_connected[i] { 1343 shell_connected[i] = false; 1344 let ctrl = [i as u8, MSG_DISCONNECT]; 1345 if shell_tx.try_push(&ctrl) { 1346 any_shell_notify = true; 1347 } 1348 } 1349 1350 if socket.state() == smoltcp::socket::tcp::State::CloseWait { 1351 socket.close(); 1352 } 1353 1354 if shell_connected[i] && socket.may_recv() { 1355 let pushed = 1356 core::iter::from_fn(|| match shell_tx.has_space() && socket.may_recv() { 1357 true => match socket.recv_slice(&mut pkt_buf[2..126]) { 1358 Ok(n) if n > 0 => { 1359 pkt_buf[0] = i as u8; 1360 pkt_buf[1] = MSG_DATA; 1361 shell_tx.try_push(&pkt_buf[..2 + n]).then_some(()) 1362 } 1363 _ => None, 1364 }, 1365 false => None, 1366 }) 1367 .take(8) 1368 .count(); 1369 if pushed > 0 { 1370 any_shell_notify = true; 1371 } 1372 } 1373 }); 1374 1375 let any_listening = (0..MAX_SHELL_SOCKETS).any(|i| { 1376 net.sockets 1377 .get_mut::<smoltcp::socket::tcp::Socket>(shell_handles[i]) 1378 .is_listening() 1379 }); 1380 1381 if !any_listening 1382 && let Some(i) = (0..MAX_SHELL_SOCKETS).find(|&i| { 1383 let s = net 1384 .sockets 1385 .get_mut::<smoltcp::socket::tcp::Socket>(shell_handles[i]); 1386 !s.is_open() && !s.is_listening() 1387 }) 1388 { 1389 let s = net 1390 .sockets 1391 .get_mut::<smoltcp::socket::tcp::Socket>(shell_handles[i]); 1392 s.abort(); 1393 s.set_nagle_enabled(false); 1394 s.set_ack_delay(None); 1395 s.set_keep_alive(Some(Duration::from_secs(30))); 1396 let _ = s.listen(SHELL_PORT); 1397 } 1398 1399 core::iter::from_fn(|| match shell_rx.try_pop(&mut shell_ring_buf) { 1400 Some(n) if n >= 2 => { 1401 let conn_id = shell_ring_buf[0] as usize; 1402 let msg_type = shell_ring_buf[1]; 1403 match msg_type { 1404 MSG_DNS_QUERY if n > 2 => { 1405 handle_dns_query( 1406 &mut net, 1407 &shell_tx, 1408 conn_id as u8, 1409 &shell_ring_buf[2..n], 1410 false, 1411 RingSource::Shell, 1412 ); 1413 any_shell_notify = true; 1414 } 1415 MSG_DNS_QUERY6 if n > 2 => { 1416 handle_dns_query( 1417 &mut net, 1418 &shell_tx, 1419 conn_id as u8, 1420 &shell_ring_buf[2..n], 1421 true, 1422 RingSource::Shell, 1423 ); 1424 any_shell_notify = true; 1425 } 1426 MSG_PING_REQUEST if n >= 7 => { 1427 handle_ping_request( 1428 &shell_tx, 1429 conn_id as u8, 1430 &shell_ring_buf[2..n], 1431 now_ms, 1432 RingSource::Shell, 1433 ); 1434 any_shell_notify = true; 1435 } 1436 MSG_PING_REQUEST6 if n >= 19 => { 1437 handle_ping_request6( 1438 &shell_tx, 1439 conn_id as u8, 1440 &shell_ring_buf[2..n], 1441 now_ms, 1442 RingSource::Shell, 1443 ); 1444 any_shell_notify = true; 1445 } 1446 MSG_UDP_BIND if n >= 4 => { 1447 handle_udp_bind( 1448 &mut net, 1449 &shell_tx, 1450 conn_id as u8, 1451 &shell_ring_buf[2..n], 1452 RingSource::Shell, 1453 ); 1454 any_shell_notify = true; 1455 } 1456 MSG_UDP_SEND if n > 8 => { 1457 handle_udp_send( 1458 &mut net, 1459 conn_id as u8, 1460 &shell_ring_buf[2..n], 1461 RingSource::Shell, 1462 ); 1463 } 1464 MSG_UDP_CLOSE => { 1465 handle_udp_close(&mut net, conn_id as u8); 1466 } 1467 MSG_IFCONFIG_REQUEST => { 1468 handle_ifconfig_request(&shell_tx, conn_id as u8); 1469 any_shell_notify = true; 1470 } 1471 MSG_ARP_REQUEST => { 1472 handle_arp_request(&shell_tx, conn_id as u8, now_ms); 1473 any_shell_notify = true; 1474 } 1475 MSG_NETSTAT_REQUEST => { 1476 handle_netstat_request(&mut net, &shell_tx, conn_id as u8); 1477 any_shell_notify = true; 1478 } 1479 MSG_MCAST_JOIN if n >= 6 => { 1480 handle_mcast_join( 1481 &mut net, 1482 &shell_tx, 1483 conn_id as u8, 1484 &shell_ring_buf[2..n], 1485 ); 1486 any_shell_notify = true; 1487 } 1488 MSG_MCAST_LEAVE if n >= 6 => { 1489 handle_mcast_leave( 1490 &mut net, 1491 &shell_tx, 1492 conn_id as u8, 1493 &shell_ring_buf[2..n], 1494 ); 1495 any_shell_notify = true; 1496 } 1497 _ if conn_id < MAX_SHELL_SOCKETS => { 1498 let socket = net 1499 .sockets 1500 .get_mut::<smoltcp::socket::tcp::Socket>(shell_handles[conn_id]); 1501 match msg_type { 1502 MSG_DATA if n > 2 && socket.may_send() => { 1503 let _ = socket.send_slice(&shell_ring_buf[2..n]); 1504 } 1505 MSG_DISCONNECT => { 1506 socket.close(); 1507 shell_connected[conn_id] = false; 1508 handle_udp_close(&mut net, conn_id as u8); 1509 } 1510 _ => {} 1511 } 1512 } 1513 _ => {} 1514 } 1515 Some(()) 1516 } 1517 _ => None, 1518 }) 1519 .take(64) 1520 .count(); 1521 1522 if let Some(irx) = &init_rx 1523 && let Some(itx) = &init_tx 1524 { 1525 core::iter::from_fn(|| match irx.try_pop(&mut init_ring_buf) { 1526 Some(n) if n >= 2 => { 1527 let conn_id = init_ring_buf[0]; 1528 let msg_type = init_ring_buf[1]; 1529 match msg_type { 1530 MSG_DNS_QUERY if n > 2 => { 1531 handle_dns_query( 1532 &mut net, 1533 itx, 1534 conn_id, 1535 &init_ring_buf[2..n], 1536 false, 1537 RingSource::Init, 1538 ); 1539 any_init_notify = true; 1540 } 1541 MSG_DNS_QUERY6 if n > 2 => { 1542 handle_dns_query( 1543 &mut net, 1544 itx, 1545 conn_id, 1546 &init_ring_buf[2..n], 1547 true, 1548 RingSource::Init, 1549 ); 1550 any_init_notify = true; 1551 } 1552 MSG_PING_REQUEST if n >= 7 => { 1553 handle_ping_request( 1554 itx, 1555 conn_id, 1556 &init_ring_buf[2..n], 1557 now_ms, 1558 RingSource::Init, 1559 ); 1560 any_init_notify = true; 1561 } 1562 MSG_PING_REQUEST6 if n >= 19 => { 1563 handle_ping_request6( 1564 itx, 1565 conn_id, 1566 &init_ring_buf[2..n], 1567 now_ms, 1568 RingSource::Init, 1569 ); 1570 any_init_notify = true; 1571 } 1572 MSG_UDP_BIND if n >= 4 => { 1573 handle_udp_bind( 1574 &mut net, 1575 itx, 1576 conn_id, 1577 &init_ring_buf[2..n], 1578 RingSource::Init, 1579 ); 1580 any_init_notify = true; 1581 } 1582 MSG_UDP_SEND if n > 8 => { 1583 handle_udp_send( 1584 &mut net, 1585 conn_id, 1586 &init_ring_buf[2..n], 1587 RingSource::Init, 1588 ); 1589 } 1590 MSG_UDP_CLOSE => { 1591 handle_udp_close(&mut net, conn_id); 1592 } 1593 MSG_IFCONFIG_REQUEST => { 1594 handle_ifconfig_request(itx, conn_id); 1595 any_init_notify = true; 1596 } 1597 MSG_ARP_REQUEST => { 1598 handle_arp_request(itx, conn_id, now_ms); 1599 any_init_notify = true; 1600 } 1601 MSG_NETSTAT_REQUEST => { 1602 handle_netstat_request(&mut net, itx, conn_id); 1603 any_init_notify = true; 1604 } 1605 MSG_MCAST_JOIN if n >= 6 => { 1606 handle_mcast_join(&mut net, itx, conn_id, &init_ring_buf[2..n]); 1607 any_init_notify = true; 1608 } 1609 MSG_MCAST_LEAVE if n >= 6 => { 1610 handle_mcast_leave(&mut net, itx, conn_id, &init_ring_buf[2..n]); 1611 any_init_notify = true; 1612 } 1613 _ => {} 1614 } 1615 Some(()) 1616 } 1617 _ => None, 1618 }) 1619 .take(64) 1620 .count(); 1621 } 1622 1623 if any_shell_notify { 1624 syscall::notify_signal(SHELL_NOTIF_SLOT, NOTIFY_BIT_RX); 1625 } 1626 1627 if any_init_notify { 1628 syscall::notify_signal(INIT_NOTIF_SLOT, NOTIFY_BIT_TX); 1629 } 1630 1631 core::iter::from_fn(|| { 1632 let now = Instant::from_millis(syscall::clock_monotonic_ms()); 1633 matches!( 1634 net.iface.poll(now, &mut dev, &mut net.sockets), 1635 smoltcp::iface::PollResult::SocketStateChanged 1636 ) 1637 .then_some(()) 1638 }) 1639 .take(16) 1640 .count(); 1641 1642 syscall::notify_signal(DRIVER_NOTIF_SLOT, NOTIFY_BIT_TX); 1643 1644 let post_ms = syscall::clock_monotonic_ms().max(0); 1645 let post_now = Instant::from_millis(post_ms); 1646 let delay = net.iface.poll_delay(post_now, &net.sockets); 1647 1648 let ping_active = unsafe { (&raw const PENDING_PING).read().is_some() }; 1649 let max_sleep = match ping_active { 1650 true => 100i64, 1651 false => 200i64, 1652 }; 1653 1654 match delay { 1655 Some(d) if d == Duration::ZERO => { 1656 syscall::sched_yield(); 1657 } 1658 Some(d) => { 1659 let deadline = post_ms + (d.total_millis() as i64).min(max_sleep); 1660 core::iter::from_fn(|| { 1661 syscall::sched_yield(); 1662 let (status, _) = syscall::notify_poll(NOTIF_SLOT); 1663 match status >= 0 { 1664 true => None, 1665 false => (syscall::clock_monotonic_ms() < deadline).then_some(()), 1666 } 1667 }) 1668 .take(100) 1669 .count(); 1670 } 1671 None => { 1672 syscall::notify_wait(NOTIF_SLOT); 1673 } 1674 } 1675 } 1676}