// Copyright (c) 2013 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 <tr1/memory>

#include <base/basictypes.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) {}
    ListenerEntry(time_t last_transmission_in,
                  uint16_t port_in,
                  int device_index_in,
                  uint32_t address_in,
                  uint32_t netmask_in)
        : last_transmission(last_transmission_in),
          port(port_in),
          device_index(device_index_in),
          address(address_in),
          netmask(netmask_in) {}
    time_t last_transmission;
    uint16_t port;
    int device_index;
    uint32_t address;
    uint32_t netmask;
  };

  typedef std::tr1::shared_ptr<ListenerEntry> ListenerEntryPtr;

  // 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| and device index |device_index|.
  std::deque<ListenerEntryPtr>::iterator FindListener(
      uint16_t port, int device_index, uint32_t address);

  // 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);

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

  // Input and output queue nubmers.
  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_

