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

// Immutable packet filters. Given pointers to packet header data, a filter is an object
// that can perform a match operation on fields in the headers and outputs a verdict on
// whether the packet should be accepted.
//
// `FilterBase` is the abstract class providing the interface of a filter.
// Concrete subclasses of `FilterBase` are filters working at different network layers, or
// compositions of one or more filters. Data fields should be provided in network byte order.
//
// Filters cannot be mutated once created. In practical use, instances of `FilterBase` and its
// subclasses should always be wrapped in a `FilterPtr` for memory management.
// A complete filter is one or more sub-filters joined together as nodes in a filter tree,
// connected by logical negation, conjunction and/or disjunction operations.

#ifndef SRC_CONNECTIVITY_NETWORK_NETDUMP_FILTER_H_
#define SRC_CONNECTIVITY_NETWORK_NETDUMP_FILTER_H_

#include <algorithm>
#include <functional>
#include <memory>
#include <utility>
#include <variant>
#include <vector>

#include "filter_constants.h"

namespace netdump {

class Packet {
 public:
  Packet() { reset(); }

  void reset() {
    frame_length = 0;
    frame = nullptr;
    ip = nullptr;
    transport = nullptr;
  }

  // Populate the header pointers with Ethernet frame header starting at `buffer`, with length
  // checks to ensure the complete headers are present. If the headers are incomplete or
  // unrecognized, the corresponding pointers are set to null.
  void populate(const void* buffer, uint16_t length);

  // `frame_len` is supplied by the client user of filter, so it is expected in host byte order.
  uint16_t frame_length;
  const struct ethhdr* frame;
  union {
    const struct iphdr* ip;  // For both IPv4 and IPv6.
    const struct ip6_hdr* ipv6;
  };
  union {
    const struct tcphdr* tcp;
    const struct udphdr* udp;
    const void* transport;
  };
};

class FilterBase;
using FilterPtr = std::unique_ptr<FilterBase>;

class FilterBase {
 public:
  // Returns `true` if the packet matches the internal filter specification.
  // The storage and type of that specification is up to the particular filter subclasses.
  // If the a relevant pointer in `packet` is null, `false` is returned if the
  // filter specifies a basic match on a header field.
  virtual bool match(const Packet& packet) = 0;

  virtual ~FilterBase() = default;
  FilterBase(const FilterBase& other) = delete;
  FilterBase& operator=(const FilterBase& other) = delete;

 protected:
  FilterBase() = default;
};

// Filter on length of frame, including frame headers.
class FrameLengthFilter : public FilterBase {
 public:
  // If `comp` is `LEQ`, the filter matches if frame length is less than or
  // equal to `frame_len`. Otherwise the filter matches if it is greater than or
  // equal.
  explicit FrameLengthFilter(uint16_t frame_len, LengthComparator comp);

  bool match(const Packet& packet) override;

  FrameLengthFilter(const FrameLengthFilter& other) = delete;
  FrameLengthFilter& operator=(const FrameLengthFilter& other) = delete;

 private:
  std::function<bool(const Packet&)> match_fn_;
};

// Filter on Ethernet frames.
class EthFilter : public FilterBase {
 public:
  // A filter matching on Ethertype field in Ethernet II only.
  explicit EthFilter(uint16_t ethtype) : spec_(Spec(ethtype)) {}

  using MacAddress = std::array<uint8_t, ETH_ALEN>;
  // A filter matching on MAC address.
  EthFilter(const MacAddress& mac, AddressFieldType type);

  bool match(const Packet& packet) override;

  EthFilter(const EthFilter& other) = delete;
  EthFilter& operator=(const EthFilter& other) = delete;

 private:
  using EthType = uint16_t;
  using Address = struct {
    MacAddress mac;
    AddressFieldType type;
  };
  using Spec = std::variant<EthType, Address>;
  Spec spec_;
};

// Filter on IP headers. An IP version must be specified, which is always checked in the packet.
// The filter may additionally match on another field, which can be one of packet length,
// transport protocol, or IPv4 or IPv6 host address.
class IpFilter : public FilterBase {
 public:
  // A filter matching on IP version only.
  explicit IpFilter(uint8_t version);

  // A filter matching on IP packet length. If `comp` is `LEQ`,
  // the filter matches if packet length is less than or equal to `ip_pkt_len`.
  // Otherwise the filter matches if it is greater than or equal.
  explicit IpFilter(uint8_t version, uint16_t ip_pkt_len, LengthComparator comp);

  // A filter matching on transport protocol.
  explicit IpFilter(uint8_t version, uint8_t protocol);

  // A filter matching on IPv4 address. `ipv4_addr` should be in network byte order.
  explicit IpFilter(uint32_t ipv4_addr, AddressFieldType type);

  using IPv6Address = std::array<uint8_t, IP6_ADDR_LEN>;
  // A filter matching on IPv6 address. `ipv6_addr` should be in network byte order.
  IpFilter(const IPv6Address& ipv6_addr, AddressFieldType type);

  bool match(const Packet& packet) override;

  IpFilter(const IpFilter& other) = delete;
  IpFilter& operator=(const IpFilter& other) = delete;

 private:
  const uint8_t version_;
  std::function<bool(const Packet&)> match_fn_;
};

// Filter on transport layer ports.
class PortFilter : public FilterBase {
 public:
  explicit PortFilter(std::vector<PortRange> ports, PortFieldType type);

  bool match(const Packet& packet) override;

  PortFilter(const PortFilter& other) = delete;
  PortFilter& operator=(const PortFilter& other) = delete;

 private:
  // TODO(xianglong): Replace with e.g. interval tree guaranteeing logarithmic lookup.
  std::vector<PortRange> ports_;
  const PortFieldType type_;

  bool match_ports(uint16_t src_port, uint16_t dst_port);
};

// Logical `NOT` (negation) of the contained filter.
class NegFilter : public FilterBase {
 public:
  explicit NegFilter(FilterPtr filter) : filter_(std::move(filter)) {}

  bool match(const Packet& packet) override;

  NegFilter(const NegFilter& other) = delete;
  NegFilter& operator=(const NegFilter& other) = delete;

 private:
  const FilterPtr filter_;
};

// Logical `AND` (conjunction) of two contained filters.
class ConjFilter : public FilterBase {
 public:
  ConjFilter(FilterPtr left, FilterPtr right) : left_(std::move(left)), right_(std::move(right)) {}

  bool match(const Packet& packet) override;

  ConjFilter(const ConjFilter& other) = delete;
  ConjFilter& operator=(const ConjFilter& other) = delete;

 private:
  const FilterPtr left_;
  const FilterPtr right_;
};

// Logical `OR` (disjunction) of two contained filters.
class DisjFilter : public FilterBase {
 public:
  DisjFilter(FilterPtr left, FilterPtr right) : left_(std::move(left)), right_(std::move(right)) {}

  bool match(const Packet& packet) override;

  DisjFilter(const DisjFilter& other) = delete;
  DisjFilter& operator=(const DisjFilter& other) = delete;

 private:
  const FilterPtr left_;
  const FilterPtr right_;
};

}  // namespace netdump

#endif  // SRC_CONNECTIVITY_NETWORK_NETDUMP_FILTER_H_
