| // 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. |
| library fuchsia.posix.socket.packet; |
| |
| using fuchsia.net; |
| using fuchsia.posix; |
| using fuchsia.posix.socket; |
| |
| 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.interface_id; |
| |
| /// 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.interface_id; |
| addr HardwareAddress; |
| }; |
| |
| /// 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. |
| protocol Socket { |
| compose fuchsia.posix.socket.BaseSocket; |
| |
| /// 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. |
| Bind(struct { |
| protocol ProtocolAssociation:optional; |
| bound_interface_id strict union { |
| 1: all Empty; |
| 2: specified fuchsia.net.interface_id; |
| }; |
| }) -> (struct {}) 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. |
| 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. |
| 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 bytes; |
| 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. |
| SendMsg(struct { |
| packet_info box<PacketInfo>; |
| data bytes:MAX; |
| control @generated_name("SendControlData") table { |
| /// Socket level ancillary data. |
| 1: socket fuchsia.posix.socket.SocketSendControlData; |
| }; |
| flags fuchsia.posix.socket.SendMsgFlags; |
| }) -> (struct {}) error fuchsia.posix.Errno; |
| }; |
| |
| /// A packet socket provider. |
| @discoverable |
| protocol Provider { |
| /// Requests a packet socket. |
| /// |
| /// + request `kind` the kind of packet socket to create. |
| /// - response `socket` the packet socket. |
| Socket(struct { |
| kind Kind; |
| }) -> (resource struct { |
| socket client_end:Socket; |
| }) error fuchsia.posix.Errno; |
| }; |