Commit 2ffb2ebc authored by garciay's avatar garciay
Browse files

Layers ongoing

parent 1707a285
......@@ -10,8 +10,8 @@ class BITSTRING;
template<typename TPDUEnc, typename TPDUDec> class Codec
{
public:
Codec() { loggers::loggers::log("Codec::Codec"); };
virtual ~Codec() { loggers::loggers::log("Codec::~Codec"); };
Codec() { loggers::get_instance().log("Codec::Codec"); };
virtual ~Codec() { loggers::get_instance().log("Codec::~Codec"); };
virtual int encode(const TPDUEnc& msg, OCTETSTRING& data) = 0;
virtual int decode(const OCTETSTRING& data, TPDUDec& msg) = 0;
};
......
......@@ -17,31 +17,31 @@ class Layer {
protected:
std::string type;
public:
Layer() : upperLayers(), lowerLayers(), type(std::string("")) { loggers::loggers::log("Layer::Layer (D)"); };
Layer(const std::string& p_type) : upperLayers(), lowerLayers(), type(std::string(p_type.begin(), p_type.end())) { loggers::loggers::log("Layer::Layer"); };
Layer() : upperLayers(), lowerLayers(), type(std::string("")) { loggers::get_instance().log("Layer::Layer (D)"); };
Layer(const std::string& p_type) : upperLayers(), lowerLayers(), type(std::string(p_type.begin(), p_type.end())) { loggers::get_instance().log("Layer::Layer"); };
virtual ~Layer() { upperLayers.clear(); lowerLayers.clear(); };
void deleteLayer() { };
public:
inline void addUpperLayer(Layer* p_layer) {
//loggers::loggers::log(">>> Layer::addUpperLayer");
//loggers::get_instance().log(">>> Layer::addUpperLayer");
if (p_layer != NULL) {
loggers::loggers::log("Layer::addUpperLayer: %s is upper layer of %s", p_layer->to_string().c_str(), to_string().c_str());
loggers::get_instance().log("Layer::addUpperLayer: %s is upper layer of %s", p_layer->to_string().c_str(), to_string().c_str());
upperLayers.push_back(p_layer);
loggers::loggers::log(" Layer::addUpperLayer: %s is loweer layer of %s", to_string().c_str(), p_layer->to_string().c_str());
loggers::get_instance().log(" Layer::addUpperLayer: %s is lower layer of %s", to_string().c_str(), p_layer->to_string().c_str());
p_layer->lowerLayers.push_back(this);
};
};
void removeUpperLayer(Layer* p_layer) { };
virtual void sendData(const OCTETSTRING& data, const Params& params) {};
virtual void receiveData(OCTETSTRING& data, Params& params) {};
virtual void sendData(OCTETSTRING& data, Params& params) { loggers::get_instance().log("Layer::sendData"); };
virtual void receiveData(OCTETSTRING& data, Params& params) { loggers::get_instance().log("Layer::receiveData"); }
inline const std::string& to_string() const { return type; };
protected:
inline void toAllLayers(std::vector<Layer*>&layers, OCTETSTRING& data, Params& params) {
//loggers::loggers::log_msg(">>> Layer::toAllLayer: ", data);
loggers::loggers::log(">>> Layer::toAllLayer: %d", layers.size());
//loggers::get_instance().log_msg(">>> Layer::toAllLayer: ", data);
loggers::get_instance().log(">>> Layer::toAllLayer: %d", layers.size());
for (std::vector<Layer*>::const_iterator it = layers.cbegin(); it != layers.cend(); ++it) {
Layer * p = *it;
p->receiveData(data, params); // FIXME BUG I
......@@ -50,18 +50,20 @@ protected:
//inline void toAllUpperLayers(OCTETSTRING& data, Params& params) { toAllLayers(upperLayers, data, params); } // TODO Useless??
//inline void toAllLowerLayers(OCTETSTRING& data, Params& params) { toAllLayers(lowerLayers, data, params); } // TODO Useless??
inline void receiveToAllLayers(OCTETSTRING& data, Params& params) {
//loggers::loggers::log_msg(">>> Layer::receiveToAllLayers: ", data);
loggers::loggers::log(">>> Layer::receiveToAllLayers: %d", upperLayers.size());
//loggers::get_instance().log_msg(">>> Layer::receiveToAllLayers: ", data);
loggers::get_instance().log(">>> Layer::receiveToAllLayers: %d", upperLayers.size());
for (std::vector<Layer*>::const_iterator it = upperLayers.cbegin(); it != upperLayers.cend(); ++it) {
Layer * p = *it;
loggers::get_instance().log("Layer::receiveToAllLayers: call Layer::receiveData for %s", p->to_string().c_str());
p->receiveData(data, params);
} // End of 'for' statement
};
inline void sendToAllLayers(OCTETSTRING& data, Params& params) {
//loggers::loggers::log_msg(">>> Layer::sendToAllLayers: ", data);
loggers::loggers::log(">>> Layer::sendToAllLayers: %d", lowerLayers.size());
//loggers::get_instance().log_msg(">>> Layer::sendToAllLayers: ", data);
loggers::get_instance().log(">>> Layer::sendToAllLayers: %d", lowerLayers.size());
for (std::vector<Layer*>::const_iterator it = lowerLayers.cbegin(); it != lowerLayers.cend(); ++it) {
Layer * p = *it;
loggers::get_instance().log("Layer::sendToAllLayers: call Layer::sendData for %s", p->to_string().c_str());
p->sendData(data, params);
} // End of 'for' statement
};
......@@ -75,14 +77,14 @@ template <typename TPort> class TLayer : public Layer {
TPortList upperPorts;
public:
TLayer() : Layer(), upperPorts() { loggers::loggers::log("TLayer::TLayer (D)"); };
TLayer(const std::string& p_type) : Layer(p_type), upperPorts() { loggers::loggers::log("TLayer::TLayer"); };
TLayer() : Layer(), upperPorts() { loggers::get_instance().log("TLayer::TLayer (D)"); };
TLayer(const std::string& p_type) : Layer(p_type), upperPorts() { loggers::get_instance().log("TLayer::TLayer"); };
void addUpperPort(TPort * p_port) { upperPorts.push_back(p_port); };
void removeUpperPort(TPort*);
protected:
template <typename TMessage> void toAllUpperPorts(const TMessage& m, const Params& param) {
loggers::loggers::log(">>> TLayer::toAllUpperPorts: %d", upperPorts.size());
loggers::get_instance().log(">>> TLayer::toAllUpperPorts: %d", upperPorts.size());
for(TPortListIterator it=upperPorts.begin(); it<upperPorts.end(); ++it){
(*it)->receiveMsg(m, param);
}
......
......@@ -2,12 +2,10 @@
#include <map>
#include "loggers.hh"
class Params : public std::map<std::string, std::string> {
public:
Params() : std::map<std::string, std::string>() { loggers::loggers::log("Params::Params"); };
Params(const Params& p_params) : std::map<std::string, std::string>(p_params.begin(), p_params.end()) { loggers::loggers::log("Params::Params (1)"); };
Params() : std::map<std::string, std::string>() {};
Params(const Params& p_params) : std::map<std::string, std::string>(p_params.begin(), p_params.end()) {};
virtual ~Params() {};
void log();
......
......@@ -29,7 +29,7 @@ void LayerStackBuilder::registerLayerFactory(const std::string & type, LayerFact
Layer* LayerStackBuilder::createLayerStack(const char* s)
{
loggers::loggers::log(">>> LayerStackBuilder::createLayerStack: %s", s);
loggers::get_instance().log(">>> LayerStackBuilder::createLayerStack: %s", s);
Layer * entry = NULL; // Initial layer (the first declared)
Layer * up = NULL; // Upper layer
......@@ -41,18 +41,18 @@ Layer* LayerStackBuilder::createLayerStack(const char* s)
std::sregex_iterator end = std::sregex_iterator();
for (std::sregex_iterator it = begin; it != end; ++it) {
std::smatch m = *it;
//loggers::loggers::log("LayerStackBuilder::createLayerStack: %d - %s - %s - %s - %s", m.size(), m[0].str().c_str(), m[1].str().c_str(), m[2].str().c_str(), m[3].str().c_str());
//loggers::get_instance().log("LayerStackBuilder::createLayerStack: %d - %s - %s - %s - %s", m.size(), m[0].str().c_str(), m[1].str().c_str(), m[2].str().c_str(), m[3].str().c_str());
LayerFactoryMap::iterator i =_fs.find(m[1].str());
if (i == _fs.end()) {
loggers::loggers::error("LayerStackBuilder::createLayerStack: %s: Unknown layer type", m[1].str().c_str());
loggers::get_instance().error("LayerStackBuilder::createLayerStack: %s: Unknown layer type", m[1].str().c_str());
}
loggers::loggers::log("LayerStackBuilder::createLayerStack: Create layer %s, %s", m[1].str().c_str(), m[3].str().c_str());
loggers::get_instance().log("LayerStackBuilder::createLayerStack: Create layer %s, %s", m[1].str().c_str(), m[3].str().c_str());
Layer * l = i->second->createLayer(m[1].str(), m[3].str());
if (NULL == l) {
loggers::loggers::error("LayerStackBuilder::createLayerStack: %s: Layer creation error", m[1].str().c_str());
loggers::get_instance().error("LayerStackBuilder::createLayerStack: %s: Layer creation error", m[1].str().c_str());
}
loggers::loggers::log("LayerStackBuilder::createLayerStack: Setup layers for %s", l->to_string().c_str());
loggers::get_instance().log("LayerStackBuilder::createLayerStack: Setup layers for %s", l->to_string().c_str());
l->addUpperLayer(up);
if (entry == NULL) { // Set the first declared layer
entry = l;
......
......@@ -5,7 +5,7 @@
#include "loggers.hh"
void Params::convert(Params& p_param, const std::string p_parameters) {
//loggers::loggers::log(">>> Params::convert: '%s'", p_parameters.c_str());
//loggers::get_instance().log(">>> Params::convert: '%s'", p_parameters.c_str());
// Sanity checks
if (p_parameters.length() == 0) {
return;
......@@ -17,7 +17,7 @@ void Params::convert(Params& p_param, const std::string p_parameters) {
std::sregex_iterator end = std::sregex_iterator();
for (std::sregex_iterator it = begin; it != end; ++it) {
std::smatch m = *it;
//loggers::loggers::log("Params::convert: %d - %s - %s - %s - %s", m.size(), m[0].str().c_str(), m[1].str().c_str(), m[2].str().c_str(), m[3].str().c_str());
//loggers::get_instance().log("Params::convert: %d - %s - %s - %s - %s", m.size(), m[0].str().c_str(), m[1].str().c_str(), m[2].str().c_str(), m[3].str().c_str());
p_param.insert(std::pair<std::string, std::string>(m[1].str(), m[2].str()));
} // End of 'for' statement
}
......@@ -27,8 +27,8 @@ void Params::convert(Params& p_param, const std::string p_parameters) {
}
void Params::log() {
loggers::loggers::log("Params::log");
loggers::get_instance().log("Params::log");
for (const_iterator it = cbegin(); it != cend(); ++it) {
loggers::loggers::log("\t(%s, %s)", it->first.c_str(), it->second.c_str());
loggers::get_instance().log("\t(%s, %s)", it->first.c_str(), it->second.c_str());
} // End of 'for' statement
}
......@@ -2,21 +2,22 @@
#include "loggers.hh"
EthernetLayer::EthernetLayer(const std::string & p_type, const std::string & param) : Layer(p_type), _params() {
loggers::loggers::log(">>> EthernetLayer::EthernetLayer: %s, %s", to_string().c_str(), param.c_str());
loggers::get_instance().log(">>> EthernetLayer::EthernetLayer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
Params::convert(_params, param);
//_params.log();
}
void EthernetLayer::sendData(OCTETSTRING& data, Params& params) {
loggers::loggers::log_msg(">>> EthernetLayer::sendData: ", data);
loggers::get_instance().log_msg(">>> EthernetLayer::sendData: ", data);
OCTETSTRING eth;
std::map<std::string, std::string>::const_iterator it = params.find("mac_dst");
if (it != params.cend()) {
eth += str2oct(CHARSTRING(it->second.c_str()));
eth = str2oct(CHARSTRING(it->second.c_str()));
} else {
const unsigned char mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
eth += OCTETSTRING(sizeof(mac_address), static_cast<const unsigned char *>(mac_address));
eth = OCTETSTRING(sizeof(mac_address), static_cast<const unsigned char *>(mac_address));
}
it = params.find("mac_src");
if (it != params.cend()) {
......@@ -29,33 +30,33 @@ void EthernetLayer::sendData(OCTETSTRING& data, Params& params) {
if (it != params.cend()) {
eth += str2oct(CHARSTRING(it->second.c_str()));
} else {
const unsigned char proto[] = {0x47, 0x89};
const unsigned char proto[] = {0x89, 0x47};
eth += OCTETSTRING(sizeof(proto), static_cast<const unsigned char *>(proto));
}
data = eth + data;
sendToAllLayers(data, params);
eth += data;
sendToAllLayers(eth, params);
}
void EthernetLayer::receiveData(OCTETSTRING& data, Params& params) {
loggers::loggers::log_msg(">>> EthernetLayer::receiveData: ", data);
loggers::get_instance().log_msg(">>> EthernetLayer::receiveData: ", data);
// Extract dest MAC Address
OCTETSTRING dst = OCTETSTRING(6, static_cast<const unsigned char *>(data));
//loggers::loggers::log_msg("EthernetLayer::receiveData: dst: ", dst);
//loggers::get_instance().log_msg("EthernetLayer::receiveData: dst: ", dst);
// Extract source MAC Address
OCTETSTRING src = OCTETSTRING(6, 6 + static_cast<const unsigned char *>(data));
//loggers::loggers::log_msg("EthernetLayer::receiveData: src: ", src);
//loggers::get_instance().log_msg("EthernetLayer::receiveData: src: ", src);
// Extract ethertype
OCTETSTRING proto = OCTETSTRING(2, 2 + static_cast<const unsigned char *>(data));
//loggers::loggers::log_msg("EthernetLayer::receiveData: proto: ", proto);
//loggers::get_instance().log_msg("EthernetLayer::receiveData: proto: ", proto);
data = OCTETSTRING(data.lengthof() - 14, 14 + static_cast<const unsigned char *>(data));
// Update params
CHARSTRING s = oct2str(dst);
params.insert(std::pair<std::string, std::string>(std::string("mac_dst"), std::string(static_cast<const char *>(s))));
s = oct2str(src);
params.insert(std::pair<std::string, std::string>(std::string("mac_src"), std::string(static_cast<const char *>(s))));
//loggers::loggers::log_msg("EthernetLayer::receiveData: payload for upper layer:", data);
//loggers::get_instance().log_msg("EthernetLayer::receiveData: payload for upper layer:", data);
receiveToAllLayers(data, params);
}
......@@ -70,7 +71,7 @@ public:
EthernetFactory::EthernetFactory() {
// register factory
loggers::loggers::log(">>> EthernetFactory::EthernetFactory");
loggers::get_instance().log(">>> EthernetFactory::EthernetFactory");
LayerStackBuilder::RegisterLayerFactory("ETH", this);
}
......
......@@ -57,8 +57,8 @@ class GeoNetworkingCodec : public Codec<LibItsGeoNetworking__TypesAndValues::Geo
int decode_extendedHeader(LibItsGeoNetworking__TypesAndValues::ExtendedHeader& u, TTCN_Buffer& decodin_buffer);
public:
GeoNetworkingCodec() : Codec<LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu>(), _ec(), _dc() { loggers::loggers::log("GeoNetworkingCodec::GeoNetworkingCodec(D) :%d ", _ec.next_header); };
virtual ~GeoNetworkingCodec() { loggers::loggers::log("GeoNetworkingCodec::~GeoNetworkingCodec"); };
GeoNetworkingCodec() : Codec<LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu>(), _ec(), _dc() { loggers::get_instance().log("GeoNetworkingCodec::GeoNetworkingCodec(D) :%d ", _ec.next_header); };
virtual ~GeoNetworkingCodec() { loggers::get_instance().log("GeoNetworkingCodec::~GeoNetworkingCodec"); };
int encode (const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& msg, OCTETSTRING& data);
int decode (const OCTETSTRING& data, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& msg);
......
......@@ -4,30 +4,29 @@
#include "loggers.hh"
GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec() {
loggers::loggers::log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
loggers::get_instance().log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
Params::convert(_params, param);
//_params.log();
}
void GeoNetworkingLayer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, const Params& params) {
loggers::loggers::log(">>> GeoNetworkingLayer::sendMsg");
loggers::get_instance().log(">>> GeoNetworkingLayer::sendMsg");
OCTETSTRING data;
_codec.encode(p.msgOut(), data);
loggers::loggers::log_msg("GeoNetworkingLayer::sendMsg: After encoding: ", data);
Params par(params);
loggers::loggers::log("GeoNetworkingLayer::sendMsg: Before calling sendData");
par.log();
sendData(data, par);
}
void GeoNetworkingLayer::sendData(OCTETSTRING& data, Params& params) {
loggers::loggers::log(">>> GeoNetworkingLayer::sendData");
loggers::get_instance().log_msg(">>> GeoNetworkingLayer::sendData: ", data);
sendToAllLayers(data, params);
}
void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
loggers::loggers::log_msg(">>> GeoNetworkingLayer::receiveData: ", data);
loggers::get_instance().log_msg(">>> GeoNetworkingLayer::receiveData: ", data);
// Decode the payload
LibItsGeoNetworking__TestSystem::GeoNetworkingInd p;
_codec.decode(data, p.msgIn());
......@@ -35,7 +34,7 @@ void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
// 1. Destination MAC address
std::map<std::string, std::string>::const_iterator it = params.find("dst");
if (it != params.cend()) {
loggers::loggers::log("GeoNetworkingLayer::receiveData: dst=", it->second.c_str());
loggers::get_instance().log("GeoNetworkingLayer::receiveData: dst=", it->second.c_str());
p.macDestinationAddress() = str2oct(CHARSTRING(it->second.c_str()));
} else {
const unsigned char mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // TODO Declare it as a C++ constant
......@@ -58,7 +57,7 @@ public:
GeoNetworkingFactory::GeoNetworkingFactory() {
// register factory
loggers::loggers::log(">>> GeoNetworkingFactory::GeoNetworkingFactory");
loggers::get_instance().log(">>> GeoNetworkingFactory::GeoNetworkingFactory");
LayerStackBuilder::RegisterLayerFactory("GN", this);
}
......
......@@ -2,7 +2,6 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <thread>
#include <chrono>
#include "Port.hh"
......@@ -10,8 +9,8 @@
#include "PcapLayer.hh"
#include "loggers.hh"
PcapLayer::PcapLayer(const std::string & p_type, const std::string & param) : Layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _pcap_h(-1), _thread_id(-1), _running(FALSE), _resume(FALSE) {
loggers::loggers::log(">>> PcapLayer::PcapLayer: %s, %s", to_string().c_str(), param.c_str());
PcapLayer::PcapLayer(const std::string & p_type, const std::string & param) : Layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _pcap_h(-1), _thread(NULL), _running(FALSE), _resume(), _time_key("PcapLayer::Handle_Fd_Event_Readable") {
loggers::get_instance().log(">>> PcapLayer::PcapLayer: %s, %s", to_string().c_str(), param.c_str());
_fd[0] = -1; _fd[1] = -1;
// Setup parameters
Params::convert(_params, param);
......@@ -24,22 +23,22 @@ PcapLayer::PcapLayer(const std::string & p_type, const std::string & param) : La
/*bpf_u_int32 mask; // subnet mask
bpf_u_int32 net; // ip address
if (pcap_lookupnet(_params["nic"].c_str(), &net, &mask, error_buffer) != 0) {
loggers::loggers::error("PcapLayer::PcapLayer: PcapLayer::PcapLayer: Failed to fetch newtork address for device %s", _params["nic"].c_str());
loggers::get_instance().error("PcapLayer::PcapLayer: PcapLayer::PcapLayer: Failed to fetch newtork address for device %s", _params["nic"].c_str());
}
loggers::loggers::log("PcapLayer::PcapLayer: Device %s Network address: %d", _params["nic"].c_str(), net);*/
loggers::get_instance().log("PcapLayer::PcapLayer: Device %s Network address: %d", _params["nic"].c_str(), net);*/
// Open the device
_device = pcap_open_live(_params["nic"].c_str(), 65536, 1, 1000, error_buffer); // TODO Replace hard coded values by PcapLayer::<constants>
if (_device == NULL) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to open device %s", _params["nic"].c_str());
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to open device %s", _params["nic"].c_str());
} // else, continue
// Set non-blocking flag for the polling procedure
if (pcap_setnonblock(_device, 1, error_buffer) != 0) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to set blocking mode: %s", error_buffer);
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to set blocking mode: %s", error_buffer);
}
// Retrieve the device file handler
_pcap_h = pcap_get_selectable_fd(_device);
if (_pcap_h == -1) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to get device handler");
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to get device handler");
}
} else {
// Check file name
......@@ -47,16 +46,16 @@ PcapLayer::PcapLayer(const std::string & p_type, const std::string & param) : La
if ((it != _params.end()) && !it->second.empty()) { // Use offline capture
struct stat s = {0};
if ((stat(_params["file"].c_str(), &s) != 0) || !S_ISREG(s.st_mode)) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to acces PCAP file %s", _params["file"].c_str());
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to acces PCAP file %s", _params["file"].c_str());
}
// File exist, open it
_device = pcap_open_offline(_params["file"].c_str(), error_buffer);
if (_device == NULL) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to open PCAP file %s", error_buffer);
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to open PCAP file %s", error_buffer);
} // else, continue
} else {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to open PCAP file %s", error_buffer);
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to open PCAP file %s", error_buffer);
}
}
// Setup filter
......@@ -65,14 +64,14 @@ PcapLayer::PcapLayer(const std::string & p_type, const std::string & param) : La
if ((it != _params.end()) && !it->second.empty()) {
filter = _params["filter"];
} // else nothing to do
loggers::loggers::log("PcapLayer::PcapLayer: Filter: %s", filter.c_str());
loggers::get_instance().log("PcapLayer::PcapLayer: Filter: %s", filter.c_str());
if (!filter.empty()) {
struct bpf_program f = {0};
if (pcap_compile(_device, &f, filter.c_str(), 1, PCAP_NETMASK_UNKNOWN) != 0) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to compile PCAP filter");
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to compile PCAP filter");
}
if (pcap_setfilter(_device, &f) != 0) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to set PCAP filter");
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to set PCAP filter");
}
pcap_freecode(&f);
}
......@@ -82,32 +81,36 @@ PcapLayer::PcapLayer(const std::string & p_type, const std::string & param) : La
} else {
// Create a pipe
if (pipe2(_fd, O_NONBLOCK) == -1) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to create a pipe: %s", ::strerror(errno));
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to create a pipe: %s", ::strerror(errno));
}
// Pass the pipe handler to the polling procedure
loggers::loggers::log("PcapLayer::PcapLayer: Call handler with descriptor %d", _fd[0]);
loggers::get_instance().log("PcapLayer::PcapLayer: Call handler with descriptor %d", _fd[0]);
Handler_Add_Fd_Read(_fd[0]);
if (pthread_create(&_thread_id, NULL, &PcapLayer::run, (void *)this) != 0) {
loggers::loggers::error("PcapLayer::PcapLayer: Failed to compile PCAP filter");
// Create the offline reader thread
_thread = new std::thread(&PcapLayer::run, (void *)this);
if (_thread == NULL) {
loggers::get_instance().error("PcapLayer::PcapLayer: Failed to start offline thread");
}
// Start a working thread to dispatch packet to a pipe
// Start it to dispatch packet to a pipe
while (_running == FALSE) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// Thread was started
loggers::loggers::log("<<< PcapLayer::PcapLayer");
loggers::get_instance().log("<<< PcapLayer::PcapLayer");
}
} // End of ctor
PcapLayer::~PcapLayer() {
loggers::loggers::log(">>> PcapLayer::~PcapLayer");
loggers::get_instance().log(">>> PcapLayer::~PcapLayer");
if (_device != NULL) {
if (_fd[0] != -1) { // TODO To be refined :-(
if (_thread != NULL) {
_running = FALSE;
// Wait for the working thread to terminate
pthread_join(_thread_id, NULL);
loggers::loggers::log("PcapLayer::~PcapLayer: Thread were stops");
_thread->join();
loggers::get_instance().log("PcapLayer::~PcapLayer: Thread were stops");
// Cleanup
delete _thread;
close(_fd[0]);
close(_fd[1]);
}
......@@ -116,71 +119,82 @@ PcapLayer::~PcapLayer() {
} // End of dtor
void * PcapLayer::run(void *p_this) {
loggers::loggers::log(">>> PcapLayer::run: Class pointer: %p", p_this);
loggers::get_instance().log(">>> PcapLayer::run");
// Pointer the main object
PcapLayer& p = *static_cast<PcapLayer *>(p_this);
// Set running flags
p._running = TRUE;
p._resume = TRUE;
sleep(1);
while (p._running) {
if (p._resume == TRUE) {
// Wait a little bit before to start sending packet
std::this_thread::sleep_for(std::chrono::seconds(1));
// Let's go
while (p._running) { // Loop while _running flag is up
if (p._resume.try_lock() == TRUE) { // Previous packet was consumed, lock for the next one
write(p._fd[1], "\n", 1);
p._resume = FALSE;
//p._resume = FALSE;
} else { // not ready yet
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
loggers::loggers::log("<<< PcapLayer::run");
loggers::get_instance().log("<<< PcapLayer::run");
return NULL;
}
void PcapLayer::sendData(OCTETSTRING& data, Params& params) {
loggers::loggers::log_msg(">>> PcapLayer::sendData: ", data);
loggers::get_instance().log_msg(">>> PcapLayer::sendData: ", data);
if (_pcap_h != -1) { // Check if offline mode is used
if (pcap_inject(_device, static_cast<const unsigned char *>(data), data.lengthof()) != 0) {
loggers::loggers::error("PcapLayer::sendData: Failed to send packet: %s", pcap_geterr(_device));
loggers::get_instance().error("PcapLayer::sendData: Failed to send packet: %s", pcap_geterr(_device));
}
} else {
loggers::loggers::log("PcapLayer::sendData: Offline mode, operation was skipped");
loggers::get_instance().log("PcapLayer::sendData: Offline mode, operation was skipped");
// TODO Use PCAP dump file to store sent message in a file??
}
}
void PcapLayer::receiveData(OCTETSTRING& data, Params& params) {
//loggers::loggers::log(">>> PcapLayer::receiveData: Received %d bytes", data.lengthof());
loggers::loggers::log_to_hexa("Packet dump", data);
//loggers::get_instance().log(">>> PcapLayer::receiveData: Received %d bytes", data.lengthof());
loggers::get_instance().log_to_hexa("Packet dump", data);
// Pass the packet to the upper layers
receiveToAllLayers(data, params);
}
void PcapLayer::Handle_Fd_Event_Readable(int fd) {
//loggers::loggers::log(">>> PcapLayer::Handle_Fd_Event_Readable: %d", fd);
//loggers::get_instance().log(">>> PcapLayer::Handle_Fd_Event_Readable: %d", fd);
struct pcap_pkthdr *pkt_header;
const u_char *pkt_data;
int result = pcap_next_ex(_device, &pkt_header, &pkt_data);
if (result == 1) { // Succeed
if (pkt_header->caplen > 14) { // Reject too small packet
//loggers::loggers::log("PcapLayer::Handle_Fd_Event_Readable: %.6d - %d", pkt_header->ts.tv_usec, pkt_header->len);
//loggers::get_instance().log("PcapLayer::Handle_Fd_Event_Readable: %.6d - %d", pkt_header->ts.tv_usec, pkt_header->len);
// Fill parameters from PCAP layer
Params params;
params.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(pkt_header->ts.tv_usec)));
// Process the packet at this layer
OCTETSTRING os(pkt_header->caplen, pkt_data);
//loggers::loggers::log_to_hexa("PcapLayer::Handle_Fd_Event_Readable: ", os);
//loggers::get_instance().log_to_hexa("PcapLayer::Handle_Fd_Event_Readable: ", os);
// TODO Case of caplen != len !!!
float duration;
loggers::get_instance().set_start_time(_time_key);
this->receiveData(os, params); // TODO Check execution time for decoding operation
loggers::get_instance().set_stop_time(_time_key, duration);
}
} // else, skip the packet
// Specific to offline mode
if (_fd[0] != -1) { // Check if offline mode is used
//loggers::loggers::log("PcapLayer::Handle_Fd_Event_Readable: Read pipe");
//loggers::get_instance().log("PcapLayer::Handle_Fd_Event_Readable: Read pipe");
char c[2];
read(_fd[0], &c, 1);
if (result == -2) { // End of file, therminate worker thread
_running = FALSE;
} else { // Get next packet
//loggers::loggers::log("PcapLayer::Handle_Fd_Event_Readable: pcap_next_ex failed: result=%d", result);
_resume = TRUE;
//loggers::get_instance().log("PcapLayer::Handle_Fd_Event_Readable: pcap_next_ex failed: result=%d", result);
_resume.unlock();
}
} // else, nothing to do
}
......@@ -195,7 +209,7 @@ public:
PcapFactory::PcapFactory() {
// register factory
loggers::loggers::log(">>> PcapFactory::PcapFactory");
loggers::get_instance().log(">>> PcapFactory::PcapFactory");
LayerStackBuilder::RegisterLayerFactory("PCAP", this);
}
......
#pragma once
#include <pthread.h>
#include <thread>
#include <mutex>
#include <pcap/pcap.h>
#include "Layer.hh"
......@@ -12,9 +13,10 @@ class PcapLayer : public Layer, public PORT {
Params _params;
pcap_t *_device;
int _pcap_h;
pthread_t _thread_id;
std::thread * _thread;