Commit 1ed49b76 authored by garciay's avatar garciay
Browse files

Update for cygwin support

parent 70f69558
Loading
Loading
Loading
Loading
+106 −66
Original line number Original line Diff line number Diff line
@@ -4,27 +4,39 @@
#include <errno.h>
#include <errno.h>
#include <chrono>
#include <chrono>


#include <sys/ioctl.h>
 
#include "Port.hh"
#include "Port.hh"


#include "RawSocketLayer.hh"
#include "RawSocketLayer.hh"
#include "loggers.hh"
#include "loggers.hh"


RawSocketLayer::RawSocketLayer(const std::string& p_type, const std::string& param) : Layer(p_type), PORT(p_type.c_str()), _params(), _socket(-1), _time_key("RawSocketLayer::Handle_Fd_Event_Readable") {
RawSocketLayer::RawSocketLayer(const std::string& p_type, const std::string& param) : Layer(p_type), PORT(p_type.c_str()), _params(), _socket(-1), _time_key("RawSocketLayer::Handle_Fd_Event_Readable"), _if_interface{0}, _if_mac_addr{0}, _mac_src(), _mac_bc(), _eth_type() {
  loggers::get_instance().log(">>> RawSocketLayer::RawSocketLayer: %s, %s", to_string().c_str(), param.c_str());
  loggers::get_instance().log(">>> RawSocketLayer::RawSocketLayer: %s, %s", to_string().c_str(), param.c_str());
  memset(&_if_interface, 0x00, sizeof(struct ifreq));
  memset(&_if_mac_addr, 0x00, sizeof(struct ifreq));
  // Setup parameters
  // Setup parameters
  Params::convert(_params, param);
  Params::convert(_params, param);
  //_params.log();
  //_params.log();
  // Prepare capture processing
  // Prepare capture processing
  if ((_socket = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) {
  if ((_socket = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) {
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to create socket %d", errno);
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to create socket: %d", errno);
  }
  }


  Params::const_iterator it = _params.find(Params::nic);
  Params::const_iterator it = _params.find(Params::nic);
  if ((it != _params.end()) && !it->second.empty()) { // Use online capture
  if ((it != _params.end()) && !it->second.empty()) {
    snprintf(_if_interface.ifr_name, sizeof(_if_interface.ifr_name), it->second.c_str());
    // Get NIC idx from its name
    setsockopt(_socket, SOL_SOCKET, SO_BINDTODEVICE, (void *)&_if_interface, sizeof(struct ifreq));
    strcpy((char *)&_if_interface.ifr_name, it->second.c_str()); // FIXME check size IFNAMESIS
    if (ioctl(_socket, SIOCGIFINDEX, &_if_interface) < 0) {
      loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to fill if interface: %d", errno);
    }
    // Allow the socket to be reused
    int32_t sockopt;
    if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) < 0) {
      loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to set SO_REUSEADDR: %d", errno);
    }
    // Bind to the device to receive packet
    if (setsockopt(_socket, SOL_SOCKET, SO_BINDTODEVICE, (void *)&_if_interface, sizeof(struct ifreq)) < 0) {
      loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to bind socket: %d", errno);
    }
  } else {
  } else {
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to open device");
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: Failed to open device");
  }
  }
@@ -35,27 +47,20 @@ RawSocketLayer::RawSocketLayer(const std::string& p_type, const std::string& par
  if (it == _params.end()) { // Not found
  if (it == _params.end()) { // Not found
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: mac_src parameter not found, cannot continue");
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: mac_src parameter not found, cannot continue");
  } else {
  } else {
    /***
    _mac_src = str2oct(it->second.c_str());
    // Reject ITS messages sent by this component
  }
    filter = "not ether src " + _params[Params::mac_src]; 
    // Accept ITS broadcasted to this componenet
    filter += " and (ether dst " + _params[Params::mac_src];
    // Accept ITS broadcasted messages
  it = _params.find(Params::mac_bc);
  it = _params.find(Params::mac_bc);
    if ((it != _params.end()) && !it->second.empty()) {
  if (it == _params.end()) { // Not found
      filter += " or ether dst " + it->second + ")";
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: mac_bc parameter not found, cannot continue");
  } else {
  } else {
      filter += " or ether dst ffffffffffff) ";
    _mac_bc = str2oct(it->second.c_str());
  }
  }
    // Add user defined filter
  it = _params.find(Params::eth_type);
    it = _params.find(std::string("filter"));
  if (it == _params.end()) { // Not found
    if ((it != _params.end()) && !it->second.empty()) {
    loggers::get_instance().error("RawSocketLayer::RawSocketLayer: eth_type parameter not found, cannot continue");
      filter += _params["filter"];
  } else {
    } // else nothing to do
    _eth_type = str2oct(it->second.c_str());
    ***/
  }
  }
  // Log final PCAP filter
  loggers::get_instance().user("RawSocketLayer::RawSocketLayer: Filter: %s", filter.c_str());
  // Pass the device file handler to the polling procedure
  // Pass the device file handler to the polling procedure
  Handler_Add_Fd_Read(_socket); // Live capture
  Handler_Add_Fd_Read(_socket); // Live capture
} // End of ctor
} // End of ctor
@@ -70,24 +75,32 @@ RawSocketLayer::~RawSocketLayer() {


void RawSocketLayer::sendData(OCTETSTRING& data, Params& params) {
void RawSocketLayer::sendData(OCTETSTRING& data, Params& params) {
  loggers::get_instance().log_msg(">>> RawSocketLayer::sendData: ", data);
  loggers::get_instance().log_msg(">>> RawSocketLayer::sendData: ", data);
  /***
  
  if (_pcap_h != -1) { // Check if offline mode is used
  // Setup 'from' parameter
    if (pcap_sendpacket(_device, static_cast<const unsigned char *>(data), data.lengthof()) == -1) {
  struct sockaddr_ll sa = { 0 };
      loggers::get_instance().error("RawSocketLayer::sendData: Failed to send packet: %s", pcap_geterr(_device));
  sa.sll_family = AF_INET;
    }
  sa.sll_ifindex = _if_interface.ifr_ifindex;
  } else if (_sent_file != NULL) {
  sa.sll_halen = ETH_ALEN;
    struct pcap_pkthdr  hdr;
  struct ether_header *eh = (struct ether_header *)(static_cast<const unsigned char *>(data));
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
  // Setup the destination MAC address
    std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
  sa.sll_addr[0] = eh->ether_dhost[0];
    hdr.ts.tv_sec = ms.count() / 1000;
  sa.sll_addr[1] = eh->ether_dhost[1];
    hdr.ts.tv_usec = (ms.count() % 1000) * 1000;
  sa.sll_addr[2] = eh->ether_dhost[2];
    hdr.caplen = data.lengthof();
  sa.sll_addr[3] = eh->ether_dhost[3];
    hdr.len = hdr.caplen;
  sa.sll_addr[4] = eh->ether_dhost[4];
    pcap_dump((u_char *)_sent_file, &hdr, static_cast<const unsigned char *>(data));
  sa.sll_addr[5] = eh->ether_dhost[5];
  } else {
  // Do not owerwrite the source mac address
    loggers::get_instance().log("RawSocketLayer::sendData: Offline mode, operation was skipped");
  
  // Send the data
  int result;
  do {
    result = sendto(_socket, static_cast<const unsigned char *>(data), data.lengthof(), 0, (struct sockaddr *)&sa, sizeof(struct sockaddr_ll));
  } while ((result < 0) && (errno == EINTR));
  if (result < 0) {
    loggers::get_instance().error("RawSocketLayer::sendData: Failed to send: %d", errno);
  }
  }
  ***/

  return;
}
}


void RawSocketLayer::receiveData(OCTETSTRING& data, Params& params) {
void RawSocketLayer::receiveData(OCTETSTRING& data, Params& params) {
@@ -101,27 +114,54 @@ void RawSocketLayer::receiveData(OCTETSTRING& data, Params& params) {
void RawSocketLayer::Handle_Fd_Event_Readable(int fd) {
void RawSocketLayer::Handle_Fd_Event_Readable(int fd) {
  //loggers::get_instance().log(">>> RawSocketLayer::Handle_Fd_Event_Readable: %d", fd);
  //loggers::get_instance().log(">>> RawSocketLayer::Handle_Fd_Event_Readable: %d", fd);


  /***
  int result;
  struct pcap_pkthdr *pkt_header;
  std::vector<unsigned char> buffer(8182);
  const u_char *pkt_data;
  do {
  int result = pcap_next_ex(_device, &pkt_header, &pkt_data);
    result = ::recvfrom(_socket, static_cast<void *>(buffer.data()), buffer.size(), 0, NULL, NULL);
  if (result == 1) { // Succeed
  } while ((result < 0) && (errno == EINTR));
    if (pkt_header->caplen > 14) { // Reject too small packet
  if (result < 0) {
      //loggers::get_instance().log("RawSocketLayer::Handle_Fd_Event_Readable: %.6d - %d", pkt_header->ts.tv_usec, pkt_header->len);
    loggers::get_instance().error("RawSocketLayer::Handle_Fd_Event_Readable: Failed to receive: %d", errno);
      // Fill parameters from PCAP layer
    return;
  }
  buffer.resize(result);
  // Set receive time
  Params params;
  Params params;
      params.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(pkt_header->ts.tv_usec)));
  unsigned long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
  // Apply filtering
  if (result < 14) {
    // Skip it
    return;
  } else {
    // Check source
    if (std::equal(buffer.cbegin() + 6, buffer.cbegin() + 12, static_cast<const unsigned char *>(_mac_src))) { // Source is me, skip it
      // Skip it
      return;
    } else {
      // Check destination
      if (
          !std::equal(buffer.cbegin(), buffer.cbegin() + 5, static_cast<const unsigned char *>(_mac_src)) &&
          !std::equal(buffer.cbegin(), buffer.cbegin() + 5, static_cast<const unsigned char *>(_mac_bc))
          ) {
        // Skip it
        return;
      } else {
        // Check Ether type
        if (!std::equal(buffer.cbegin() + 12, buffer.cbegin() + 13, static_cast<const unsigned char *>(_eth_type))) {
          // Skip it
          return;
        } else { 
          // Process the packet at this layer
          // Process the packet at this layer
      OCTETSTRING os(pkt_header->caplen, pkt_data);
          params.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(ms)));
      //loggers::get_instance().log_to_hexa("RawSocketLayer::Handle_Fd_Event_Readable: ", os);
          OCTETSTRING os(buffer.size(), buffer.data());
      // TODO Case of caplen != len !!!
          loggers::get_instance().log_to_hexa("RawSocketLayer::Handle_Fd_Event_Readable: ", os);
          float duration;
          float duration;
          loggers::get_instance().set_start_time(_time_key);
          loggers::get_instance().set_start_time(_time_key);
          this->receiveData(os, params); // TODO Check execution time for decoding operation
          this->receiveData(os, params); // TODO Check execution time for decoding operation
          loggers::get_instance().set_stop_time(_time_key, duration);
          loggers::get_instance().set_stop_time(_time_key, duration);
        }
        }
  } // else, skip the packet
      }
  ***/
    }
  }
}
}


class RawSocketFactory: public LayerFactory {
class RawSocketFactory: public LayerFactory {
+10 −1
Original line number Original line Diff line number Diff line
@@ -2,18 +2,24 @@


#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#if (OSTYPE == linux)
#include <netinet/ether.h> // Used for raw sockets
#include <netinet/ether.h> // Used for raw sockets
#else
#endif
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <net/if.h> // Used for raw sockets
#include <net/if.h> // Used for raw sockets
#if (OSTYPE == linux)
#include <net/ethernet.h> // Used for raw sockets
#include <net/ethernet.h> // Used for raw sockets

#include <linux/if_packet.h> // Used for raw sockets
#include <linux/if_packet.h> // Used for raw sockets
#else
#endif


#include "Layer.hh"
#include "Layer.hh"
#include "Params.hh"
#include "Params.hh"


class OCTETSTRING;
class PORT;
class PORT;


class RawSocketLayer : public Layer, public PORT {
class RawSocketLayer : public Layer, public PORT {
@@ -22,6 +28,9 @@ class RawSocketLayer : public Layer, public PORT {
  std::string _time_key;
  std::string _time_key;
  struct ifreq _if_interface;
  struct ifreq _if_interface;
  struct ifreq _if_mac_addr;
  struct ifreq _if_mac_addr;
  OCTETSTRING _mac_src;
  OCTETSTRING _mac_bc;
  OCTETSTRING _eth_type;


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