Skip to main content

edge_nal_std/
lib.rs

1#![allow(async_fn_in_trait)]
2#![warn(clippy::large_futures)]
3#![allow(clippy::uninlined_format_args)]
4#![allow(unknown_lints)]
5
6use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
7use core::ops::Deref;
8use core::pin::pin;
9
10use std::io;
11use std::net::{self, Shutdown, TcpStream, ToSocketAddrs, UdpSocket as StdUdpSocket};
12
13#[cfg(not(feature = "async-io-mini"))]
14use async_io::Async;
15#[cfg(feature = "async-io-mini")]
16use async_io_mini::Async;
17
18use futures_lite::io::{AsyncReadExt, AsyncWriteExt};
19
20use embedded_io_async::{ErrorType, Read, Write};
21
22use edge_nal::{
23    AddrType, Dns, MulticastV4, MulticastV6, Readable, TcpAccept, TcpBind, TcpConnect, TcpShutdown,
24    TcpSplit, UdpBind, UdpConnect, UdpReceive, UdpSend, UdpSplit,
25};
26
27#[cfg(any(target_os = "linux", target_os = "android"))]
28pub use raw::*;
29
30/// The STD network stack implementation.
31///
32/// This uses the standard library's networking types under the hood,
33/// wrapped in async-io's `Async` type for async support.
34///
35/// The type is `Copy` and `Clone`, so it can be easily passed around.
36#[derive(Default, Copy, Clone)]
37pub struct Stack(());
38
39impl Stack {
40    /// Create a new STD network stack instance.
41    pub const fn new() -> Self {
42        Self(())
43    }
44}
45
46impl TcpConnect for Stack {
47    type Error = io::Error;
48
49    type Socket<'a>
50        = TcpSocket
51    where
52        Self: 'a;
53
54    async fn connect(&self, remote: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
55        let socket = Async::<TcpStream>::connect(remote).await?;
56
57        Ok(TcpSocket(socket))
58    }
59}
60
61impl TcpBind for Stack {
62    type Error = io::Error;
63
64    type Accept<'a>
65        = TcpAcceptor
66    where
67        Self: 'a;
68
69    async fn bind(&self, local: SocketAddr) -> Result<Self::Accept<'_>, Self::Error> {
70        let acceptor = Async::<net::TcpListener>::bind(local).map(TcpAcceptor)?;
71
72        Ok(acceptor)
73    }
74}
75
76/// The TCP acceptor type for the STD network stack.
77pub struct TcpAcceptor(Async<net::TcpListener>);
78
79impl TcpAccept for TcpAcceptor {
80    type Error = io::Error;
81
82    type Socket<'a>
83        = TcpSocket
84    where
85        Self: 'a;
86
87    #[cfg(not(target_os = "espidf"))]
88    async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
89        let socket = self.0.accept().await.map(|(socket, _)| socket)?;
90
91        Ok((socket.as_ref().peer_addr()?, TcpSocket(socket)))
92    }
93
94    #[cfg(target_os = "espidf")]
95    async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
96        // ESP IDF (lwIP actually) does not really support `select`-ing on
97        // socket accept: https://groups.google.com/g/osdeve_mirror_tcpip_lwip/c/Vsz7SVa6a2M
98        //
99        // If we do this, `select` would block and not return with our accepting socket `fd`
100        // marked as ready even if our accepting socket has a pending connection.
101        //
102        // (Note also that since the time when the above link was posted on the internet,
103        // the lwIP `accept` API has improved a bit in that it would now return `EWOULDBLOCK`
104        // instead of blocking indefinitely
105        // - and we take advantage of that in the "async" implementation below.)
106        //
107        // The workaround below is not ideal in that
108        // it uses a timer to poll the socket, but it avoids spinning a hidden,
109        // separate thread just to accept connections - which would be the alternative.
110        loop {
111            match self.0.as_ref().accept() {
112                Ok((socket, _)) => break Ok((socket.peer_addr()?, TcpSocket(Async::new(socket)?))),
113                Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
114                    #[cfg(not(feature = "async-io-mini"))]
115                    use async_io::Timer;
116                    #[cfg(feature = "async-io-mini")]
117                    use async_io_mini::Timer;
118
119                    Timer::after(core::time::Duration::from_millis(20)).await;
120                }
121                Err(err) => break Err(err),
122            }
123        }
124    }
125}
126
127/// The TCP socket type for the STD network stack.
128pub struct TcpSocket(Async<TcpStream>);
129
130impl TcpSocket {
131    /// Create a new TCP socket from the given async TCP stream.
132    ///
133    /// # Arguments
134    /// - `socket`: The async TCP stream to wrap.
135    pub const fn new(socket: Async<TcpStream>) -> Self {
136        Self(socket)
137    }
138
139    /// Release the underlying async TCP stream.
140    pub fn release(self) -> Async<TcpStream> {
141        self.0
142    }
143}
144
145impl Deref for TcpSocket {
146    type Target = Async<TcpStream>;
147
148    fn deref(&self) -> &Self::Target {
149        &self.0
150    }
151}
152
153impl ErrorType for TcpSocket {
154    type Error = io::Error;
155}
156
157impl Read for TcpSocket {
158    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
159        self.0.read(buf).await
160    }
161}
162
163impl Write for TcpSocket {
164    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
165        self.0.write(buf).await
166    }
167
168    async fn flush(&mut self) -> Result<(), Self::Error> {
169        self.0.flush().await
170    }
171}
172
173impl Readable for TcpSocket {
174    async fn readable(&mut self) -> Result<(), Self::Error> {
175        self.0.readable().await
176    }
177}
178
179impl ErrorType for &TcpSocket {
180    type Error = io::Error;
181}
182
183impl Read for &TcpSocket {
184    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
185        (&self.0).read(buf).await
186    }
187}
188
189impl Write for &TcpSocket {
190    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
191        (&self.0).write(buf).await
192    }
193
194    async fn flush(&mut self) -> Result<(), Self::Error> {
195        (&self.0).flush().await
196    }
197}
198
199impl Readable for &TcpSocket {
200    async fn readable(&mut self) -> Result<(), Self::Error> {
201        self.0.readable().await
202    }
203}
204
205impl TcpSplit for TcpSocket {
206    type Read<'a>
207        = &'a TcpSocket
208    where
209        Self: 'a;
210
211    type Write<'a>
212        = &'a TcpSocket
213    where
214        Self: 'a;
215
216    fn split(&mut self) -> (Self::Read<'_>, Self::Write<'_>) {
217        let socket = &*self;
218
219        (socket, socket)
220    }
221}
222
223impl TcpShutdown for TcpSocket {
224    async fn close(&mut self, what: edge_nal::Close) -> Result<(), Self::Error> {
225        match what {
226            edge_nal::Close::Read => self.0.as_ref().shutdown(Shutdown::Read)?,
227            edge_nal::Close::Write => self.0.as_ref().shutdown(Shutdown::Write)?,
228            edge_nal::Close::Both => self.0.as_ref().shutdown(Shutdown::Both)?,
229        }
230
231        Ok(())
232    }
233
234    async fn abort(&mut self) -> Result<(), Self::Error> {
235        // No-op, STD will abort the socket on drop anyway
236
237        Ok(())
238    }
239}
240
241impl UdpConnect for Stack {
242    type Error = io::Error;
243
244    type Socket<'a>
245        = UdpSocket
246    where
247        Self: 'a;
248
249    async fn connect(
250        &self,
251        local: SocketAddr,
252        remote: SocketAddr,
253    ) -> Result<Self::Socket<'_>, Self::Error> {
254        let socket = Async::<StdUdpSocket>::bind(local)?;
255
256        socket.as_ref().connect(remote)?;
257
258        Ok(UdpSocket(socket))
259    }
260}
261
262impl UdpBind for Stack {
263    type Error = io::Error;
264
265    type Socket<'a>
266        = UdpSocket
267    where
268        Self: 'a;
269
270    async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
271        let socket = Async::<StdUdpSocket>::bind(local)?;
272
273        socket.as_ref().set_broadcast(true)?;
274
275        Ok(UdpSocket(socket))
276    }
277}
278
279/// The UDP socket type for the STD network stack.
280pub struct UdpSocket(Async<StdUdpSocket>);
281
282impl UdpSocket {
283    /// Create a new UDP socket from the given async UDP socket.
284    ///
285    /// # Arguments
286    /// - `socket`: The async UDP socket to wrap.
287    pub const fn new(socket: Async<StdUdpSocket>) -> Self {
288        Self(socket)
289    }
290
291    /// Release the underlying async UDP socket.
292    pub fn release(self) -> Async<StdUdpSocket> {
293        self.0
294    }
295
296    /// Join a multicast group for IPv4.
297    ///
298    /// # Arguments
299    /// - `multiaddr`: The multicast address to join.
300    /// - `interface`: The interface address to use.
301    pub fn join_multicast_v4(
302        &self,
303        multiaddr: &Ipv4Addr,
304        interface: &Ipv4Addr,
305    ) -> Result<(), io::Error> {
306        #[cfg(not(target_os = "espidf"))]
307        self.as_ref().join_multicast_v4(multiaddr, interface)?;
308
309        #[cfg(target_os = "espidf")]
310        self.setsockopt_ipproto_ip(
311            multiaddr, interface, 3, /* IP_ADD_MEMBERSHIP in ESP IDF*/
312        )?;
313
314        Ok(())
315    }
316
317    /// Leave a multicast group for IPv4.
318    ///
319    /// # Arguments
320    /// - `multiaddr`: The multicast address to leave.
321    /// - `interface`: The interface address to use.
322    pub fn leave_multicast_v4(
323        &self,
324        multiaddr: &Ipv4Addr,
325        interface: &Ipv4Addr,
326    ) -> Result<(), io::Error> {
327        #[cfg(not(target_os = "espidf"))]
328        self.as_ref().leave_multicast_v4(multiaddr, interface)?;
329
330        #[cfg(target_os = "espidf")]
331        self.setsockopt_ipproto_ip(
332            multiaddr, interface, 4, /* IP_LEAVE_MEMBERSHIP in ESP IDF*/
333        )?;
334
335        Ok(())
336    }
337
338    #[cfg(target_os = "espidf")]
339    pub fn setsockopt_ipproto_ip(
340        &self,
341        multiaddr: &Ipv4Addr,
342        interface: &Ipv4Addr,
343        option: u32,
344    ) -> Result<(), io::Error> {
345        // join_multicast_v4() is broken for ESP-IDF due to IP_ADD_MEMBERSHIP being wrongly defined to 11,
346        // while it should be 3: https://github.com/rust-lang/libc/blob/main/src/unix/newlib/mod.rs#L568
347        //
348        // leave_multicast_v4() is broken for ESP-IDF due to IP_ADD_MEMBERSHIP being wrongly defined to 12,
349        // while it should be 4: https://github.com/rust-lang/libc/blob/main/src/unix/newlib/mod.rs#L569
350
351        let mreq = sys::ip_mreq {
352            imr_multiaddr: sys::in_addr {
353                s_addr: u32::from_ne_bytes(multiaddr.octets()),
354            },
355            imr_interface: sys::in_addr {
356                s_addr: u32::from_ne_bytes(interface.octets()),
357            },
358        };
359
360        use std::os::fd::AsRawFd;
361
362        syscall_los!(unsafe {
363            sys::setsockopt(
364                self.0.as_raw_fd(),
365                sys::IPPROTO_IP as _,
366                option as _,
367                &mreq as *const _ as *const _,
368                core::mem::size_of::<sys::ip_mreq>() as _,
369            )
370        })?;
371
372        Ok(())
373    }
374}
375
376impl Deref for UdpSocket {
377    type Target = Async<StdUdpSocket>;
378
379    fn deref(&self) -> &Self::Target {
380        &self.0
381    }
382}
383
384impl ErrorType for &UdpSocket {
385    type Error = io::Error;
386}
387
388impl UdpReceive for &UdpSocket {
389    async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
390        let remote = self.0.as_ref().peer_addr();
391
392        let (len, remote) = if let Ok(remote) = remote {
393            // Connected socket
394            let fut = pin!(self.0.recv(buffer));
395            let len = fut.await?;
396
397            (len, remote)
398        } else {
399            // Unconnected socket
400            let fut = pin!(self.0.recv_from(buffer));
401            let (len, remote) = fut.await?;
402
403            (len, remote)
404        };
405
406        Ok((len, remote))
407    }
408}
409
410impl UdpSend for &UdpSocket {
411    async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
412        let is_remote = self.0.as_ref().peer_addr().is_ok();
413
414        if is_remote {
415            // Connected socket
416            let mut offset = 0;
417
418            loop {
419                let fut = pin!(self.0.send(&data[offset..]));
420                offset += fut.await?;
421
422                if offset == data.len() {
423                    break;
424                }
425            }
426        } else {
427            // Unconnected socket
428            let mut offset = 0;
429
430            loop {
431                let fut = pin!(self.0.send_to(&data[offset..], remote));
432                offset += fut.await?;
433
434                if offset == data.len() {
435                    break;
436                }
437            }
438        }
439
440        Ok(())
441    }
442}
443
444impl MulticastV4 for &UdpSocket {
445    async fn join_v4(
446        &mut self,
447        multicast_addr: Ipv4Addr,
448        interface: Ipv4Addr,
449    ) -> Result<(), Self::Error> {
450        self.join_multicast_v4(&multicast_addr, &interface)
451    }
452
453    async fn leave_v4(
454        &mut self,
455        multicast_addr: Ipv4Addr,
456        interface: Ipv4Addr,
457    ) -> Result<(), Self::Error> {
458        self.leave_multicast_v4(&multicast_addr, &interface)
459    }
460}
461
462impl MulticastV6 for &UdpSocket {
463    async fn join_v6(
464        &mut self,
465        multicast_addr: Ipv6Addr,
466        interface: u32,
467    ) -> Result<(), Self::Error> {
468        self.0
469            .as_ref()
470            .join_multicast_v6(&multicast_addr, interface)
471    }
472
473    async fn leave_v6(
474        &mut self,
475        multicast_addr: Ipv6Addr,
476        interface: u32,
477    ) -> Result<(), Self::Error> {
478        self.0
479            .as_ref()
480            .leave_multicast_v6(&multicast_addr, interface)
481    }
482}
483
484impl Readable for &UdpSocket {
485    async fn readable(&mut self) -> Result<(), Self::Error> {
486        self.0.readable().await
487    }
488}
489
490impl ErrorType for UdpSocket {
491    type Error = io::Error;
492}
493
494impl UdpReceive for UdpSocket {
495    async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
496        let mut rself = &*self;
497
498        let fut = pin!(rself.receive(buffer));
499        fut.await
500    }
501}
502
503impl UdpSend for UdpSocket {
504    async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
505        let mut rself = &*self;
506
507        let fut = pin!(rself.send(remote, data));
508        fut.await
509    }
510}
511
512impl MulticastV4 for UdpSocket {
513    async fn join_v4(
514        &mut self,
515        multicast_addr: Ipv4Addr,
516        interface: Ipv4Addr,
517    ) -> Result<(), Self::Error> {
518        self.join_multicast_v4(&multicast_addr, &interface)
519    }
520
521    async fn leave_v4(
522        &mut self,
523        multicast_addr: Ipv4Addr,
524        interface: Ipv4Addr,
525    ) -> Result<(), Self::Error> {
526        self.leave_multicast_v4(&multicast_addr, &interface)
527    }
528}
529
530impl MulticastV6 for UdpSocket {
531    async fn join_v6(
532        &mut self,
533        multicast_addr: Ipv6Addr,
534        interface: u32,
535    ) -> Result<(), Self::Error> {
536        self.0
537            .as_ref()
538            .join_multicast_v6(&multicast_addr, interface)
539    }
540
541    async fn leave_v6(
542        &mut self,
543        multicast_addr: Ipv6Addr,
544        interface: u32,
545    ) -> Result<(), Self::Error> {
546        self.0
547            .as_ref()
548            .leave_multicast_v6(&multicast_addr, interface)
549    }
550}
551
552impl Readable for UdpSocket {
553    async fn readable(&mut self) -> Result<(), Self::Error> {
554        let mut rself = &*self;
555
556        let fut = pin!(rself.readable());
557        fut.await
558    }
559}
560
561impl UdpSplit for UdpSocket {
562    type Receive<'a>
563        = &'a Self
564    where
565        Self: 'a;
566
567    type Send<'a>
568        = &'a Self
569    where
570        Self: 'a;
571
572    fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
573        let socket = &*self;
574
575        (socket, socket)
576    }
577}
578
579impl Dns for Stack {
580    type Error = io::Error;
581
582    async fn get_host_by_name(
583        &self,
584        host: &str,
585        addr_type: AddrType,
586    ) -> Result<IpAddr, Self::Error> {
587        let host = host.to_string();
588
589        dns_lookup_host(&host, addr_type)
590    }
591
592    async fn get_host_by_address(
593        &self,
594        _addr: IpAddr,
595        _result: &mut [u8],
596    ) -> Result<usize, Self::Error> {
597        Err(io::ErrorKind::Unsupported.into())
598    }
599}
600
601/// Perform a DNS lookup for the given host and address type.
602fn dns_lookup_host(host: &str, addr_type: AddrType) -> Result<IpAddr, io::Error> {
603    (host, 0_u16)
604        .to_socket_addrs()?
605        .find(|addr| match addr_type {
606            AddrType::IPv4 => matches!(addr, std::net::SocketAddr::V4(_)),
607            AddrType::IPv6 => matches!(addr, std::net::SocketAddr::V6(_)),
608            AddrType::Either => true,
609        })
610        .map(|addr| match addr {
611            std::net::SocketAddr::V4(v4) => v4.ip().octets().into(),
612            std::net::SocketAddr::V6(v6) => v6.ip().octets().into(),
613        })
614        .ok_or_else(|| io::ErrorKind::AddrNotAvailable.into())
615}
616
617// TODO: Figure out if the RAW socket implementation can be used on any other OS.
618// It seems, that would be difficult on Darwin; wondering about the other BSDs though?
619#[cfg(any(target_os = "linux", target_os = "android"))]
620mod raw {
621    use core::ops::Deref;
622    use core::pin::pin;
623
624    use std::io::{self, ErrorKind};
625    use std::os::fd::{AsFd, AsRawFd};
626
627    #[cfg(not(feature = "async-io-mini"))]
628    use async_io::Async;
629    #[cfg(feature = "async-io-mini")]
630    use async_io_mini::Async;
631
632    use edge_nal::{MacAddr, RawBind, RawReceive, RawSend, RawSplit, Readable};
633    use embedded_io_async::ErrorType;
634
635    use crate::sys;
636    use crate::syscall_los;
637
638    /// The RAW interface binding type for Linux.
639    #[derive(Default, Copy, Clone)]
640    pub struct Interface(u32);
641
642    impl Interface {
643        /// Create a new RAW interface binding for the given interface index.
644        pub const fn new(interface: u32) -> Self {
645            Self(interface)
646        }
647    }
648
649    impl RawBind for Interface {
650        type Error = io::Error;
651
652        type Socket<'a>
653            = RawSocket
654        where
655            Self: 'a;
656
657        async fn bind(&self) -> Result<Self::Socket<'_>, Self::Error> {
658            let socket = syscall_los!(unsafe {
659                sys::socket(
660                    sys::PF_PACKET,
661                    sys::SOCK_DGRAM,
662                    (sys::ETH_P_IP as u16).to_be() as _,
663                )
664            })?;
665
666            let sockaddr = sys::sockaddr_ll {
667                sll_family: sys::AF_PACKET as _,
668                sll_protocol: (sys::ETH_P_IP as u16).to_be() as _,
669                sll_ifindex: self.0 as _,
670                sll_hatype: 0,
671                sll_pkttype: 0,
672                sll_halen: 0,
673                sll_addr: Default::default(),
674            };
675
676            syscall_los!(unsafe {
677                sys::bind(
678                    socket,
679                    &sockaddr as *const _ as *const _,
680                    core::mem::size_of::<sys::sockaddr_ll>() as _,
681                )
682            })?;
683
684            // TODO
685            // syscall_los!(unsafe {
686            //     sys::setsockopt(socket, sys::SOL_PACKET, sys::PACKET_AUXDATA, &1_u32 as *const _ as *const _, 4)
687            // })?;
688
689            let socket = {
690                use std::os::fd::FromRawFd;
691
692                unsafe { std::net::UdpSocket::from_raw_fd(socket) }
693            };
694
695            socket.set_broadcast(true)?;
696
697            Ok(RawSocket(Async::new(socket)?, self.0 as _))
698        }
699    }
700
701    /// The RAW socket type for Linux.
702    pub struct RawSocket(Async<std::net::UdpSocket>, u32);
703
704    impl RawSocket {
705        /// Create a new RAW socket from the given async UDP socket and interface index.
706        ///
707        /// # Arguments
708        /// - `socket`: The async UDP socket to wrap.
709        /// - `interface`: The interface index.
710        pub const fn new(socket: Async<std::net::UdpSocket>, interface: u32) -> Self {
711            Self(socket, interface)
712        }
713
714        /// Release the underlying async UDP socket and interface index.
715        pub fn release(self) -> (Async<std::net::UdpSocket>, u32) {
716            (self.0, self.1)
717        }
718    }
719
720    impl Deref for RawSocket {
721        type Target = Async<std::net::UdpSocket>;
722
723        fn deref(&self) -> &Self::Target {
724            &self.0
725        }
726    }
727
728    impl ErrorType for &RawSocket {
729        type Error = io::Error;
730    }
731
732    impl RawReceive for &RawSocket {
733        async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, MacAddr), Self::Error> {
734            let fut = pin!(self.0.read_with(|io| {
735                let mut storage: sys::sockaddr_storage = unsafe { core::mem::zeroed() };
736                let mut addrlen = core::mem::size_of_val(&storage) as sys::socklen_t;
737
738                let ret = syscall_los!(unsafe {
739                    sys::recvfrom(
740                        io.as_fd().as_raw_fd(),
741                        buffer.as_mut_ptr() as *mut _,
742                        buffer.len(),
743                        0,
744                        &mut storage as *mut _ as *mut _,
745                        &mut addrlen,
746                    )
747                })?;
748
749                let sockaddr = as_sockaddr_ll(&storage, addrlen as usize)?;
750
751                let mut mac = [0; 6];
752                mac.copy_from_slice(&sockaddr.sll_addr[..6]);
753
754                Ok((ret as usize, mac))
755            }));
756
757            fut.await
758        }
759    }
760
761    impl RawSend for &RawSocket {
762        async fn send(&mut self, mac: MacAddr, data: &[u8]) -> Result<(), Self::Error> {
763            let mut sockaddr = sys::sockaddr_ll {
764                sll_family: sys::AF_PACKET as _,
765                sll_protocol: (sys::ETH_P_IP as u16).to_be() as _,
766                sll_ifindex: self.1 as _,
767                sll_hatype: 0,
768                sll_pkttype: 0,
769                sll_halen: 0,
770                sll_addr: Default::default(),
771            };
772
773            sockaddr.sll_halen = mac.len() as _;
774            sockaddr.sll_addr[..mac.len()].copy_from_slice(&mac);
775
776            let fut = pin!(self.0.write_with(|io| {
777                let len = core::cmp::min(data.len(), u16::MAX as usize);
778
779                let ret = syscall_los!(unsafe {
780                    sys::sendto(
781                        io.as_fd().as_raw_fd(),
782                        data.as_ptr() as *const _,
783                        len,
784                        sys::MSG_NOSIGNAL,
785                        &sockaddr as *const _ as *const _,
786                        core::mem::size_of::<sys::sockaddr_ll>() as _,
787                    )
788                })?;
789                Ok(ret as usize)
790            }));
791
792            let len = fut.await?;
793
794            assert_eq!(len, data.len());
795
796            Ok(())
797        }
798    }
799
800    impl Readable for &RawSocket {
801        async fn readable(&mut self) -> Result<(), Self::Error> {
802            self.0.readable().await
803        }
804    }
805
806    impl ErrorType for RawSocket {
807        type Error = io::Error;
808    }
809
810    impl RawReceive for RawSocket {
811        async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, MacAddr), Self::Error> {
812            let mut rself = &*self;
813
814            let fut = pin!(rself.receive(buffer));
815
816            fut.await
817        }
818    }
819
820    impl RawSend for RawSocket {
821        async fn send(&mut self, mac: MacAddr, data: &[u8]) -> Result<(), Self::Error> {
822            let mut rself = &*self;
823
824            let fut = pin!(rself.send(mac, data));
825
826            fut.await
827        }
828    }
829
830    impl RawSplit for RawSocket {
831        type Receive<'a>
832            = &'a Self
833        where
834            Self: 'a;
835
836        type Send<'a>
837            = &'a Self
838        where
839            Self: 'a;
840
841        fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
842            let socket = &*self;
843
844            (socket, socket)
845        }
846    }
847
848    impl Readable for RawSocket {
849        async fn readable(&mut self) -> Result<(), Self::Error> {
850            self.0.readable().await
851        }
852    }
853
854    fn as_sockaddr_ll(
855        storage: &sys::sockaddr_storage,
856        len: usize,
857    ) -> io::Result<&sys::sockaddr_ll> {
858        match storage.ss_family as core::ffi::c_int {
859            sys::AF_PACKET => {
860                assert!(len >= core::mem::size_of::<sys::sockaddr_ll>());
861                Ok(unsafe { (storage as *const _ as *const sys::sockaddr_ll).as_ref() }.unwrap())
862            }
863            _ => Err(io::Error::new(ErrorKind::InvalidInput, "invalid argument")),
864        }
865    }
866}
867
868#[cfg(any(target_os = "linux", target_os = "android", target_os = "espidf"))]
869mod sys {
870    pub use libc::*;
871
872    #[macro_export]
873    macro_rules! syscall {
874        ($ret:expr) => {{
875            let result = $ret;
876
877            if result != 0 {
878                Err(::std::io::Error::from_raw_os_error(result))
879            } else {
880                Ok(result)
881            }
882        }};
883    }
884
885    #[macro_export]
886    macro_rules! syscall_los {
887        ($ret:expr) => {{
888            let result = $ret;
889
890            if result == -1 {
891                Err(::std::io::Error::last_os_error())
892            } else {
893                Ok(result)
894            }
895        }};
896    }
897
898    #[macro_export]
899    macro_rules! syscall_los_eagain {
900        ($ret:expr) => {{
901            #[allow(unreachable_patterns)]
902            match syscall_los!($ret) {
903                Ok(_) => Ok(()),
904                Err(e)
905                    if matches!(
906                        e.raw_os_error(),
907                        Some(sys::EINPROGRESS) | Some(sys::EAGAIN) | Some(sys::EWOULDBLOCK)
908                    ) =>
909                {
910                    Ok(())
911                }
912                Err(e) => Err(e),
913            }?;
914
915            Ok::<_, io::Error>(())
916        }};
917    }
918}