blob: a053af9478af314d58564ba077464933b7e8a498 [file] [log] [blame]
// 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/42165832): 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/42165832): 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/42056856): 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/42166513): 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;
};