smoltcp/iface/interface/
ethernet.rs

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