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