smoltcp/iface/interface/
ethernet.rs

1use super::*;
2
3impl InterfaceInner {
4    pub(super) fn process_ethernet<'frame>(
5        &mut self,
6        sockets: &mut SocketSet,
7        meta: crate::phy::PacketMeta,
8        frame: &'frame [u8],
9        fragments: &'frame mut FragmentsBuffer,
10    ) -> Option<EthernetPacket<'frame>> {
11        let eth_frame = check!(EthernetFrame::new_checked(frame));
12
13        // Ignore any packets not directed to our hardware address or any of the multicast groups.
14        if !eth_frame.dst_addr().is_broadcast()
15            && !eth_frame.dst_addr().is_multicast()
16            && HardwareAddress::Ethernet(eth_frame.dst_addr()) != self.hardware_addr
17        {
18            return None;
19        }
20
21        match eth_frame.ethertype() {
22            #[cfg(feature = "proto-ipv4")]
23            EthernetProtocol::Arp => self.process_arp(self.now, &eth_frame),
24            #[cfg(feature = "proto-ipv4")]
25            EthernetProtocol::Ipv4 => {
26                let ipv4_packet = check!(Ipv4Packet::new_checked(eth_frame.payload()));
27
28                self.process_ipv4(
29                    sockets,
30                    meta,
31                    eth_frame.src_addr().into(),
32                    &ipv4_packet,
33                    fragments,
34                )
35                .map(EthernetPacket::Ip)
36            }
37            #[cfg(feature = "proto-ipv6")]
38            EthernetProtocol::Ipv6 => {
39                let ipv6_packet = check!(Ipv6Packet::new_checked(eth_frame.payload()));
40                self.process_ipv6(sockets, meta, eth_frame.src_addr().into(), &ipv6_packet)
41                    .map(EthernetPacket::Ip)
42            }
43            // Drop all other traffic.
44            _ => None,
45        }
46    }
47
48    pub(super) fn dispatch_ethernet<Tx, F>(
49        &mut self,
50        tx_token: Tx,
51        buffer_len: usize,
52        f: F,
53    ) -> Result<(), DispatchError>
54    where
55        Tx: TxToken,
56        F: FnOnce(EthernetFrame<&mut [u8]>),
57    {
58        let tx_len = EthernetFrame::<&[u8]>::buffer_len(buffer_len);
59        tx_token.consume(tx_len, |tx_buffer| {
60            debug_assert!(tx_buffer.as_ref().len() == tx_len);
61            let mut frame = EthernetFrame::new_unchecked(tx_buffer);
62
63            let src_addr = self.hardware_addr.ethernet_or_panic();
64            frame.set_src_addr(src_addr);
65
66            f(frame);
67
68            Ok(())
69        })
70    }
71}