#pragma once

#include <sys/types.h>
#include <sys/socket.h>
#if !defined(LINUX)
#include <netdb.h>
#else // LINUX
#include <netinet/ether.h> // Used for raw sockets
#include <net/ethernet.h> // Used for raw sockets
#include <linux/if_packet.h> // Used for raw sockets
#endif // LINUX
#include <netinet/in.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <net/if.h> // Used for raw sockets

#include "TLayer.hh"
#include "Params.hh"

class OCTETSTRING;
class PORT;

class RawSocketLayer : public Layer, public PORT {
  Params _params;
  int _socket;
  std::string _time_key;
  struct ifreq _if_interface;
  struct ifreq _if_mac_addr;
  std::vector<unsigned char> _mac_src;
  std::vector<unsigned char> _mac_bc;
  std::vector<unsigned char> _eth_type;

public:
  RawSocketLayer(const std::string& p_type, const std::string& param);
  virtual ~RawSocketLayer();

  virtual void sendData(OCTETSTRING& data, Params& params);
  virtual void receiveData(OCTETSTRING& data, Params& info);
  
  void Handle_Fd_Event_Readable(int fd);
}; // End of class RawSocketLayer

