// 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 Internet Protocol, versions 4 and 6.

mod forwarding;
mod icmp;
#[cfg(test)]
mod testdata;
mod types;

pub use self::types::*;

use log::{debug, trace};
use std::fmt::Debug;
use std::mem;

use packet::{BufferMut, BufferSerializer, ParsablePacket, ParseBufferMut, Serializer};
use zerocopy::{ByteSlice, ByteSliceMut};

use crate::device::DeviceId;
use crate::ip::forwarding::{Destination, ForwardingTable};
use crate::wire::ipv4::{Ipv4Packet, Ipv4PacketBuilder};
use crate::wire::ipv6::{Ipv6Packet, Ipv6PacketBuilder};
use crate::{Context, EventDispatcher};

// default IPv4 TTL or IPv6 hops
const DEFAULT_TTL: u8 = 64;

/// The state associated with the IP layer.
#[derive(Default)]
pub struct IpLayerState {
    v4: IpLayerStateInner<Ipv4>,
    v6: IpLayerStateInner<Ipv6>,
}

#[derive(Default)]
struct IpLayerStateInner<I: Ip> {
    forward: bool,
    table: ForwardingTable<I>,
}

fn dispatch_receive_ip_packet<D: EventDispatcher, I: IpAddr, B: BufferMut>(
    ctx: &mut Context<D>, proto: IpProto, src_ip: I, dst_ip: I, mut buffer: B,
) -> bool {
    increment_counter!(ctx, "dispatch_receive_ip_packet");
    match proto {
        IpProto::Icmp | IpProto::Icmpv6 => icmp::receive_icmp_packet(ctx, src_ip, dst_ip, buffer),
        IpProto::Tcp | IpProto::Udp => {
            crate::transport::receive_ip_packet(ctx, src_ip, dst_ip, proto, buffer)
        }
    }
}

/// Receive an IP packet from a device.
pub fn receive_ip_packet<D: EventDispatcher, B: BufferMut, I: Ip>(
    ctx: &mut Context<D>, device: DeviceId, mut buffer: B,
) {
    trace!("receive_ip_packet({})", device);
    let mut packet = if let Ok(packet) = buffer.parse_mut::<<I as IpExt<_>>::Packet>() {
        packet
    } else {
        // TODO(joshlf): Do something with ICMP here?
        return;
    };
    trace!("receive_ip_packet: parsed packet: {:?}", packet);

    if I::LOOPBACK_SUBNET.contains(packet.dst_ip()) {
        // A packet from outside this host was sent with the destination IP of
        // the loopback address, which is illegal. Loopback traffic is handled
        // explicitly in send_ip_packet. TODO(joshlf): Do something with ICMP
        // here?
        debug!(
            "got packet from remote host for loopback address {}",
            packet.dst_ip()
        );
    } else if deliver(ctx, device, packet.dst_ip()) {
        trace!("receive_ip_packet: delivering locally");
        // TODO(joshlf):
        // - Do something with ICMP if we don't have a handler for that protocol?
        // - Check for already-expired TTL?
        let handled = if let Ok(proto) = packet.proto() {
            let src_ip = packet.src_ip();
            let dst_ip = packet.dst_ip();
            // drop packet so we can re-use the underlying buffer
            mem::drop(packet);
            dispatch_receive_ip_packet(ctx, proto, src_ip, dst_ip, buffer)
        } else {
            // TODO(joshlf): Log unrecognized protocol number
            false
        };
    } else if let Some(dest) = forward(ctx, packet.dst_ip()) {
        let ttl = packet.ttl();
        if ttl > 1 {
            trace!("receive_ip_packet: forwarding");
            packet.set_ttl(ttl - 1);
            let meta = packet.parse_metadata();
            // drop packet so we can re-use the underlying buffer
            mem::drop(packet);
            // Undo the effects of parsing so that the body of the buffer
            // contains the entire IP packet again (not just the body).
            buffer.undo_parse(meta);
            crate::device::send_ip_frame(
                ctx,
                dest.device,
                dest.next_hop,
                BufferSerializer::new_vec(buffer),
            );
            return;
        } else {
            // TTL is 0 or would become 0 after decrement; see "TTL" section,
            // https://tools.ietf.org/html/rfc791#page-14
            // TODO(joshlf): Do something with ICMP here?
            debug!("received IP packet dropped due to expired TTL");
        }
    } else {
        // TODO(joshlf): Do something with ICMP here?
        debug!(
            "received IP packet with no known route to destination {}",
            packet.dst_ip()
        );
    }
}

/// Get the local address of the interface that will be used to route to a
/// remote address.
///
/// `local_address_for_remote` looks up the route to `remote`. If one is found,
/// it returns the IP address of the interface specified by the route, or `None`
/// if the interface has no IP address.
pub fn local_address_for_remote<D: EventDispatcher, A: IpAddr>(
    ctx: &mut Context<D>, remote: A,
) -> Option<A> {
    let route = lookup_route(&ctx.state().ip, remote)?;
    crate::device::get_ip_addr(ctx, route.device).map(|(addr, _)| addr)
}

// Should we deliver this packet locally?
// deliver returns true if:
// - dst_ip is equal to the address set on the device
// - dst_ip is equal to the broadcast address of the subnet set on the device
// - dst_ip is equal to the global broadcast address
fn deliver<D: EventDispatcher, A: IpAddr>(
    ctx: &mut Context<D>, device: DeviceId, dst_ip: A,
) -> bool {
    // TODO(joshlf):
    // - This implements a strict host model (in which we only accept packets
    //   which are addressed to the device over which they were received). This
    //   is the easiest to implement for the time being, but we should actually
    //   put real thought into what our host model should be (NET-1011).
    specialize_ip_addr!(
        fn deliver(dst_ip: Self, addr_subnet: Option<(Self, Subnet<Self>)>) -> bool {
            Ipv4Addr => {
                addr_subnet
                    .map(|(addr, subnet)| dst_ip == addr || dst_ip == subnet.broadcast())
                    .unwrap_or(dst_ip == Ipv4::BROADCAST_ADDRESS)
            }
            Ipv6Addr => { log_unimplemented!(false, "ip::deliver: Ipv6 not implemeneted") }
        }
    );
    A::deliver(dst_ip, crate::device::get_ip_addr::<D, A>(ctx, device))
}

// Should we forward this packet, and if so, to whom?
fn forward<D: EventDispatcher, A: IpAddr>(
    ctx: &mut Context<D>, dst_ip: A,
) -> Option<Destination<A::Version>> {
    specialize_ip_addr!(
        fn forwarding_enabled(state: &IpLayerState) -> bool {
            Ipv4Addr => { state.v4.forward }
            Ipv6Addr => { state.v6.forward }
        }
    );
    let ip_state = &ctx.state().ip;
    if A::forwarding_enabled(ip_state) {
        lookup_route(ip_state, dst_ip)
    } else {
        None
    }
}

// Look up the route to a host.
fn lookup_route<A: IpAddr>(state: &IpLayerState, dst_ip: A) -> Option<Destination<A::Version>> {
    specialize_ip_addr!(
        fn get_table(state: &IpLayerState) -> &ForwardingTable<Self::Version> {
            Ipv4Addr => { &state.v4.table }
            Ipv6Addr => { &state.v6.table }
        }
    );
    A::get_table(state).lookup(dst_ip)
}

/// Add a route to the forwarding table.
pub fn add_device_route<D: EventDispatcher, A: IpAddr>(
    ctx: &mut Context<D>, subnet: Subnet<A>, device: DeviceId,
) {
    specialize_ip_addr!(
        fn generic_add_route(state: &mut IpLayerState, subnet: Subnet<Self>, device: DeviceId) {
            Ipv4Addr => { state.v4.table.add_device_route(subnet, device) }
            Ipv6Addr => { state.v6.table.add_device_route(subnet, device) }
        }
    );
    A::generic_add_route(&mut ctx.state().ip, subnet, device)
}

/// Is this one of our local addresses?
///
/// `is_local_addr` returns whether `addr` is the address associated with one of
/// our local interfaces.
pub fn is_local_addr<D: EventDispatcher, A: IpAddr>(ctx: &mut Context<D>, addr: A) -> bool {
    log_unimplemented!(false, "ip::is_local_addr: not implemented")
}

/// Send an IP packet to a remote host.
///
/// `send_ip_packet` accepts a destination IP address, a protocol, and a
/// callback. It computes the routing information, and invokes the callback with
/// the computed destination address. The callback returns a
/// `SerializationRequest`, which is serialized in a new IP packet and sent.
pub fn send_ip_packet<D: EventDispatcher, A, S, F>(
    ctx: &mut Context<D>, dst_ip: A, proto: IpProto, get_body: F,
) where
    A: IpAddr,
    S: Serializer,
    F: FnOnce(A) -> S,
{
    trace!("send_ip_packet({}, {})", dst_ip, proto);
    increment_counter!(ctx, "send_ip_packet");
    if A::Version::LOOPBACK_SUBNET.contains(dst_ip) {
        increment_counter!(ctx, "send_ip_packet::loopback");
        // TODO(joshlf): Currently, we serialize using the normal Serializer
        // functionality. I wonder if, in the case of delivering to loopback, we
        // can do something more efficient?
        let mut buffer = get_body(A::Version::LOOPBACK_ADDRESS).serialize_outer();
        // TODO(joshlf): Respond with some kind of error if we don't have a
        // handler for that protocol? Maybe simulate what would have happened
        // (w.r.t ICMP) if this were a remote host?
        dispatch_receive_ip_packet(
            ctx,
            proto,
            A::Version::LOOPBACK_ADDRESS,
            dst_ip,
            buffer.as_buf_mut(),
        );
    } else if let Some(dest) = lookup_route(&ctx.state().ip, dst_ip) {
        let (src_ip, _) = crate::device::get_ip_addr(ctx, dest.device)
            .expect("IP device route set for device without IP address");
        send_ip_packet_from_device(
            ctx,
            dest.device,
            src_ip,
            dst_ip,
            dest.next_hop,
            proto,
            get_body(src_ip),
        );
    } else {
        debug!("No route to host");
        // TODO(joshlf): No route to host
    }
}

/// Send an IP packet to a remote host from a specific source address.
///
/// `send_ip_packet_from` accepts a source and destination IP address and a
/// `SerializationRequest`. It computes the routing information and serializes
/// the request in a new IP packet and sends it.
///
/// `send_ip_packet_from` computes a route to the destination with the
/// restriction that the packet must originate from the source address, and must
/// eagress over the interface associated with that source address. If this
/// restriction cannot be met, a "no route to host" error is returned.
pub fn send_ip_packet_from<D: EventDispatcher, A, S>(
    ctx: &mut Context<D>, src_ip: A, dst_ip: A, proto: IpProto, body: S,
) where
    A: IpAddr,
    S: Serializer,
{
    // TODO(joshlf): Figure out how to compute a route with the restrictions
    // mentioned in the doc comment.
    log_unimplemented!((), "ip::send_ip_packet_from: not implemented");
}

/// Send an IP packet to a remote host over a specific device.
///
/// `send_ip_packet_from_device` accepts a device, a source and destination IP
/// address, a next hop IP address, and a `SerializationRequest`. It computes
/// the routing information and serializes the request in a new IP packet and
/// sends it.
///
/// # Panics
///
/// Since `send_ip_packet_from_device` specifies a physical device, it cannot
/// send to or from a loopback IP address. If either `src_ip` or `dst_ip` are in
/// the loopback subnet, `send_ip_packet_from_device` will panic.
pub fn send_ip_packet_from_device<D: EventDispatcher, A, S>(
    ctx: &mut Context<D>, device: DeviceId, src_ip: A, dst_ip: A, next_hop: A, proto: IpProto,
    body: S,
) where
    A: IpAddr,
    S: Serializer,
{
    assert!(!A::Version::LOOPBACK_SUBNET.contains(src_ip));
    assert!(!A::Version::LOOPBACK_SUBNET.contains(dst_ip));

    specialize_ip_addr!(
        fn serialize<D, S>(
            ctx: &mut Context<D>, device: DeviceId, src_ip: Self, dst_ip: Self, next_hop: Self, ttl: u8, proto: IpProto, body: S
        )
        where
            D: EventDispatcher,
            S: Serializer,
        {
            Ipv4Addr => {
                let body = body.encapsulate(Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto));
                crate::device::send_ip_frame(ctx, device, next_hop, body);
            }
            Ipv6Addr => {
                let body = body.encapsulate(Ipv6PacketBuilder::new(src_ip, dst_ip, ttl, proto));
                crate::device::send_ip_frame(ctx, device, next_hop, body);
            }
        }
    );
    A::serialize(
        ctx,
        device,
        src_ip,
        dst_ip,
        next_hop,
        DEFAULT_TTL,
        proto,
        body,
    )
}

// An `Ip` extension trait for internal use.
//
// This trait adds extra associated types that are useful for our implementation
// here, but which consumers outside of the ip module do not need to see.
trait IpExt<B: ByteSlice>: Ip {
    type Packet: IpPacket<B, Self>;
}

impl<B: ByteSlice, I: Ip> IpExt<B> for I {
    default type Packet = !;
}

impl<B: ByteSlice> IpExt<B> for Ipv4 {
    type Packet = Ipv4Packet<B>;
}

impl<B: ByteSlice> IpExt<B> for Ipv6 {
    type Packet = Ipv6Packet<B>;
}

// `Ipv4Packet` or `Ipv6Packet`
trait IpPacket<B: ByteSlice, I: Ip>: Sized + Debug + ParsablePacket<B, ()> {
    fn src_ip(&self) -> I::Addr;
    fn dst_ip(&self) -> I::Addr;
    fn proto(&self) -> Result<IpProto, u8>;
    fn ttl(&self) -> u8;
    fn set_ttl(&mut self, ttl: u8)
    where
        B: ByteSliceMut;
}

impl<B: ByteSlice> IpPacket<B, Ipv4> for Ipv4Packet<B> {
    fn src_ip(&self) -> Ipv4Addr {
        Ipv4Packet::src_ip(self)
    }
    fn dst_ip(&self) -> Ipv4Addr {
        Ipv4Packet::dst_ip(self)
    }
    fn proto(&self) -> Result<IpProto, u8> {
        Ipv4Packet::proto(self)
    }
    fn ttl(&self) -> u8 {
        Ipv4Packet::ttl(self)
    }
    fn set_ttl(&mut self, ttl: u8)
    where
        B: ByteSliceMut,
    {
        Ipv4Packet::set_ttl(self, ttl)
    }
}

impl<B: ByteSlice> IpPacket<B, Ipv6> for Ipv6Packet<B> {
    fn src_ip(&self) -> Ipv6Addr {
        Ipv6Packet::src_ip(self)
    }
    fn dst_ip(&self) -> Ipv6Addr {
        Ipv6Packet::dst_ip(self)
    }
    fn proto(&self) -> Result<IpProto, u8> {
        Ipv6Packet::proto(self)
    }
    fn ttl(&self) -> u8 {
        Ipv6Packet::hop_limit(self)
    }
    fn set_ttl(&mut self, ttl: u8)
    where
        B: ByteSliceMut,
    {
        Ipv6Packet::set_hop_limit(self, ttl)
    }
}
