// Copyright 2021 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.
@available(added=11)
library fuchsia.posix.socket.packet;

using fuchsia.net;
using fuchsia.posix;
using fuchsia.posix.socket;
using zx;

type Empty = struct {};

/// A kind of packet socket.
type Kind = strict enum {
    /// A packet socket that operates with network-layer packets.
    NETWORK = 1;

    /// A packet socket that operates with link-layer packets.
    ///
    /// Packets are passed unmodified between the wire and client when the
    /// packet socket is of this kind.
    LINK = 2;
};

/// A network-layer protocol (above link-layer).
///
/// Values are defined by
/// https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml.
// Values of this type are passthrough as the value does not need to be
// interpreted by the server. This is so that packet sockets may be used to
// send/receive packets for a network protocol that the server does not
// implement.
alias Protocol = uint16;

/// The protocol association for a packet socket.
type ProtocolAssociation = strict union {
    /// An association with all protocols.
    1: all Empty;

    /// An association with a protocol.
    2: specified Protocol;
};

/// The type of a hardware.
// `ARPHDR_*` values from
// `//zircon/third_party/ulib/musl/include/net/if_arp.h`.
type HardwareType = strict enum {
    /// Hardware that operates only at the network layer; a pure L3 interface.
    ///
    /// Hardware of this type have no L2 headers/addressing.
    // Equivalent to ARPHDR_NONE.
    NETWORK_ONLY = 1;

    /// Hardware that operates on ethernet-based links.
    // Equivalent to ARPHDR_ETHER.
    ETHERNET = 2;

    /// Hardware that loops back packets.
    // Equivalent to ARPHDR_LOOPBACK.
    LOOPBACK = 3;
};

/// The type of a packet.
// `PACKET_*` values from
// `//zircon/third_party/ulib/musl/include/netpacket/packet.h`.
type PacketType = strict enum {
    /// A packet that arrived at its destination.
    HOST = 1;

    /// A packet that was broadcasted.
    BROADCAST = 2;

    /// A packet that was multicasted.
    MULTICAST = 3;

    /// A packet that arrived at a host that isn't its destination.
    OTHER_HOST = 4;

    /// A packet that is being sent on a local interface, regardless of how it
    /// is being sent (unicasted, multicasted, broadcasted).
    OUTGOING = 5;

    // Intentionally do not include PACKET_LOOPBACK or PACKET_FASTROUTE as those
    // are not exposed to applications:
    // https://github.com/torvalds/linux/blob/73bfd370/include/uapi/linux/if_packet.h#L29.
};

/// A hardware address.
// TODO(https://fxbug.dev/84984): Move this to fuchsia.net.* once we support
// querying an interface's L2 properties.
type HardwareAddress = flexible union {
    /// Indicates that the hardware does not support link-layer addressing.
    1: none Empty;

    /// An EUI-48 based address.
    2: eui48 fuchsia.net.MacAddress;
};

/// An interface's properties.
// TODO(https://fxbug.dev/84984): Move this to fuchsia.net.* once we support
// querying an interface's L2 properties.
type InterfaceProperties = struct {
    /// The interface's ID.
    id fuchsia.net.InterfaceId;

    /// The interface's hardware address.
    addr HardwareAddress;

    /// The interface's hardware type.
    type HardwareType;
};

/// Information about a packet.
type PacketInfo = struct {
    protocol Protocol;
    interface_id fuchsia.net.InterfaceId;
    addr HardwareAddress;
};

// TODO(https://fxbug.dev/105608): Use a generated constant.
const SOCKET_PROTOCOL_NAME string = "fuchsia.posix.socket.packet/Socket";

/// A packet socket.
///
/// This interface is essentially POSIX.
///
/// All methods on this type are nonblocking; their exact behaviors match their
/// Linux counterparts.
///
/// *Warning:* This protocol is not yet ready for direct use by clients.
/// Instead, clients should use the BSD sockets API to interact with sockets.
/// We plan to change this protocol substantially and clients that couple
/// directly to this protocol will make those changes more difficult.
// TODO(https://fxbug.dev/85597): Implement RFC-0109 for packet sockets.
closed protocol Socket {
    compose fuchsia.posix.socket.BaseSocket;

    strict Describe() -> (resource table {
        /// Signals additional information about the state of the socket such as
        /// readiness or shutdown-ness.
        1: event zx.Handle:EVENTPAIR;
    });

    /// Bind the socket to a protocol and/or interface.
    ///
    /// + request `protocol` the socket's new protocol association.
    /// + request `bound_interface_id` the socket's new interface binding.
    strict Bind(struct {
        protocol ProtocolAssociation:optional;
        bound_interface_id strict union {
            1: all Empty;
            2: specified fuchsia.net.InterfaceId;
        };
    }) -> () error fuchsia.posix.Errno;

    /// Returns the the socket's properties.
    ///
    /// - response `kind` the socket's `Kind`.
    /// - response `protocol` the socket's protocol association, if associated.
    /// - response `bound_interface` properties of the socket's interface
    ///   binding.
    strict GetInfo() -> (struct {
        kind Kind;
        protocol ProtocolAssociation:optional;
        bound_interface strict union {
            1: all Empty;
            2: specified InterfaceProperties;
        };
    }) error fuchsia.posix.Errno;

    /// Receives a message from the socket.
    ///
    /// + request `want_packet_info` request information about the packet to be
    ///   returned.
    /// + request `data_len` the maximum allowed length of the response data
    ///   buffer.
    /// + request `want_control` request ancillary data to be returned.
    /// + request `flags` flags for the receive request.
    /// - response `packet_info` information about the packet, if requested.
    /// - response `data` the message.
    /// - response `control` control messages, if requested.
    /// - response `truncated` indicates whether or not the returned message
    ///   was truncated.
    strict RecvMsg(struct {
        want_packet_info bool;
        data_len uint32;
        want_control bool;
        flags fuchsia.posix.socket.RecvMsgFlags;
    }) -> (struct {
        packet_info box<@generated_name("RecvPacketInfo") struct {
            packet_info PacketInfo;
            packet_type PacketType;
            interface_type HardwareType;
        }>;
        data vector<uint8>:MAX;
        control @generated_name("RecvControlData") table {
            /// Socket level ancillary data.
            1: socket fuchsia.posix.socket.SocketRecvControlData;
        };
        truncated uint32;
    }) error fuchsia.posix.Errno;

    /// Sends a message on the socket.
    ///
    /// + request `packet_info` information about the packet.
    /// + request `data` the message.
    /// + request `control` ancillary data.
    /// + request `flags` flags for the send request.
    strict SendMsg(struct {
        packet_info box<PacketInfo>;
        data vector<uint8>:MAX;
        control @generated_name("SendControlData") table {
            /// Socket level ancillary data.
            1: socket fuchsia.posix.socket.SocketSendControlData;
        };
        flags fuchsia.posix.socket.SendMsgFlags;
    }) -> () error fuchsia.posix.Errno;
};

/// A packet socket provider.
@discoverable
closed protocol Provider {
    /// Requests a packet socket.
    ///
    /// + request `kind` the kind of packet socket to create.
    /// - response `socket` the packet socket.
    strict Socket(struct {
        kind Kind;
    }) -> (resource struct {
        socket client_end:Socket;
    }) error fuchsia.posix.Errno;
};
