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

library fuchsia.netstack;

using fuchsia.net;
using fuchsia.net.dhcp;
using fuchsia.hardware.ethernet;
using zx;

enum Protocol {
    UNSPECIFIED = 0;
    UDP = 1;
    TCP = 2;
};

enum Status {
    OK = 0;
    UNKNOWN_ERROR = 1;
    DNS_ERROR = 2;
    PARSE_ERROR = 3;
    IPV4_ONLY = 4;
    UNKNOWN_INTERFACE = 5;
};

struct NetErr {
    Status status;
    string message;
};

struct InterfaceConfig {
    string name;

    /// An unstable file path corresponding to the interface. Used in watching the creation
    /// and destruction of the interface, or in accessing the interface using netdump.
    string filepath;

    uint32 metric;
    /// Deprecated; to configure a network interface, use SetDhcpClientStatus
    /// and SetInterfaceAddress instead.
    IpAddressConfig ip_address_config;
};

union IpAddressConfig {
    1: fuchsia.net.Subnet static_ip;
    2: bool dhcp;
};

/// https://linux.die.net/man/7/netdevice
struct NetInterface {
    uint32 id;
    uint32 flags;
    uint32 features;
    uint32 configuration;
    string name;
    /// addr is one of the interface's IPv4 addresses, even if the interface
    /// holds multiple. No guarantees are made about which address is used when
    /// an interface has multiple IPv4 addresses.
    ///
    /// If the interface does not have an IPv4 address, addr is the unspecified
    /// IPv4 address (0.0.0.0).
    fuchsia.net.IpAddress addr;
    /// netmask is addr's corresponding network mask.
    ///
    /// If the interface does not have an IPv4 address, netmask is the 0 netmask
    /// (0.0.0.0).
    fuchsia.net.IpAddress netmask;
    /// netmask is addr's corresponding network's broadcast address.
    ///
    /// If the interface does not have an IPv4 address, broadaddr is the
    /// unspecified IPv4 address (0.0.0.0).
    fuchsia.net.IpAddress broadaddr;
    vector<fuchsia.net.Subnet> ipv6addrs;
    bytes hwaddr;
};

/// New version that includes a metric value.
// TODO(NET-2078): Move this to NetInterface once Chromium stops using
// netstack.fidl.
struct NetInterface2 {
    uint32 id;
    uint32 flags;
    uint32 features;
    uint32 configuration;
    uint32 metric;
    string name;
    /// addr is one of the interface's IPv4 addresses, even if the interface
    /// holds multiple. No guarantees are made about which address is used when
    /// an interface has multiple IPv4 addresses.
    ///
    /// If the interface does not have an IPv4 address, addr is the unspecified
    /// IPv4 address (0.0.0.0).
    fuchsia.net.IpAddress addr;
    /// netmask is addr's corresponding network mask.
    ///
    /// If the interface does not have an IPv4 address, netmask is the 0 netmask
    /// (0.0.0.0).
    fuchsia.net.IpAddress netmask;
    /// netmask is addr's corresponding network's broadcast address.
    ///
    /// If the interface does not have an IPv4 address, broadaddr is the
    /// unspecified IPv4 address (0.0.0.0).
    fuchsia.net.IpAddress broadaddr;
    vector<fuchsia.net.Subnet> ipv6addrs;
    bytes hwaddr;
};

/// Flags for NetInterface.flags.
const uint32 NetInterfaceFlagUp = 0x01; // Set if the interface is up.
const uint32 NetInterfaceFlagDhcp = 0x02; // Set if DHCP is enabled.

struct RouteTableEntry {
    fuchsia.net.IpAddress destination;
    fuchsia.net.IpAddress netmask;
    fuchsia.net.IpAddress gateway;
    uint32 nicid;
};

/// New version that includes a metric value.
// TODO(NET-2078): Move this to NetInterface once Chromium stops using
// netstack.fidl.
struct RouteTableEntry2 {
    fuchsia.net.IpAddress destination;
    fuchsia.net.IpAddress netmask;
    fuchsia.net.IpAddress? gateway;
    uint32 nicid;
    uint32 metric;
};

struct SocketAddress {
    fuchsia.net.IpAddress addr;
    uint16 port;
};

[Discoverable]
protocol Netstack {
    /// Finds the port number from a given service name and protocol. [service] can be a
    /// number like "42", or a service name like "http". If [protocol] is UNSPECIFIED,
    /// the service is checked for TCP first, then UDP.
    GetPortForService(string service, Protocol protocol) -> (uint16 port);

    /// Finds the IP address for a given host name and port. This may issue network
    /// requests via DNS to look up domain names. E.g.
    /// GetAddress("example.com", 80) -> [{142.42.42.1}]
    GetAddress(string address, uint16 port) -> (vector<SocketAddress> addresses, NetErr err);

    /// Returns the list of registered network interfaces.
    GetInterfaces() -> (vector<NetInterface> interfaces);
    GetInterfaces2() -> (vector<NetInterface2> interfaces);

    // DEPRECATED: see devicesettings.fidl
    // Returns the netstack's node name.
    // 5: GetNodeName() -> (string node_name);

    /// Returns current route table.
    GetRouteTable() -> (vector<RouteTableEntry> rt);
    GetRouteTable2() -> (vector<RouteTableEntry2> rt);

    /// Sets the status (up or down) for the interface with the given nicid.
    SetInterfaceStatus(uint32 nicid, bool enabled);

    /// Sets the address for the interface with the given nicid.
    /// Masks off addr.PrefixLen bits from addr.Addr to set the subnet.
    SetInterfaceAddress(uint32 nicid, fuchsia.net.IpAddress addr, uint8 prefixLen) -> (NetErr result);

    /// Removes the address for the interface with the given nicid.
    /// Masks off addr.PrefixLen bits from addr.Addr to set the subnet.
    RemoveInterfaceAddress(uint32 nicid, fuchsia.net.IpAddress addr, uint8 prefixLen) -> (NetErr result);

    /// Sets the route metric for the interface with the given nicid.
    SetInterfaceMetric(uint32 nicid, uint32 metric) -> (NetErr result);

    /// Creates a bridge and returns the newly created nicid or an
    /// error if the creation fails.
    BridgeInterfaces(vector<uint32> nicids) -> (NetErr result, uint32 nicid);

    AddEthernetDevice(string topological_path, InterfaceConfig interfaceConfig, fuchsia.hardware.ethernet.Device device) -> (uint32 nicid);

    // TODO(stijlist): re-home this protocol. GetDhcpClient should be a member
    // of the protocol that eventually owns network interface management
    // in general.
    GetDhcpClient(uint32 nicid, request<fuchsia.net.dhcp.Client> client) -> () error zx.status;

    /// Begin a route transaction for atomically getting and setting the route
    /// table.  Returns true if a transaction can be started.
    StartRouteTableTransaction(request<RouteTableTransaction> routeTableTransaction) -> (zx.status status);

    -> OnInterfacesChanged(vector<NetInterface> interfaces);
};

[Discoverable]
protocol ResolverAdmin {
    SetNameServers(vector<fuchsia.net.IpAddress> servers);
};

[Discoverable]
protocol RouteTableTransaction {
    AddRoute(RouteTableEntry2 r) -> (zx.status status);
    DelRoute(RouteTableEntry2 r) -> (zx.status status);
};
