// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! The Ethernet protocol.

use std::fmt::{self, Display, Formatter};

use log::debug;
use packet::{Buf, ParseBuffer, Serializer};
use zerocopy::{AsBytes, FromBytes, Unaligned};

use crate::device::arp::{ArpDevice, ArpHardwareType, ArpState};
use crate::device::DeviceId;
use crate::ip::{Ip, IpAddr, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr, Subnet};
use crate::wire::arp::peek_arp_types;
use crate::wire::ethernet::{EthernetFrame, EthernetFrameBuilder};
use crate::{Context, EventDispatcher};

/// A media access control (MAC) address.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(transparent)]
pub struct Mac([u8; 6]);

unsafe impl FromBytes for Mac {}
unsafe impl AsBytes for Mac {}
unsafe impl Unaligned for Mac {}

impl Mac {
    /// The broadcast MAC address.
    ///
    /// The broadcast MAC address, FF:FF:FF:FF:FF:FF, indicates that a frame should
    /// be received by all receivers regardless of their local MAC address.
    pub const BROADCAST: Mac = Mac([0xFF; 6]);

    const EUI_MAGIC: [u8; 2] = [0xff, 0xfe];

    /// Construct a new MAC address.
    pub const fn new(bytes: [u8; 6]) -> Mac {
        Mac(bytes)
    }

    /// Get the bytes of the MAC address.
    pub fn bytes(&self) -> [u8; 6] {
        self.0
    }

    /// Return the RFC4291 EUI-64 interface identifier for this MAC address.
    ///
    /// `eui_magic` is the two bytes that are inserted between the MAC address
    /// to form the identifier. If None, the standard 0xfffe will be used.
    ///
    /// TODO: remove `eui_magic` arg if/once it is unused.
    pub fn to_eui64(&self, eui_magic: Option<[u8; 2]>) -> [u8; 8] {
        let mut eui = [0; 8];
        eui[0..3].copy_from_slice(&self.0[0..3]);
        eui[3..5].copy_from_slice(&eui_magic.unwrap_or(Self::EUI_MAGIC));
        eui[5..8].copy_from_slice(&self.0[3..6]);
        eui[0] ^= 0b0000_0010;
        eui
    }

    /// Return the link-local IPv6 address for this MAC address, as per RFC 4862.
    ///
    /// `eui_magic` is the two bytes that are inserted between the MAC address
    /// to form the identifier. If None, the standard 0xfffe will be used.
    ///
    /// TODO: remove `eui_magic` arg if/once it is unused.
    pub fn to_slaac_ipv6(&self, eui_magic: Option<[u8; 2]>) -> Ipv6Addr {
        let mut ipv6_addr = [0; 16];
        ipv6_addr[0..2].copy_from_slice(&[0xfe, 0x80]);
        ipv6_addr[8..16].copy_from_slice(&self.to_eui64(eui_magic));
        Ipv6Addr::new(ipv6_addr)
    }

    /// Is this a unicast MAC address?
    ///
    /// Returns true if the least significant bit of the first byte of the
    /// address is 0.
    pub fn is_unicast(&self) -> bool {
        // https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
        self.0[0] & 1 == 0
    }

    /// Is this a multicast MAC address?
    ///
    /// Returns true if the least significant bit of the first byte of the
    /// address is 1.
    pub fn is_multicast(&self) -> bool {
        // https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
        self.0[0] & 1 == 1
    }

    /// Is this the broadcast MAC address?
    ///
    /// Returns true if this is the broadcast MAC address, FF:FF:FF:FF:FF:FF.
    pub fn is_broadcast(&self) -> bool {
        // https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
        *self == Mac::BROADCAST
    }
}

/// An EtherType number.
#[allow(missing_docs)]
#[derive(Eq, PartialEq, Debug)]
#[repr(u16)]
pub enum EtherType {
    Ipv4 = EtherType::IPV4,
    Arp = EtherType::ARP,
    Ipv6 = EtherType::IPV6,
}

impl EtherType {
    const IPV4: u16 = 0x0800;
    const ARP: u16 = 0x0806;
    const IPV6: u16 = 0x86DD;

    /// Construct an `EtherType` from a `u16`.
    ///
    /// `from_u16` returns the `EtherType` with the numerical value `u`, or
    /// `None` if the value is unrecognized.
    pub fn from_u16(u: u16) -> Option<EtherType> {
        match u {
            Self::IPV4 => Some(EtherType::Ipv4),
            Self::ARP => Some(EtherType::Arp),
            Self::IPV6 => Some(EtherType::Ipv6),
            _ => None,
        }
    }
}

impl Display for EtherType {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(
            f,
            "{}",
            match self {
                EtherType::Ipv4 => "IPv4",
                EtherType::Arp => "ARP",
                EtherType::Ipv6 => "IPv6",
            }
        )
    }
}

/// The state associated with an Ethernet device.
pub struct EthernetDeviceState {
    mac: Mac,
    ipv4_addr: Option<(Ipv4Addr, Subnet<Ipv4Addr>)>,
    ipv6_addr: Option<(Ipv6Addr, Subnet<Ipv6Addr>)>,
    ipv4_arp: ArpState<Ipv4Addr, EthernetArpDevice>,
}

impl EthernetDeviceState {
    /// Construct a new `EthernetDeviceState`.
    pub fn new(mac: Mac) -> EthernetDeviceState {
        EthernetDeviceState {
            mac,
            ipv4_addr: None,
            ipv6_addr: None,
            ipv4_arp: ArpState::default(),
        }
    }
}

/// An extension trait adding IP-related functionality to `Ipv4` and `Ipv6`.
trait EthernetIpExt: Ip {
    const ETHER_TYPE: EtherType;
}

impl<I: Ip> EthernetIpExt for I {
    default const ETHER_TYPE: EtherType = EtherType::Ipv4;
}

impl EthernetIpExt for Ipv4 {
    const ETHER_TYPE: EtherType = EtherType::Ipv4;
}

impl EthernetIpExt for Ipv6 {
    const ETHER_TYPE: EtherType = EtherType::Ipv6;
}

/// Send an IP packet in an Ethernet frame.
///
/// `send_ip_frame` accepts a device ID, a local IP address, and a
/// `SerializationRequest`. It computes the routing information and serializes
/// the request in a new Ethernet frame and sends it.
pub fn send_ip_frame<D: EventDispatcher, A, S>(
    ctx: &mut Context<D>, device_id: u64, local_addr: A, body: S,
) where
    A: IpAddr,
    S: Serializer,
{
    specialize_ip_addr!(
        fn lookup_dst_mac<D>(ctx: &mut Context<D>, device_id: u64, local_addr: Self) -> Option<Mac>
        where
            D: EventDispatcher,
        {
            Ipv4Addr => {
                let src_mac = get_device_state(ctx, device_id).mac;
                if let Some(dst_mac) = crate::device::arp::lookup::<_, _, EthernetArpDevice>(
                    ctx, device_id, src_mac, local_addr,
                ) {
                    Some(dst_mac)
                } else {
                    log_unimplemented!(
                        None,
                        "device::ethernet::send_ip_frame: unimplemented on arp cache miss"
                    )
                }
            }
            Ipv6Addr => { log_unimplemented!(None, "device::ethernet::send_ip_frame: IPv6 unimplemented") }
        }
    );

    if let Some(dst_mac) = A::lookup_dst_mac(ctx, device_id, local_addr) {
        let src_mac = get_device_state(ctx, device_id).mac;
        let buffer = body
            .encapsulate(EthernetFrameBuilder::new(
                src_mac,
                dst_mac,
                A::Version::ETHER_TYPE,
            ))
            .serialize_outer();
        ctx.dispatcher()
            .send_frame(DeviceId::new_ethernet(device_id), buffer.as_ref());
    }
}

/// Receive an Ethernet frame from the network.
pub fn receive_frame<D: EventDispatcher>(ctx: &mut Context<D>, device_id: u64, bytes: &mut [u8]) {
    let mut buffer = Buf::new(bytes, ..);
    let frame = if let Ok(frame) = buffer.parse::<EthernetFrame<_>>() {
        frame
    } else {
        // TODO(joshlf): Do something else?
        return;
    };

    if let Some(Ok(ethertype)) = frame.ethertype() {
        let (src, dst) = (frame.src_mac(), frame.dst_mac());
        let device = DeviceId::new_ethernet(device_id);
        match ethertype {
            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, EtherType::Ipv4) => {
                        crate::device::arp::receive_arp_packet::<D, Ipv4Addr, EthernetArpDevice, _>(
                            ctx, device_id, src, dst, buffer,
                        )
                    }
                    types => debug!("got ARP packet for unsupported types: {:?}", types),
                }
            }
            EtherType::Ipv4 => crate::ip::receive_ip_packet::<D, _, Ipv4>(ctx, device, buffer),
            EtherType::Ipv6 => crate::ip::receive_ip_packet::<D, _, Ipv6>(ctx, device, buffer),
        }
    } else {
        // TODO(joshlf): Do something else?
        return;
    }
}

/// Get the IP address associated with this device.
pub fn get_ip_addr<D: EventDispatcher, A: IpAddr>(
    ctx: &mut Context<D>, device_id: u64,
) -> Option<(A, Subnet<A>)> {
    specialize_ip_addr!(
        fn get_ip_addr(state: &EthernetDeviceState) -> Option<(Self, Subnet<Self>)> {
            Ipv4Addr => { state.ipv4_addr }
            Ipv6Addr => { state.ipv6_addr }
        }
    );
    A::get_ip_addr(get_device_state(ctx, device_id))
}

/// Set the IP address associated with this device.
pub fn set_ip_addr<D: EventDispatcher, A: IpAddr>(
    ctx: &mut Context<D>, device_id: u64, addr: A, subnet: Subnet<A>,
) {
    // TODO(joshlf): Perform any other necessary setup
    specialize_ip_addr!(
        fn set_ip_addr(state: &mut EthernetDeviceState, addr: Self, subnet: Subnet<Self>) {
            Ipv4Addr => { state.ipv4_addr = Some((addr, subnet)) }
            Ipv6Addr => { state.ipv6_addr = Some((addr, subnet)) }
        }
    );
    A::set_ip_addr(get_device_state(ctx, device_id), addr, subnet)
}

fn get_device_state<D: EventDispatcher>(
    ctx: &mut Context<D>, device_id: u64,
) -> &mut EthernetDeviceState {
    ctx.state()
        .device
        .ethernet
        .get_mut(&device_id)
        .expect(&format!("no such Ethernet device: {}", device_id))
}

// Dummy type used to implement ArpDevice.
pub struct EthernetArpDevice;

impl ArpDevice<Ipv4Addr> for EthernetArpDevice {
    type HardwareAddr = Mac;
    const BROADCAST: Mac = Mac::BROADCAST;

    fn send_arp_frame<D: EventDispatcher, S: Serializer>(
        ctx: &mut Context<D>, device_id: u64, dst: Self::HardwareAddr, body: S,
    ) {
        let src = get_device_state(ctx, device_id).mac;
        let buffer = body
            .encapsulate(EthernetFrameBuilder::new(src, dst, EtherType::Arp))
            .serialize_outer();
        ctx.dispatcher()
            .send_frame(DeviceId::new_ethernet(device_id), buffer.as_ref());
    }

    fn get_arp_state<D: EventDispatcher>(
        ctx: &mut Context<D>, device_id: u64,
    ) -> &mut ArpState<Ipv4Addr, Self> {
        &mut get_device_state(ctx, device_id).ipv4_arp
    }

    fn get_protocol_addr<D: EventDispatcher>(
        ctx: &mut Context<D>, device_id: u64,
    ) -> Option<Ipv4Addr> {
        get_device_state(ctx, device_id).ipv4_addr.map(|x| x.0)
    }

    fn get_hardware_addr<D: EventDispatcher>(ctx: &mut Context<D>, device_id: u64) -> Mac {
        get_device_state(ctx, device_id).mac
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_mac_to_eui() {
        assert_eq!(
            Mac::new([0x00, 0x1a, 0xaa, 0x12, 0x34, 0x56]).to_eui64(None),
            [0x02, 0x1a, 0xaa, 0xff, 0xfe, 0x12, 0x34, 0x56]
        );
        assert_eq!(
            Mac::new([0x00, 0x1a, 0xaa, 0x12, 0x34, 0x56]).to_eui64(Some([0xfe, 0xfe])),
            [0x02, 0x1a, 0xaa, 0xfe, 0xfe, 0x12, 0x34, 0x56]
        );
    }

    #[test]
    fn test_slaac() {
        assert_eq!(
            Mac::new([0x00, 0x1a, 0xaa, 0x12, 0x34, 0x56]).to_slaac_ipv6(None),
            Ipv6Addr::new([
                0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x1a, 0xaa, 0xff, 0xfe, 0x12, 0x34, 0x56
            ])
        );
        assert_eq!(
            Mac::new([0x00, 0x1a, 0xaa, 0x12, 0x34, 0x56]).to_slaac_ipv6(Some([0xfe, 0xfe])),
            Ipv6Addr::new([
                0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x1a, 0xaa, 0xfe, 0xfe, 0x12, 0x34, 0x56
            ])
        );
    }
}
