// Copyright 2019 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.

use libc::{self, c_char, c_int, c_short};
use std::ffi::CString;
use std::io::Error;
use std::net::UdpSocket;
use std::ptr;
use structopt::StructOpt;

// Socket ioctl get interface index. Defined in Linux:include/uapi/linux/sockios.h
const SIOCSIFFLAGS: c_int = 0x8914;

// Interface flag UP. Defined in Linux:include/uapi/linux/if.h
const IFF_UP: c_short = 1 << 0;
const IFF_NOARP: c_short = 1 << 7;

const ETH_IFACE_NAME: &str = "eth0";

#[derive(StructOpt, Debug)]
enum Command {
    #[structopt(name = "up")]
    Up,
    #[structopt(name = "xfer")]
    Transfer {
        send_byte: u8,
        receive_byte: u8,
        length: usize,
    },
}

// Open a socket and return the file descriptor. The type and protocol don't really matter since
// we're only using this socket to perform ioctls.
fn open_fd() -> std::io::Result<i32> {
    // The protocol is a two byte value that must be given as an i32 in network order. It is defined
    // as an i32 in libc so we must cast to u16 before converting to big endian.
    let protocol = (libc::IPPROTO_UDP as u16).to_be() as i32;
    let fd = unsafe { libc::socket(libc::AF_PACKET, libc::SOCK_DGRAM, protocol) };
    if fd == -1 {
        Err(Error::last_os_error())
    } else {
        Ok(fd)
    }
}

// See Linux:include/uapi/linux/if.h.
// We add padding to this struct to bring the size to sizeof(ifreq), which is 40.
#[repr(C)]
struct SetFlagsRequest {
    name: [c_char; 16],
    flags: c_short,
    _padding: [u8; 22],
}

// Do a "set interface flags" ioctl on the fd. We use this to bring up the ethernet interface, which
// is specified in the request using ETH_IFACE_NAME.
fn set_flags(fd: i32, flags: c_short) -> () {
    let mut req = SetFlagsRequest {
        name: [0; 16],
        flags: flags,
        _padding: [0; 22],
    };
    let name = CString::new(ETH_IFACE_NAME).unwrap();
    unsafe {
        ptr::copy_nonoverlapping(
            name.as_ptr(),
            req.name.as_mut_ptr(),
            name.as_bytes_with_nul().len(),
        );
        libc::ioctl(fd, SIOCSIFFLAGS, &mut req);
    }
}

fn main() -> std::io::Result<()> {
    let cmd = Command::from_args();
    match cmd {
        Command::Up => {
            let fd = open_fd()?;
            // In addition to bringing up the interface (IFF_UP), we specify no ARP (IFF_NOARP) to
            // reduce packet spam.
            set_flags(fd, IFF_UP | IFF_NOARP);
            println!("PASS");
        }
        Command::Transfer {
            send_byte,
            receive_byte,
            length,
        } => {
            // Bind the socket to all addresses, on port 4242.
            let socket = UdpSocket::bind(("::", 4242))?;

            // Send to fe80::1, the IPv6 address of the host.
            let send_buf = vec![send_byte; length];
            socket.send_to(&send_buf, ("fe80::1", 4242))?;

            let mut recv_buf = vec![0; length];
            let actual = socket.recv(&mut recv_buf)?;

            if actual == length && recv_buf.iter().all(|b| *b == receive_byte) {
                println!("PASS");
            }
        }
    }
    Ok(())
}
