blob: 2cbddeba9fd1f571f13478a34f6c0d3624a8c8bb [file] [log] [blame]
// Copyright 2025 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.
/// A collection of fundamental matchers for network objects.
@available(added=HEAD)
library fuchsia.net.matchers;
using fuchsia.net;
using fuchsia.net.interfaces;
/// A matcher for network interfaces.
type Interface = flexible union {
/// The ID of the interface as assigned by the netstack.
// TODO(https://fxbug.dev/351015513): We may want to make interface ID
// matchers referency for routes matchers (ensuring they reference an
// installed interface and removing any matchers when the interface is
// removed). We do *not* want this for filtering.
1: id fuchsia.net.InterfaceId;
/// The name of the interface.
2: name fuchsia.net.interfaces.Name;
/// The port class of the interface.
3: port_class fuchsia.net.interfaces.PortClass;
};
/// A matcher for network interfaces where it might be unbound (`BindToDevice`
/// has not been called).
type BoundInterface = flexible union {
/// Matches iff the socket is bound to a matching interface (see
/// [`Interface`] for matching criteria).
1: bound Interface;
/// Matches iff the outgoing traffic is not bound to a device.
2: unbound struct {};
};
/// A matcher for IP addresses.
type Address = struct {
matcher @generated_name("AddressMatcherType") flexible union {
/// The subnet that must contain the IP address in the packet header in
/// order for it to match.
1: subnet fuchsia.net.Subnet;
/// The range of addresses that must include the IP address in the
/// packet header in order for it to match.
///
/// The endpoints of the range must be in the same address family, and
/// `start` must <= `end`. (Comparisons are performed on the numerical
/// big-endian representation of the IP address.)
2: range @generated_name("AddressRange") struct {
/// The inclusive start of the address range.
start fuchsia.net.IpAddress;
/// The inclusive end of the address range.
end fuchsia.net.IpAddress;
};
};
/// Whether to check for an "inverse" or "negative" match (in which case,
/// if the matcher criteria do *not* apply, it *is* considered a match, and
/// vice versa).
invert bool;
};
/// A matcher for transport-layer port numbers.
///
/// `start` must <= `end`.
type Port = struct {
/// The inclusive start of the port range.
start uint16;
/// The inclusive end of the port range.
end uint16;
/// Whether to check for an "inverse" or "negative" match.
invert bool;
};
/// A matcher for TCP packets.
type TcpPacket = table {
/// Matcher for the TCP source port.
1: src_port Port;
/// Matcher for the TCP destination port.
2: dst_port Port;
};
/// A matcher for UDP packets.
type UdpPacket = table {
/// Matcher for the UDP source port.
1: src_port Port;
/// Matcher for the UDP destination port.
2: dst_port Port;
};
/// A matcher for ICMPv4 packets.
type IcmpPacket = table {};
/// A matcher for ICMPv6 packets.
type Icmpv6Packet = table {};
/// A matcher for transport-layer information in packets.
type PacketTransportProtocol = flexible union {
1: tcp TcpPacket;
2: udp UdpPacket;
3: icmp IcmpPacket;
4: icmpv6 Icmpv6Packet;
};
/// Matches the mark value of a packet or socket.
type Mark = flexible union {
/// This mark domain does not have a mark.
1: unmarked struct {};
2: marked struct {
/// Mask to apply before comparing to the range in `between`.
mask uint32;
/// The mark is between the given range.
between struct {
/// Start of the range, inclusive.
start uint32;
/// End of the range, inclusive.
end uint32;
};
/// Whether to check for an "inverse" or "negative" match.
///
/// The mask is applied as normal, but the value is checked for
/// inequality.
invert bool;
};
};
/// A matcher for a socket's cookie.
type SocketCookie = struct {
/// The cookie value to compare for equality.
cookie uint64;
/// Whether to check for an "inverse" or "negative" match.
invert bool;
};
/// An empty type for use in unions.
type Empty = struct {};
/// A matcher for TCP sockets.
type TcpSocket = flexible union {
/// Only matches against the transport protocol and nothing else.
1: empty Empty;
/// Match against the source port of TCP sockets.
2: src_port Port;
/// Match against the destination port of TCP sockets.
3: dst_port Port;
/// The TCP socket's state must be contained in the set of states. If unset,
/// matches all states, just as if it was fully set.
///
/// The constants are structured to correspond to the enum values of
/// fuchsia.net.tcp.States.
4: states @generated_name("TcpState") strict bits {
ESTABLISHED = 0b00000000001;
SYN_SENT = 0b00000000010;
SYN_RECV = 0b00000000100;
FIN_WAIT1 = 0b00000001000;
FIN_WAIT2 = 0b00000010000;
TIME_WAIT = 0b00000100000;
CLOSE = 0b00001000000;
CLOSE_WAIT = 0b00010000000;
LAST_ACK = 0b00100000000;
LISTEN = 0b01000000000;
CLOSING = 0b10000000000;
};
};
/// A matcher for UDP sockets.
type UdpSocket = flexible union {
/// Only matches against the transport protocol and nothing else.
1: empty Empty;
/// Match against the source port of UDP sockets.
2: src_port Port;
/// Match against the destination port of UDP sockets.
3: dst_port Port;
/// The UDP socket's state must be contained in the set of states.
///
/// If unset, matches all states, just as if it was fully set.
4: states @generated_name("UdpState") strict bits {
/// The UDP socket is bound but not connected.
BOUND = 0b01;
/// The UDP socket is explicitly connected.
CONNECTED = 0b10;
};
};
/// A matcher for transport-layer fields of a socket.
type SocketTransportProtocol = flexible union {
/// Matches against TCP fields.
1: tcp TcpSocket;
/// Matches against UDP fields.
2: udp UdpSocket;
};