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 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, ð_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 _ => 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}