// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_SHIMS_NETFILTER_QUEUE_PROCESSOR_H_
#define SHILL_SHIMS_NETFILTER_QUEUE_PROCESSOR_H_

#include <inttypes.h>
#include <sys/time.h>

#include <deque>
#include <memory>
#include <string>

#include <base/macros.h>

struct nfgenmsg;
struct nfq_data;
struct nfq_handle;
struct nfq_q_handle;

namespace shill {

namespace shims {

class NetfilterQueueProcessor {
 public:
  NetfilterQueueProcessor(int input_queue, int output_queue);
  virtual ~NetfilterQueueProcessor();

  // Run the main loop of the processor.
  void Run();

  // Initialize state and install the processor so it accepts messages
  // from the kernel.
  bool Start();

  // Uninitialize state.
  void Stop();

 private:
  friend class NetfilterQueueProcessorTest;

  class Packet {
   public:
    Packet();
    virtual ~Packet();

    // Inputs a netfilter data packet and reads meta-information (packet id)
    // and attempts to decode the payload as a UDP packet.  Returns true if
    // the meta-information is decoded, regardless of whether the payload
    // was decoded.
    bool ParseNetfilterData(struct nfq_data* netfilter_data);

    // Getters.
    int in_device() const { return in_device_; }
    int out_device() const { return out_device_; }
    bool is_udp() const { return is_udp_; }
    uint32_t packet_id() const { return packet_id_; }
    uint32_t source_ip() const { return source_ip_; }
    uint32_t destination_ip() const { return destination_ip_; }
    uint16_t source_port() const { return source_port_; }
    uint16_t destination_port() const { return destination_port_; }

   private:
    friend class NetfilterQueueProcessorTest;

    bool ParsePayloadUDPData(const unsigned char* payload, size_t payload_len);

    // Setter only used in unit tests.
    void SetValues(int in_device,
                   int out_device,
                   bool is_udp,
                   uint32_t packet_id,
                   uint32_t source_ip,
                   uint32_t destination_ip,
                   uint16_t source_port,
                   uint16_t destination_port);

    uint32_t packet_id_;
    int in_device_;
    int out_device_;
    bool is_udp_;
    uint32_t source_ip_;
    uint32_t destination_ip_;
    uint16_t source_port_;
    uint16_t destination_port_;

    DISALLOW_COPY_AND_ASSIGN(Packet);
  };

  struct ListenerEntry {
    ListenerEntry()
        : last_transmission(0),
          port(0),
          device_index(0),
          address(0),
          netmask(0),
          destination(0) {}
    ListenerEntry(time_t last_transmission_in,
                  uint16_t port_in,
                  int device_index_in,
                  uint32_t address_in,
                  uint32_t netmask_in,
                  uint32_t destination_in)
        : last_transmission(last_transmission_in),
          port(port_in),
          device_index(device_index_in),
          address(address_in),
          netmask(netmask_in),
          destination(destination_in) {}
    time_t last_transmission;
    uint16_t port;
    int device_index;
    uint32_t address;
    uint32_t netmask;
    uint32_t destination;
  };

  using ListenerEntryPtr = std::shared_ptr<ListenerEntry>;

  // Called by the netlink_queue code when a packet arrives for the
  // input queue.
  static int InputQueueCallback(struct nfq_q_handle* queue_handle,
                                struct nfgenmsg* generic_message,
                                struct nfq_data* netfilter_data,
                                void* private_data);

  // Called by the netlink_queue code when a packet arrives for the
  // output queue.
  static int OutputQueueCallback(struct nfq_q_handle* queue_handle,
                                 struct nfgenmsg* generic_message,
                                 struct nfq_data* netfilter_data,
                                 void* private_data);

  // Return the netmask associated with |device_index|.
  static uint32_t GetNetmaskForDevice(int device_index);

  // Expire listener that are no longer valid |now|.
  void ExpireListeners(time_t now);

  // Find a listener entry with port |port|, device index |device_index|
  // and local address |address|.
  std::deque<ListenerEntryPtr>::iterator FindListener(
      uint16_t port, int device_index, uint32_t address);

  // Find a listener entry with port |port| and device index |device_index|
  // which transmitted to multicast destination |destination|.
  std::deque<ListenerEntryPtr>::iterator FindDestination(
      uint16_t port, int device_index, uint32_t destination);

  // Returns true if incoming packet |packet| should be allowed to pass.
  bool IsIncomingPacketAllowed(const Packet& packet, time_t now);

  // Log the transmission of an outgoing packet.
  void LogOutgoingPacket(const Packet& packet, time_t now);

  static std::string AddressAndPortToString(uint32_t ip, uint16_t port);

  // Size of the packet buffer passed to the netlink queue library.
  static const int kBufferSize;
  // The number of seconds after which we should forget about a listener.
  static const int kExpirationIntervalSeconds;
  // Number of bytes in a single unit of IP header length.
  static const int kIPHeaderLengthUnitBytes;
  // The maximum expected value for the "header length" element of the IP
  // header, in units of kIPHeaderLengthUnitBytes bytes.
  static const int kMaxIPHeaderLength;
  // The maximum number of listeners that we keep track of.
  static const size_t kMaxListenerEntries;
  // Number of bytes of the network payload we are interested in seeing.
  static const int kPayloadCopySize;

  // Input and output queue numbers.
  int input_queue_;
  int output_queue_;

  // Pointer to a netfilter queue library instance.  A bare pointer is
  // necessary since this must be freed via nfq_close().
  struct nfq_handle* nfq_handle_;

  // Input and output queue handles.  A bare pointer is necessary since
  // this must be freed via nfq_destroy_queue().
  struct nfq_q_handle* input_queue_handle_;
  struct nfq_q_handle* output_queue_handle_;

  // A list of records of listening sockets.
  std::deque<ListenerEntryPtr> listeners_;

  DISALLOW_COPY_AND_ASSIGN(NetfilterQueueProcessor);
};

}  // namespace shims

}  // namespace shill

#endif  // SHILL_SHIMS_NETFILTER_QUEUE_PROCESSOR_H_

