/// Receive an Ethernet frame from the network.
Receive an Ethernet frame from the network.
Receive an Ethernet frame from the network .
pub(super) fn receive_frame<B: BufferMut, C: BufferEthernetIpLinkDeviceContext<B>>(
    ctx: &mut C,
    device_id: C::DeviceId,
    mut buffer: B,
) {
    trace!("ethernet::receive_frame: device_id = {:?}", device_id);
    // NOTE(joshlf): We do not currently validate that the Ethernet frame
    // satisfies the minimum length requirement. We expect that if this
    // requirement is necessary (due to requirements of the physical medium),
    // the driver or hardware will have checked it, and that if this requirement
    // is not necessary, it is acceptable for us to operate on a smaller
    // Ethernet frame. If this becomes insufficient in the future, we may want
    // to consider making this behavior configurable (at compile time, at
    // runtime on a global basis, or at runtime on a per-device basis).
    let frame = if let Ok(frame) =
        buffer.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::NoCheck)
    {
        frame
    } else {
        trace!("ethernet::receive_frame: failed to parse ethernet frame");
        // TODO(joshlf): Do something else?
        return;
    };
    let (_, dst) = (frame.src_mac(), frame.dst_mac());
    if !ctx.get_state_with(device_id).link.should_deliver(&dst) {
        trace!("ethernet::receive_frame: destination mac {:?} not for device {:?}", dst, device_id);
        return;
    }
    let frame_dst = FrameDestination::from(dst);
    match frame.ethertype() {
        Some(EtherType::Arp) => {
            let types = if let Ok(types) = peek_arp_types(buffer.as_ref()) {
                types
            } else {
                // TODO(joshlf): Do something else here?
                return;
            };
            match types {
                (ArpHardwareType::Ethernet, ArpNetworkType::Ipv4) => {
                    arp::receive_arp_packet(ctx, device_id, buffer)
                }
            }
        }
        Some(EtherType::Ipv4) => {
            ctx.receive_frame(RecvIpFrameMeta::<_, Ipv4>::new(device_id, frame_dst), buffer)
        }
        Some(EtherType::Ipv6) => {
            ctx.receive_frame(RecvIpFrameMeta::<_, Ipv6>::new(device_id, frame_dst), buffer)
        }
        Some(EtherType::Other(_)) | None => {} // TODO(joshlf)
    }
}
pub ( super ) fn receive_frame < B : BufferMut , C : BufferEthernetIpLinkDeviceContext < B > > ( ctx : & mut C , device_id : C :: DeviceId , mut buffer : B , ) { trace ! ( " " device_id ) ; // NOTE(joshlf): We do not currently validate that the Ethernet frame // satisfies the minimum length requirement. We expect that if this // requirement is necessary (due to requirements of the physical medium), // the driver or hardware will have checked it, and that if this requirement // is not necessary, it is acceptable for us to operate on a smaller // Ethernet frame. If this becomes insufficient in the future, we may want // to consider making this behavior configurable (at compile time, at // runtime on a global basis, or at runtime on a per-device basis). let frame = if let Ok ( frame ) = buffer . parse_with :: < _ , EthernetFrame < _ > > ( EthernetFrameLengthCheck :: NoCheck ) { frame } else { trace ! ( " " ) ; // TODO(joshlf): Do something else? return ; } ; let ( _ , dst ) = ( frame . src_mac ( ) , frame . dst_mac ( ) ) ; if ! ctx . get_state_with ( device_id ) . link . should_deliver ( & dst ) { trace ! ( " " dst device_id ) ; return ; } let frame_dst = FrameDestination :: from ( dst ) ; match frame . ethertype ( ) { Some ( EtherType :: Arp ) => { let types = if let Ok ( types ) = peek_arp_types ( buffer . as_ref ( ) ) { types } else { // TODO(joshlf): Do something else here? return ; } ; match types { ( ArpHardwareType :: Ethernet , ArpNetworkType :: Ipv4 ) => { arp :: receive_arp_packet ( ctx , device_id , buffer ) } } } Some ( EtherType :: Ipv4 ) => { ctx . receive_frame ( RecvIpFrameMeta :: < _ , Ipv4 > :: new ( device_id , frame_dst ) , buffer ) } Some ( EtherType :: Ipv6 ) => { ctx . receive_frame ( RecvIpFrameMeta :: < _ , Ipv6 > :: new ( device_id , frame_dst ) , buffer ) } Some ( EtherType :: Other ( _ ) ) | None => { } // TODO(joshlf) } }
Receive an Ethernet frame from the network.
Receive an Ethernet frame from the network .
ctx
&mut C
device_id
C::DeviceId
buffer
B