smoltcp/iface/interface/
ethernet.rs1use 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 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, ð_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 _ => 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}