Nothing to see here, move along
at main 226 lines 9.6 kB view raw
1use core::sync::atomic::{AtomicBool, Ordering}; 2use smoltcp::iface::{Config, Interface, SocketHandle, SocketSet, SocketStorage}; 3use smoltcp::socket::{dhcpv4, dns, icmp, tcp, udp}; 4use smoltcp::time::{Duration, Instant}; 5use smoltcp::wire::{ 6 EthernetAddress, HardwareAddress, IpAddress, IpCidr, Ipv4Address, Ipv6Address, Ipv6Cidr, 7}; 8 9use crate::device::PacketDevice; 10 11static CREATED: AtomicBool = AtomicBool::new(false); 12pub static MDNS_JOIN_FAILED: AtomicBool = AtomicBool::new(false); 13 14const TCP_RX_BUF_SIZE: usize = 8192; 15const TCP_TX_BUF_SIZE: usize = 8192; 16const SHELL_TCP_RX_SIZE: usize = 8192; 17const SHELL_TCP_TX_SIZE: usize = 8192; 18pub const MAX_SHELL_SOCKETS: usize = 4; 19pub const MAX_UDP_SOCKETS: usize = 4; 20const DNS_QUERY_SLOTS: usize = 2; 21const MAX_SOCKETS: usize = 2 + MAX_SHELL_SOCKETS + 2 + 1 + MAX_UDP_SOCKETS + 1; 22 23static mut TCP_RX_DATA: [u8; TCP_RX_BUF_SIZE] = [0u8; TCP_RX_BUF_SIZE]; 24static mut TCP_TX_DATA: [u8; TCP_TX_BUF_SIZE] = [0u8; TCP_TX_BUF_SIZE]; 25static mut SHELL_TCP_RX_POOL: [[u8; SHELL_TCP_RX_SIZE]; MAX_SHELL_SOCKETS] = 26 [[0u8; SHELL_TCP_RX_SIZE]; MAX_SHELL_SOCKETS]; 27static mut SHELL_TCP_TX_POOL: [[u8; SHELL_TCP_TX_SIZE]; MAX_SHELL_SOCKETS] = 28 [[0u8; SHELL_TCP_TX_SIZE]; MAX_SHELL_SOCKETS]; 29static mut SOCKET_STORAGE: [SocketStorage<'static>; MAX_SOCKETS] = 30 [SocketStorage::EMPTY; MAX_SOCKETS]; 31static mut DNS_QUERIES: [Option<dns::DnsQuery>; DNS_QUERY_SLOTS] = 32 [const { None }; DNS_QUERY_SLOTS]; 33 34const ICMP_META_SLOTS: usize = 4; 35const ICMP_PAYLOAD_SIZE: usize = 512; 36static mut ICMP_RX_META: [icmp::PacketMetadata; ICMP_META_SLOTS] = 37 [icmp::PacketMetadata::EMPTY; ICMP_META_SLOTS]; 38static mut ICMP_RX_DATA: [u8; ICMP_PAYLOAD_SIZE] = [0u8; ICMP_PAYLOAD_SIZE]; 39static mut ICMP_TX_META: [icmp::PacketMetadata; ICMP_META_SLOTS] = 40 [icmp::PacketMetadata::EMPTY; ICMP_META_SLOTS]; 41static mut ICMP_TX_DATA: [u8; ICMP_PAYLOAD_SIZE] = [0u8; ICMP_PAYLOAD_SIZE]; 42 43const UDP_BUF_SIZE: usize = 2048; 44const UDP_META_SLOTS: usize = 4; 45static mut UDP_RX_META_POOL: [[udp::PacketMetadata; UDP_META_SLOTS]; MAX_UDP_SOCKETS] = 46 [[udp::PacketMetadata::EMPTY; UDP_META_SLOTS]; MAX_UDP_SOCKETS]; 47static mut UDP_RX_DATA_POOL: [[u8; UDP_BUF_SIZE]; MAX_UDP_SOCKETS] = 48 [[0u8; UDP_BUF_SIZE]; MAX_UDP_SOCKETS]; 49static mut UDP_TX_META_POOL: [[udp::PacketMetadata; UDP_META_SLOTS]; MAX_UDP_SOCKETS] = 50 [[udp::PacketMetadata::EMPTY; UDP_META_SLOTS]; MAX_UDP_SOCKETS]; 51static mut UDP_TX_DATA_POOL: [[u8; UDP_BUF_SIZE]; MAX_UDP_SOCKETS] = 52 [[0u8; UDP_BUF_SIZE]; MAX_UDP_SOCKETS]; 53 54const MDNS_META_SLOTS: usize = 4; 55const MDNS_BUF_SIZE: usize = 1500; 56static mut MDNS_RX_META: [udp::PacketMetadata; MDNS_META_SLOTS] = 57 [udp::PacketMetadata::EMPTY; MDNS_META_SLOTS]; 58static mut MDNS_RX_DATA: [u8; MDNS_BUF_SIZE] = [0u8; MDNS_BUF_SIZE]; 59static mut MDNS_TX_META: [udp::PacketMetadata; MDNS_META_SLOTS] = 60 [udp::PacketMetadata::EMPTY; MDNS_META_SLOTS]; 61static mut MDNS_TX_DATA: [u8; MDNS_BUF_SIZE] = [0u8; MDNS_BUF_SIZE]; 62 63pub struct NetStack { 64 pub iface: Interface, 65 pub sockets: SocketSet<'static>, 66 pub tcp_handle: SocketHandle, 67 pub shell_handles: [SocketHandle; MAX_SHELL_SOCKETS], 68 pub dhcp_handle: SocketHandle, 69 pub dns_handle: SocketHandle, 70 pub icmp_handle: SocketHandle, 71 pub udp_handles: [SocketHandle; MAX_UDP_SOCKETS], 72 pub mdns_handle: SocketHandle, 73} 74 75#[allow(clippy::deref_addrof)] 76pub fn create(device: &mut PacketDevice, mac: [u8; 6], now: Instant) -> NetStack { 77 assert!( 78 !CREATED.swap(true, Ordering::Relaxed), 79 "stack::create() called twice" 80 ); 81 let hw_addr = HardwareAddress::Ethernet(EthernetAddress(mac)); 82 let config = Config::new(hw_addr); 83 let mut iface = Interface::new(config, device, now); 84 85 let socket_storage: &'static mut [SocketStorage<'static>; MAX_SOCKETS] = 86 unsafe { &mut *(&raw mut SOCKET_STORAGE) }; 87 let mut sockets = SocketSet::new(&mut socket_storage[..]); 88 89 let tcp_rx_data: &'static mut [u8] = unsafe { &mut *(&raw mut TCP_RX_DATA) }; 90 let tcp_rx_buf = tcp::SocketBuffer::new(tcp_rx_data); 91 let tcp_tx_data: &'static mut [u8] = unsafe { &mut *(&raw mut TCP_TX_DATA) }; 92 let tcp_tx_buf = tcp::SocketBuffer::new(tcp_tx_data); 93 let tcp_socket = tcp::Socket::new(tcp_rx_buf, tcp_tx_buf); 94 let tcp_handle = sockets.add(tcp_socket); 95 96 let rx_pool: &'static mut [[u8; SHELL_TCP_RX_SIZE]; MAX_SHELL_SOCKETS] = 97 unsafe { &mut *(&raw mut SHELL_TCP_RX_POOL) }; 98 let tx_pool: &'static mut [[u8; SHELL_TCP_TX_SIZE]; MAX_SHELL_SOCKETS] = 99 unsafe { &mut *(&raw mut SHELL_TCP_TX_POOL) }; 100 101 let mut shell_handles_tmp: [Option<SocketHandle>; MAX_SHELL_SOCKETS] = 102 [None; MAX_SHELL_SOCKETS]; 103 rx_pool 104 .iter_mut() 105 .zip(tx_pool.iter_mut()) 106 .zip(shell_handles_tmp.iter_mut()) 107 .for_each(|((rx_data, tx_data), slot)| { 108 let mut sock = tcp::Socket::new( 109 tcp::SocketBuffer::new(&mut rx_data[..]), 110 tcp::SocketBuffer::new(&mut tx_data[..]), 111 ); 112 sock.set_nagle_enabled(false); 113 sock.set_ack_delay(None); 114 sock.set_keep_alive(Some(Duration::from_secs(30))); 115 *slot = Some(sockets.add(sock)); 116 }); 117 118 let shell_handles = shell_handles_tmp.map(|opt| opt.unwrap()); 119 120 let dhcp_socket = dhcpv4::Socket::new(); 121 let dhcp_handle = sockets.add(dhcp_socket); 122 123 let dns_queries: &'static mut [Option<dns::DnsQuery>; DNS_QUERY_SLOTS] = 124 unsafe { &mut *(&raw mut DNS_QUERIES) }; 125 let dns_socket = dns::Socket::new(&[] as &[IpAddress], &mut dns_queries[..]); 126 let dns_handle = sockets.add(dns_socket); 127 128 let icmp_rx_meta: &'static mut [icmp::PacketMetadata; ICMP_META_SLOTS] = 129 unsafe { &mut *(&raw mut ICMP_RX_META) }; 130 let icmp_rx_data: &'static mut [u8; ICMP_PAYLOAD_SIZE] = 131 unsafe { &mut *(&raw mut ICMP_RX_DATA) }; 132 let icmp_tx_meta: &'static mut [icmp::PacketMetadata; ICMP_META_SLOTS] = 133 unsafe { &mut *(&raw mut ICMP_TX_META) }; 134 let icmp_tx_data: &'static mut [u8; ICMP_PAYLOAD_SIZE] = 135 unsafe { &mut *(&raw mut ICMP_TX_DATA) }; 136 let icmp_rx_buf = icmp::PacketBuffer::new(&mut icmp_rx_meta[..], &mut icmp_rx_data[..]); 137 let icmp_tx_buf = icmp::PacketBuffer::new(&mut icmp_tx_meta[..], &mut icmp_tx_data[..]); 138 let mut icmp_socket = icmp::Socket::new(icmp_rx_buf, icmp_tx_buf); 139 icmp_socket.bind(icmp::Endpoint::Ident(0x4C41)).unwrap(); 140 let icmp_handle = sockets.add(icmp_socket); 141 142 let udp_rx_meta_pool: &'static mut [[udp::PacketMetadata; UDP_META_SLOTS]; MAX_UDP_SOCKETS] = 143 unsafe { &mut *(&raw mut UDP_RX_META_POOL) }; 144 let udp_rx_data_pool: &'static mut [[u8; UDP_BUF_SIZE]; MAX_UDP_SOCKETS] = 145 unsafe { &mut *(&raw mut UDP_RX_DATA_POOL) }; 146 let udp_tx_meta_pool: &'static mut [[udp::PacketMetadata; UDP_META_SLOTS]; MAX_UDP_SOCKETS] = 147 unsafe { &mut *(&raw mut UDP_TX_META_POOL) }; 148 let udp_tx_data_pool: &'static mut [[u8; UDP_BUF_SIZE]; MAX_UDP_SOCKETS] = 149 unsafe { &mut *(&raw mut UDP_TX_DATA_POOL) }; 150 151 let mut udp_handles_tmp: [Option<SocketHandle>; MAX_UDP_SOCKETS] = [None; MAX_UDP_SOCKETS]; 152 udp_rx_meta_pool 153 .iter_mut() 154 .zip(udp_rx_data_pool.iter_mut()) 155 .zip(udp_tx_meta_pool.iter_mut()) 156 .zip(udp_tx_data_pool.iter_mut()) 157 .zip(udp_handles_tmp.iter_mut()) 158 .for_each(|((((rx_meta, rx_data), tx_meta), tx_data), slot)| { 159 let sock = udp::Socket::new( 160 udp::PacketBuffer::new(&mut rx_meta[..], &mut rx_data[..]), 161 udp::PacketBuffer::new(&mut tx_meta[..], &mut tx_data[..]), 162 ); 163 *slot = Some(sockets.add(sock)); 164 }); 165 166 let udp_handles = udp_handles_tmp.map(|opt| opt.unwrap()); 167 168 let mdns_rx_meta: &'static mut [udp::PacketMetadata; MDNS_META_SLOTS] = 169 unsafe { &mut *(&raw mut MDNS_RX_META) }; 170 let mdns_rx_data: &'static mut [u8; MDNS_BUF_SIZE] = unsafe { &mut *(&raw mut MDNS_RX_DATA) }; 171 let mdns_tx_meta: &'static mut [udp::PacketMetadata; MDNS_META_SLOTS] = 172 unsafe { &mut *(&raw mut MDNS_TX_META) }; 173 let mdns_tx_data: &'static mut [u8; MDNS_BUF_SIZE] = unsafe { &mut *(&raw mut MDNS_TX_DATA) }; 174 let mdns_rx_buf = udp::PacketBuffer::new(&mut mdns_rx_meta[..], &mut mdns_rx_data[..]); 175 let mdns_tx_buf = udp::PacketBuffer::new(&mut mdns_tx_meta[..], &mut mdns_tx_data[..]); 176 let mut mdns_socket = udp::Socket::new(mdns_rx_buf, mdns_tx_buf); 177 mdns_socket 178 .bind(smoltcp::wire::IpListenEndpoint { 179 addr: None, 180 port: 5353, 181 }) 182 .unwrap(); 183 let mdns_handle = sockets.add(mdns_socket); 184 185 let link_local = eui64_link_local(&mac); 186 iface.update_ip_addrs(|addrs| { 187 let _ = addrs.push(IpCidr::Ipv6(Ipv6Cidr::new(link_local, 64))); 188 }); 189 190 if iface 191 .join_multicast_group(Ipv4Address::new(224, 0, 0, 251)) 192 .is_err() 193 { 194 MDNS_JOIN_FAILED.store(true, Ordering::Relaxed); 195 } 196 197 NetStack { 198 iface, 199 sockets, 200 tcp_handle, 201 shell_handles, 202 dhcp_handle, 203 dns_handle, 204 icmp_handle, 205 udp_handles, 206 mdns_handle, 207 } 208} 209 210pub fn eui64_link_local_bytes(mac: &[u8; 6]) -> [u8; 16] { 211 let addr = eui64_link_local(mac); 212 addr.octets() 213} 214 215fn eui64_link_local(mac: &[u8; 6]) -> Ipv6Address { 216 Ipv6Address::new( 217 0xfe80, 218 0, 219 0, 220 0, 221 ((mac[0] ^ 0x02) as u16) << 8 | mac[1] as u16, 222 (mac[2] as u16) << 8 | 0x00ff, 223 0xfe00 | mac[3] as u16, 224 (mac[4] as u16) << 8 | mac[5] as u16, 225 ) 226}