#include "LibItsMapemSpatem_TestSystem.hh"
#include "mapem_codec.hh"
#include "asn1/asn_application.h" // from asn1c
#include "loggers.hh"
#include "mapem_codec.hh"
extern "C" {
extern asn_TYPE_descriptor_t asn_DEF_MAPEM;
extern asn_TYPE_descriptor_t asn_DEF_MAPEM;
}
int mapem_pdu_codec::encode (const MAPEM__PDU__Descriptions::MAPEM& p_mapem, BITSTRING& p_data)
{
int mapem_pdu_codec::encode(const MAPEM__PDU__Descriptions::MAPEM &p_mapem, BITSTRING &p_data) {
return _encode(MAPEM__PDU__Descriptions::MAPEM_descr_, asn_DEF_MAPEM, p_mapem, p_data);
}
int mapem_pdu_codec::decode (const BITSTRING& p_data, MAPEM__PDU__Descriptions::MAPEM& p_mapem)
{
int mapem_pdu_codec::decode(const BITSTRING &p_data, MAPEM__PDU__Descriptions::MAPEM &p_mapem) {
return _decode(MAPEM__PDU__Descriptions::MAPEM_descr_, asn_DEF_MAPEM, p_data, p_mapem);
}
#pragma once
#include "codec.hh"
#include "per_codec.hh"
#include "params.hh"
#include "per_codec.hh"
#include "LibItsMapemSpatem_TestSystem.hh"
class mapem_pdu_codec : public per_codec <MAPEM__PDU__Descriptions::MAPEM>
{
class mapem_pdu_codec : public per_codec<MAPEM__PDU__Descriptions::MAPEM> {
public:
explicit mapem_pdu_codec() { };
virtual int encode (const MAPEM__PDU__Descriptions::MAPEM& sapem, BITSTRING& data);
virtual int decode (const BITSTRING& data, MAPEM__PDU__Descriptions::MAPEM&);
explicit mapem_pdu_codec(){};
virtual int encode(const MAPEM__PDU__Descriptions::MAPEM &sapem, BITSTRING &data);
virtual int decode(const BITSTRING &data, MAPEM__PDU__Descriptions::MAPEM &);
}; // End of class mapem_pdu_codec
......@@ -6,7 +6,8 @@
#include "loggers.hh"
mapem_spatem_layer::mapem_spatem_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsMapemSpatem__TestSystem::MapemSpatemPort>(p_type), _params(), _mapem_codec(), _spatem_codec() {
mapem_spatem_layer::mapem_spatem_layer(const std::string &p_type, const std::string &param)
: t_layer<LibItsMapemSpatem__TestSystem::MapemSpatemPort>(p_type), _params(), _mapem_codec(), _spatem_codec() {
loggers::get_instance().log(">>> mapem_spatem_layer::mapem_spatem_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
params::convert(_params, param);
......@@ -18,7 +19,7 @@ mapem_spatem_layer::mapem_spatem_layer(const std::string & p_type, const std::st
registration<mapem_spatem_layer>::get_instance().add_item(p_type, this);
}
void mapem_spatem_layer::sendMsg(const LibItsMapemSpatem__TestSystem::MapemReq& p, params& params){
void mapem_spatem_layer::sendMsg(const LibItsMapemSpatem__TestSystem::MapemReq &p, params &params) {
loggers::get_instance().log_msg(">>> mapem_spatem_layer::sendMsg: ", p);
// Encode mapem PDU
......@@ -31,7 +32,7 @@ void mapem_spatem_layer::sendMsg(const LibItsMapemSpatem__TestSystem::MapemReq&
send_data(data, _params);
}
void mapem_spatem_layer::sendMsg(const LibItsMapemSpatem__TestSystem::SpatemReq& p, params& params){
void mapem_spatem_layer::sendMsg(const LibItsMapemSpatem__TestSystem::SpatemReq &p, params &params) {
loggers::get_instance().log_msg(">>> mapem_spatem_layer::sendMsg: ", p);
// Encode spatem PDU
......@@ -43,18 +44,17 @@ void mapem_spatem_layer::sendMsg(const LibItsMapemSpatem__TestSystem::SpatemReq&
send_data(data, _params);
}
void mapem_spatem_layer::send_data(OCTETSTRING& data, params& params) {
void mapem_spatem_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> mapem_spatem_layer::send_data: ", data);
//params.log();
// params.log();
send_to_all_layers(data, params);
}
void mapem_spatem_layer::receive_data(OCTETSTRING& data, params& params)
{
void mapem_spatem_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> mapem_spatem_layer::receive_data: ", data);
// Sanity check
if (*(static_cast<const unsigned char*>(data)+ 1) == 0x05) { // Check that received packet has MAPE message id
if (*(static_cast<const unsigned char *>(data) + 1) == 0x05) { // Check that received packet has MAPE message id
// Decode the MAPEM payload
LibItsMapemSpatem__TestSystem::MapemInd p;
_mapem_codec.decode(data, p.msgIn());
......@@ -137,7 +137,7 @@ void mapem_spatem_layer::receive_data(OCTETSTRING& data, params& params)
// Pass it to the ports if any
to_all_upper_ports(p, params);
} else if (*(static_cast<const unsigned char*>(data)+ 1) == 0x04) { // Check that received packet has SPATE message id
} else if (*(static_cast<const unsigned char *>(data) + 1) == 0x04) { // Check that received packet has SPATE message id
// Decode the SPATEM payload
LibItsMapemSpatem__TestSystem::SpatemInd p;
_spatem_codec.decode(data, p.msgIn());
......@@ -222,12 +222,12 @@ void mapem_spatem_layer::receive_data(OCTETSTRING& data, params& params)
to_all_upper_ports(p, params);
} else {
// Not a MAPEM/SPATEM message, discard it
loggers::get_instance().warning("mapem_spatem_layer::receive_data: Wrong message id: 0x%02x", *(static_cast<const unsigned char*>(data)+ 1));
loggers::get_instance().warning("mapem_spatem_layer::receive_data: Wrong message id: 0x%02x", *(static_cast<const unsigned char *>(data) + 1));
return;
}
}
int mapem_spatem_layer::enable_secured_mode(const std::string& p_certificate_id, const boolean p_enforce_security) {
int mapem_spatem_layer::enable_secured_mode(const std::string &p_certificate_id, const boolean p_enforce_security) {
loggers::get_instance().log(">>> mapem_spatem_layer::enable_secured_mode: '%s' - %x", p_certificate_id.c_str(), p_enforce_security);
return 0;
......
......@@ -10,9 +10,9 @@
*/
#pragma once
#include "t_layer.hh"
#include "mapem_codec.hh"
#include "spatem_codec.hh"
#include "t_layer.hh"
namespace LibItsMapemSpatem__TestSystem {
class MapemSpatemPort;
......@@ -20,26 +20,26 @@ namespace LibItsMapemSpatem__TestSystem {
class MapemInd;
class SpatemReq;
class SpatemInd;
}
} // namespace LibItsMapemSpatem__TestSystem
class mapem_spatem_layer : public t_layer<LibItsMapemSpatem__TestSystem::MapemSpatemPort> {
params _params;
mapem_codec _mapem_codec;
spatem_codec _spatem_codec;
public:
mapem_spatem_layer() : t_layer<LibItsMapemSpatem__TestSystem::MapemSpatemPort>(), _params(), _mapem_codec(), _spatem_codec() {};
mapem_spatem_layer(const std::string& p_type, const std::string& param);
virtual ~mapem_spatem_layer() {};
mapem_spatem_layer() : t_layer<LibItsMapemSpatem__TestSystem::MapemSpatemPort>(), _params(), _mapem_codec(), _spatem_codec(){};
mapem_spatem_layer(const std::string &p_type, const std::string &param);
virtual ~mapem_spatem_layer(){};
void sendMsg(const LibItsMapemSpatem__TestSystem::MapemReq&, params& params);
void sendMsg(const LibItsMapemSpatem__TestSystem::SpatemReq&, params& params);
void sendMsg(const LibItsMapemSpatem__TestSystem::MapemReq &, params &params);
void sendMsg(const LibItsMapemSpatem__TestSystem::SpatemReq &, params &params);
virtual void send_data(OCTETSTRING& data, params& params);
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void send_data(OCTETSTRING &data, params &params);
virtual void receive_data(OCTETSTRING &data, params &info);
int enable_secured_mode(const std::string& p_certificate_id, const boolean p_enforce_security);
int enable_secured_mode(const std::string &p_certificate_id, const boolean p_enforce_security);
int disable_secured_mode();
}; // End of class mapem_spatem_layer
......@@ -16,13 +16,11 @@
class mapem_spatem_layer_factory : public layer_factory {
static mapem_spatem_layer_factory _f;
public:
mapem_spatem_layer_factory() {
// Register factory
layer_stack_builder::register_layer_factory("MapemSpatem", this);
};
inline virtual layer* create_layer(const std::string& p_type, const std::string& p_param){
return new mapem_spatem_layer(p_type, p_param);
};
inline virtual layer *create_layer(const std::string &p_type, const std::string &p_param) { return new mapem_spatem_layer(p_type, p_param); };
}; // End of class mapem_spatem_layer_factory
......@@ -11,5 +11,5 @@
#pragma once
using namespace std; // Required for isnan()
#include "LibItsMapemSpatem_TypesAndValues.hh"
#include "LibItsMapemSpatem_TestSystem.hh"
#include "LibItsMapemSpatem_TypesAndValues.hh"
#include "mapem_spatem_types.hh"
#include "spatem_codec.hh"
#include "asn1/asn_application.h" // from asn1c
#include "loggers.hh"
#include "mapem_spatem_types.hh"
int spatem_codec::encode (const SPATEM__PDU__Descriptions::SPATEM& spatem, OCTETSTRING& data)
{
int spatem_codec::encode(const SPATEM__PDU__Descriptions::SPATEM &spatem, OCTETSTRING &data) {
loggers::get_instance().log(">>> spatem_codec::encode");
BITSTRING b;
int rc = asn_codec.encode(spatem, b);
if(rc){
if (rc) {
data = bit2oct(b);
loggers::get_instance().log_msg("spatem_codec::encode: ", data);
}
return rc;
}
int spatem_codec::decode (const OCTETSTRING& data, SPATEM__PDU__Descriptions::SPATEM& spatem, params* params)
{
int spatem_codec::decode(const OCTETSTRING &data, SPATEM__PDU__Descriptions::SPATEM &spatem, params *params) {
loggers::get_instance().log_msg(">>> spatem_codec::decode: ", data);
int rc = asn_codec.decode(oct2bit(data), spatem);
loggers::get_instance().log("spatem_codec::decode: ASN.1 codec returned %d", rc);
if(rc) {
if (rc) {
loggers::get_instance().log_msg("spatem_codec::decode: ", spatem);
}
return rc;
......
#pragma once
#include "codec.hh"
#include "spatem_pdu_codec.hh"
#include "params.hh"
#include "spatem_pdu_codec.hh"
#include "mapem_spatem_types.hh"
class spatem_codec : public codec<SPATEM__PDU__Descriptions::SPATEM, SPATEM__PDU__Descriptions::SPATEM>
{
class spatem_codec : public codec<SPATEM__PDU__Descriptions::SPATEM, SPATEM__PDU__Descriptions::SPATEM> {
spatem_pdu_codec asn_codec;
public:
explicit spatem_codec() : codec<SPATEM__PDU__Descriptions::SPATEM, SPATEM__PDU__Descriptions::SPATEM>(), asn_codec() { };
virtual ~spatem_codec() { };
explicit spatem_codec() : codec<SPATEM__PDU__Descriptions::SPATEM, SPATEM__PDU__Descriptions::SPATEM>(), asn_codec(){};
virtual ~spatem_codec(){};
virtual int encode (const SPATEM__PDU__Descriptions::SPATEM& spatem, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, SPATEM__PDU__Descriptions::SPATEM&, params* params = NULL);
virtual int encode(const SPATEM__PDU__Descriptions::SPATEM &spatem, OCTETSTRING &data);
virtual int decode(const OCTETSTRING &data, SPATEM__PDU__Descriptions::SPATEM &, params *params = NULL);
}; // End of class spatem_codec
#include "mapem_spatem_types.hh"
#include "spatem_codec.hh"
#include "asn1/asn_application.h" // from asn1c
#include "loggers.hh"
#include "mapem_spatem_types.hh"
#include "spatem_codec.hh"
extern "C" {
extern asn_TYPE_descriptor_t asn_DEF_SPATEM;
extern asn_TYPE_descriptor_t asn_DEF_SPATEM;
}
int spatem_pdu_codec::encode (const SPATEM__PDU__Descriptions::SPATEM& p_spatem, BITSTRING& p_data)
{
int spatem_pdu_codec::encode(const SPATEM__PDU__Descriptions::SPATEM &p_spatem, BITSTRING &p_data) {
return _encode(SPATEM__PDU__Descriptions::SPATEM_descr_, asn_DEF_SPATEM, p_spatem, p_data);
}
int spatem_pdu_codec::decode (const BITSTRING& p_data, SPATEM__PDU__Descriptions::SPATEM& p_spatem)
{
int spatem_pdu_codec::decode(const BITSTRING &p_data, SPATEM__PDU__Descriptions::SPATEM &p_spatem) {
return _decode(SPATEM__PDU__Descriptions::SPATEM_descr_, asn_DEF_SPATEM, p_data, p_spatem);
}
#pragma once
#include "codec.hh"
#include "per_codec.hh"
#include "params.hh"
#include "per_codec.hh"
#include "mapem_spatem_types.hh"
class spatem_pdu_codec : public per_codec <SPATEM__PDU__Descriptions::SPATEM>
{
class spatem_pdu_codec : public per_codec<SPATEM__PDU__Descriptions::SPATEM> {
public:
explicit spatem_pdu_codec() { };
virtual int encode (const SPATEM__PDU__Descriptions::SPATEM& spatem, BITSTRING& data);
virtual int decode (const BITSTRING& data, SPATEM__PDU__Descriptions::SPATEM&);
explicit spatem_pdu_codec(){};
virtual int encode(const SPATEM__PDU__Descriptions::SPATEM &spatem, BITSTRING &data);
virtual int decode(const BITSTRING &data, SPATEM__PDU__Descriptions::SPATEM &);
}; // End of class spatem_pdu_codec
#if defined (__CYGWIN__)
#if defined(__CYGWIN__)
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <chrono>
#include <sstream>
#include <errno.h>
#include <fcntl.h>
#include <iomanip>
#include <sstream>
#include <sys/stat.h>
#include <unistd.h>
#include <Port.hh>
......@@ -21,44 +21,45 @@
typedef struct {
bpf_int32 tv_sec; /* seconds */
bpf_int32 tv_usec; /* microseconds */
}pcap_o_timeval;
} pcap_o_timeval;
typedef struct pcap_o_pkthdr {
pcap_o_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
}pcap_o_pkthdr;
} pcap_o_pkthdr;
extern "C" int pcap_oid_get_request(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp);
static const char* _hexDigits = "0123456789ABCDEF";
static char * _bin2hex(char * hex, size_t hlen, const char * bin, size_t blen)
{
static const char *_hexDigits = "0123456789ABCDEF";
static char * _bin2hex(char *hex, size_t hlen, const char *bin, size_t blen) {
const unsigned char *b, *e;
char * s;
// sanity check
if (hlen >= 0 && hlen < blen * 2) return NULL;
if (hlen >= 0 && hlen < blen * 2)
return NULL;
b = (const unsigned char *)bin;
e = b + blen - 1;
s = hex + blen * 2;
if (s < hex + hlen) *s = 0;
for (; b <= e; e--){
if (s < hex + hlen)
*s = 0;
for (; b <= e; e--) {
*(--s) = _hexDigits[(*e) & 0xF];
*(--s) = _hexDigits[(*e) >> 4];
}
return hex + blen * 2;
}
pcap_layer::pcap_layer(const std::string& p_type, const std::string& param) :
layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _running(FALSE), _time_key("pcap_layer::Handle_Fd_Event_Readable") {
pcap_layer::pcap_layer(const std::string &p_type, const std::string &param)
: layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _running(FALSE), _time_key("pcap_layer::Handle_Fd_Event_Readable") {
loggers::get_instance().log(">>> pcap_layer::pcap_layer: %s, %s", p_type.c_str(), param.c_str());
params::convert(_params, param);
char error_buffer[PCAP_ERRBUF_SIZE];
params::const_iterator it;
std::string nic; //network interface name
std::string nic; // network interface name
bpf_u_int32 mask; // subnet mask
bpf_u_int32 net; // ip address
......@@ -76,7 +77,7 @@ pcap_layer::pcap_layer(const std::string& p_type, const std::string& param) :
loggers::get_instance().log("pcap_layer::pcap_layer: Device %s Network address: %d", nic.c_str(), net);
// Open the device
_device = pcap_open_live(nic.c_str(), 65536/*64*1024*/, 1, 100, error_buffer);
_device = pcap_open_live(nic.c_str(), 65536 /*64*1024*/, 1, 100, error_buffer);
if (_device == NULL) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to open device %s", nic.c_str());
return;
......@@ -111,12 +112,12 @@ pcap_layer::pcap_layer(const std::string& p_type, const std::string& param) :
else
mac_bc = "ffffffffffff";
if(mac_bc == mac_src || mac_src.empty())
if (mac_bc == mac_src || mac_src.empty())
filter = "ether dst " + mac_bc;
else
filter = "( ether dst " + mac_bc + " or ether dst " + mac_src + " )";
if(! mac_src.empty())
if (!mac_src.empty())
// Reject ITS messages sent by this component
filter += " and not ether src " + mac_src;
......@@ -182,17 +183,17 @@ pcap_layer::~pcap_layer() {
}
} // End of dtor
void* pcap_layer::run(void* p_this) {
pcap_layer& p = *static_cast<pcap_layer *>(p_this);
void *pcap_layer::run(void *p_this) {
pcap_layer &p = *static_cast<pcap_layer *>(p_this);
return p.thread();
}
void* pcap_layer::thread() {
void *pcap_layer::thread() {
pcap_o_pkthdr *pkt_header;
const u_char *pkt_data;
const u_char * pkt_data;
unsigned char pkt_count = 0;
// loggers::get_instance().log(">>> pcap_layer::run");
// loggers::get_instance().log(">>> pcap_layer::run");
_running = TRUE;
......@@ -201,16 +202,16 @@ void* pcap_layer::thread() {
while (_running) { // Loop while _running flag is up
// get next frame
int result = pcap_next_ex(_device, (struct pcap_pkthdr**)&pkt_header, &pkt_data);
if(result == 0){
int result = pcap_next_ex(_device, (struct pcap_pkthdr **)&pkt_header, &pkt_data);
if (result == 0) {
continue;
}
if(result < 0){
// loggers::get_instance().log("<<< pcap_layer::run: error %s", pcap_geterr(_device));
if (result < 0) {
// loggers::get_instance().log("<<< pcap_layer::run: error %s", pcap_geterr(_device));
break;
}
while(_running && !_resume.try_lock()) {
while (_running && !_resume.try_lock()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
#if 0
......@@ -226,21 +227,22 @@ void* pcap_layer::thread() {
_o_params[params::timestamp] = std::to_string(pkt_header->ts.tv_sec * 1000 + static_cast<int>(pkt_header->ts.tv_usec / 1000)); // Use milliseconds
#endif
_o_data = OCTETSTRING(pkt_header->len, pkt_data);
write(_fd[1], &pkt_count, 1);pkt_count++;
write(_fd[1], &pkt_count, 1);
pkt_count++;
}
_running = FALSE;
// loggers::get_instance().log("<<< pcap_layer::run");
// loggers::get_instance().log("<<< pcap_layer::run");
return NULL;
}
void pcap_layer::send_data(OCTETSTRING& data, params& params) {
void pcap_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> pcap_layer::send_data: ", data);
if (pcap_sendpacket(_device, static_cast<const unsigned char *>(data), data.lengthof()) == -1) {
loggers::get_instance().error("pcap_layer::send_data: Failed to send packet: %s", pcap_geterr(_device));
}
}
void pcap_layer::receive_data(OCTETSTRING& data, params& params) {
void pcap_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log(">>> pcap_layer::receive_data: Received %d bytes", data.lengthof());
loggers::get_instance().log_to_hexa("Packet dump", data);
......
......@@ -10,11 +10,11 @@
*/
#pragma once
#include <thread>
#include <mutex>
#include <thread>
#include "t_layer.hh"
#include "params.hh"
#include "t_layer.hh"
#include <Octetstring.hh>
......@@ -29,21 +29,22 @@ typedef struct pcap pcap_t;
class pcap_layer : public layer, public PORT {
params _params; //! Layer parameters
pcap_t* _device; //! Device handle
std::thread* _thread; //! Thread handle, used to read PCAP file instead of NIC, used in file mode
pcap_t * _device; //! Device handle
std::thread *_thread; //! Thread handle, used to read PCAP file instead of NIC, used in file mode
std::mutex _resume;
bool _running; //! Set to true when the thread is running, used in file mode
int _fd[2]; //! pipe to signal to Titan
OCTETSTRING _o_data;
params _o_params;
std::string _time_key;
static void* run(void* p_this);
static void *run(void *p_this);
public:
void* thread(void);
void *thread(void);
public: //! \publicsection
/*!
* \brief Specialised constructor
......@@ -51,7 +52,7 @@ public: //! \publicsection
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
pcap_layer(const std::string& p_type, const std::string& param);
pcap_layer(const std::string &p_type, const std::string &param);
/*!
* \brief Default destructor
*/
......@@ -64,7 +65,7 @@ public: //! \publicsection
* \param[in] p_data The data to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
*/
virtual void send_data(OCTETSTRING& data, params& params);
virtual void send_data(OCTETSTRING &data, params &params);
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& params);
......@@ -72,7 +73,7 @@ public: //! \publicsection
* \param[in] p_data The bytes formated data received
* \param[in] p_params Some lower layers parameters values when data was received
*/
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void receive_data(OCTETSTRING &data, params &info);
void Handle_Fd_Event_Readable(int fd);
};
#if 0
#include <unistd.h>
#include <chrono>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <chrono>
#include <unistd.h>
#include <Port.hh>
......
#if defined (__CYGWIN__)
#include "pcap_cygwin_layer.hh"
#if defined(__CYGWIN__)
#include "pcap_cygwin_layer.hh"
#else
#include "pcap_linux_layer.hh"
#include "pcap_linux_layer.hh"
#endif
......@@ -18,7 +18,7 @@
* \class pcap_layer_factory
* \brief This class provides a factory class to create an pcap_layer class instance
*/
class pcap_layer_factory: public layer_factory {
class pcap_layer_factory : public layer_factory {
static pcap_layer_factory _f; //! Reference to the unique instance of this class
public: //! \publicsection
/*!
......@@ -38,8 +38,5 @@ public: //! \publicsection
* \return 0 on success, -1 otherwise
* \inline
*/
inline virtual layer* create_layer(const std::string& p_type, const std::string& p_param) {
return new pcap_layer(p_type, p_param);
};
inline virtual layer *create_layer(const std::string &p_type, const std::string &p_param) { return new pcap_layer(p_type, p_param); };
}; // End of class pcap_layer_factory
#if !defined (__CYGWIN__)
#include <unistd.h>
#if !defined(__CYGWIN__)
#include <chrono>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <iomanip>
#include <net/if.h>
#include <errno.h>
#include <chrono>
#include <sstream>
#include <iomanip>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <Port.hh>
......@@ -15,31 +15,29 @@
#include "loggers.hh"
static const char* _hexDigits = "0123456789ABCDEF";
static char * _bin2hex(char * hex, size_t hlen, const char * bin, size_t blen)
{
static const char *_hexDigits = "0123456789ABCDEF";
static char * _bin2hex(char *hex, size_t hlen, const char *bin, size_t blen) {
const unsigned char *b, *e;
char * s;
// sanity check
if (hlen >= 0 && hlen < blen * 2) return NULL;
if (hlen >= 0 && hlen < blen * 2)
return NULL;
b = (const unsigned char *)bin;
e = b + blen - 1;
s = hex + blen * 2;
if (s < hex + hlen) *s = 0;
for (; b <= e; e--){
if (s < hex + hlen)
*s = 0;
for (; b <= e; e--) {
*(--s) = _hexDigits[(*e) & 0xF];
*(--s) = _hexDigits[(*e) >> 4];
}
return hex + blen * 2;
}
pcap_layer::pcap_layer(const std::string& p_type, const std::string& param)
: layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _pcap_h(-1),
_time_key("pcap_layer::Handle_Fd_Event_Readable")
{
pcap_layer::pcap_layer(const std::string &p_type, const std::string &param)
: layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _pcap_h(-1), _time_key("pcap_layer::Handle_Fd_Event_Readable") {
char error_buffer[PCAP_ERRBUF_SIZE];
params::const_iterator it;
std::string nic;
......@@ -64,7 +62,7 @@ pcap_layer::pcap_layer(const std::string& p_type, const std::string& param)
}
}
// Open the device in promiscuous mode
_device = pcap_open_live(nic.c_str(), 65536/*64*1024*/, 1, 100, error_buffer); // TODO Replace hard coded values by pcap_layer::<constants>
_device = pcap_open_live(nic.c_str(), 65536 /*64*1024*/, 1, 100, error_buffer); // TODO Replace hard coded values by pcap_layer::<constants>
if (_device == NULL) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to open device %s", nic.c_str());
return;
......@@ -133,7 +131,7 @@ pcap_layer::pcap_layer(const std::string& p_type, const std::string& param)
struct bpf_program f = {0};
if (pcap_compile(_device, &f, filter.c_str(), 1, PCAP_NETMASK_UNKNOWN) != 0) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to compile PCAP filter");
}else{
} else {
if (pcap_setfilter(_device, &f) != 0) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to set PCAP filter");
}
......@@ -153,8 +151,7 @@ pcap_layer::~pcap_layer() {
}
} // End of dtor
void pcap_layer::send_data(OCTETSTRING& data, params& params) {
void pcap_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> pcap_layer::send_data: ", data);
if (pcap_sendpacket(_device, static_cast<const unsigned char *>(data), data.lengthof()) == -1) {
......@@ -162,7 +159,7 @@ void pcap_layer::send_data(OCTETSTRING& data, params& params) {
}
}
void pcap_layer::receive_data(OCTETSTRING& data, params& params) {
void pcap_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log(">>> pcap_layer::receive_data: Received %d bytes", data.lengthof());
loggers::get_instance().log_to_hexa("Packet dump", data);
......@@ -171,20 +168,22 @@ void pcap_layer::receive_data(OCTETSTRING& data, params& params) {
}
void pcap_layer::Handle_Fd_Event_Readable(int fd) {
//loggers::get_instance().log(">>> pcap_layer::Handle_Fd_Event_Readable: %d", fd);
// loggers::get_instance().log(">>> pcap_layer::Handle_Fd_Event_Readable: %d", fd);
pcap_pkthdr *pkt_header;
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::get_instance().log("pcap_layer::Handle_Fd_Event_Readable: %ld - %ld - %ld - %d", pkt_header->ts.tv_sec, pkt_header->ts.tv_usec, pkt_header->ts.tv_sec * 1000 + static_cast<unsigned int>(pkt_header->ts.tv_usec / 1000), pkt_header->len);
loggers::get_instance().log("pcap_layer::Handle_Fd_Event_Readable: %ld - %ld - %ld - %d", pkt_header->ts.tv_sec, pkt_header->ts.tv_usec,
pkt_header->ts.tv_sec * 1000 + static_cast<unsigned int>(pkt_header->ts.tv_usec / 1000), pkt_header->len);
// Fill parameters from PCAP layer
params params;
params.insert(std::pair<std::string, std::string>(params::timestamp, std::to_string(pkt_header->ts.tv_sec * 1000 + static_cast<unsigned int>(pkt_header->ts.tv_usec / 1000)))); // Use milliseconds
params.insert(std::pair<std::string, std::string>(
params::timestamp, std::to_string(pkt_header->ts.tv_sec * 1000 + static_cast<unsigned int>(pkt_header->ts.tv_usec / 1000)))); // Use milliseconds
// Process the packet at this layer
OCTETSTRING os(pkt_header->caplen, pkt_data);
//loggers::get_instance().log_to_hexa("pcap_layer::Handle_Fd_Event_Readable: ", os);
// loggers::get_instance().log_to_hexa("pcap_layer::Handle_Fd_Event_Readable: ", os);
// TODO Case of caplen != len !!!
float duration;
loggers::get_instance().set_start_time(_time_key);
......
......@@ -12,8 +12,8 @@
#include <pcap/pcap.h>
#include "t_layer.hh"
#include "params.hh"
#include "t_layer.hh"
class PORT; //! Forward declaration of TITAN class
......@@ -23,9 +23,9 @@ class PORT; //! Forward declaration of TITAN class
*/
class pcap_layer : public layer, public PORT {
params _params; //! Layer parameters
pcap_t* _device; //! Device handle
pcap_t * _device; //! Device handle
int _pcap_h; //! PCAP instance handle
pcap_dumper_t* _sent_file; //! Write file handle to save sent packet, used in file mode
pcap_dumper_t *_sent_file; //! Write file handle to save sent packet, used in file mode
std::string _time_key; //! \todo
public: //! \publicsection
......@@ -35,7 +35,7 @@ public: //! \publicsection
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
pcap_layer(const std::string& p_type, const std::string& param);
pcap_layer(const std::string &p_type, const std::string &param);
/*!
* \brief Default destructor
*/
......@@ -48,7 +48,7 @@ public: //! \publicsection
* \param[in] p_data The data to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
*/
virtual void send_data(OCTETSTRING& data, params& params);
virtual void send_data(OCTETSTRING &data, params &params);
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& params);
......@@ -56,7 +56,7 @@ public: //! \publicsection
* \param[in] p_data The bytes formated data received
* \param[in] p_params Some lower layers parameters values when data was received
*/
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void receive_data(OCTETSTRING &data, params &info);
void Handle_Fd_Event_Readable(int fd);
};
#if defined (__CYGWIN__)
#if defined(__CYGWIN__)
#define _GNU_SOURCE
#endif
#include <unistd.h>
#include <chrono>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <chrono>
#include <unistd.h>
#include <Port.hh>
......@@ -19,20 +19,20 @@
typedef struct {
bpf_int32 tv_sec; /* seconds */
bpf_int32 tv_usec; /* microseconds */
}pcap_o_timeval;
} pcap_o_timeval;
typedef struct pcap_o_pkthdr {
pcap_o_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
}pcap_o_pkthdr;
} pcap_o_pkthdr;
#else
typedef struct pcap_pkthdr pcap_o_pkthdr;
typedef struct timeval pcap_o_timeval;
#endif
pcap_offline_layer::pcap_offline_layer(const std::string& p_type, const std::string& param) :
layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _running(FALSE), _time_key("pcap_offline_layer::Handle_Fd_Event_Readable") {
pcap_offline_layer::pcap_offline_layer(const std::string &p_type, const std::string &param)
: layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _running(FALSE), _time_key("pcap_offline_layer::Handle_Fd_Event_Readable") {
loggers::get_instance().log(">>> pcap_offline_layer::pcap_offline_layer: %s, %s", p_type.c_str(), param.c_str());
params::convert(_params, param);
......@@ -49,20 +49,20 @@ pcap_offline_layer::pcap_offline_layer(const std::string& p_type, const std::str
it = _params.find(std::string("file"));
if ((it != _params.end()) && !it->second.empty()) {
const std::string& file = it->second;
const std::string &file = it->second;
_device = pcap_open_offline(file.c_str(), error_buffer);
if (_device) {
// Add user defined filter
it = _params.find(std::string("filter"));
if ((it != _params.end()) && !it->second.empty()) {
const std::string& filter = it->second;
const std::string &filter = it->second;
// Log final PCAP filter
loggers::get_instance().user("pcap_offline_layer::pcap_offline_layer: Filter: %s", filter.c_str());
struct bpf_program f = {0};
if (pcap_compile(_device, &f, filter.c_str(), 1, PCAP_NETMASK_UNKNOWN) != 0) {
loggers::get_instance().error("pcap_offline_layer::pcap_offline_layer: Failed to compile PCAP filter");
}else{
} else {
if (pcap_setfilter(_device, &f) != 0) {
loggers::get_instance().error("pcap_offline_layer::pcap_offline_layer: Failed to set PCAP filter");
}
......@@ -109,14 +109,12 @@ pcap_offline_layer::~pcap_offline_layer() {
}
} // End of dtor
void* pcap_offline_layer::run(void* p_this) {
pcap_offline_layer& p = *static_cast<pcap_offline_layer *>(p_this);
void *pcap_offline_layer::run(void *p_this) {
pcap_offline_layer &p = *static_cast<pcap_offline_layer *>(p_this);
return p.thread();
}
static long timeval_diff (const pcap_o_timeval &x, const pcap_o_timeval &y)
{
static long timeval_diff(const pcap_o_timeval &x, const pcap_o_timeval &y) {
pcap_o_timeval z = y;
/* Perform the carry for the later subtraction by updating y. */
if (x.tv_usec < y.tv_usec) {
......@@ -130,16 +128,16 @@ static long timeval_diff (const pcap_o_timeval &x, const pcap_o_timeval &y)
z.tv_sec -= nsec;
}
return (x.tv_sec - z.tv_sec) * 1000 + ((x.tv_usec - z.tv_usec)/1000);
return (x.tv_sec - z.tv_sec) * 1000 + ((x.tv_usec - z.tv_usec) / 1000);
}
void* pcap_offline_layer::thread() {
void *pcap_offline_layer::thread() {
pcap_o_pkthdr *pkt_header;
pcap_o_pkthdr lh;
const u_char *pkt_data;
const u_char * pkt_data;
unsigned char pkt_count = 0;
// loggers::get_instance().log(">>> pcap_offline_layer::run");
// loggers::get_instance().log(">>> pcap_offline_layer::run");
memset(&lh, 0, sizeof(lh));
......@@ -148,7 +146,7 @@ void* pcap_offline_layer::thread() {
int delay = 1000;
params::const_iterator it;
it = _params.find(std::string("delay"));
if(it != _params.cend()){
if (it != _params.cend()) {
delay = std::stoi(it->second);
}
......@@ -157,27 +155,27 @@ void* pcap_offline_layer::thread() {
while (_running) { // Loop while _running flag is up
// get next frame
int result = pcap_next_ex(_device, (struct pcap_pkthdr**)&pkt_header, &pkt_data);
if(result == 2){
if(_loop){
int result = pcap_next_ex(_device, (struct pcap_pkthdr **)&pkt_header, &pkt_data);
if (result == 2) {
if (_loop) {
}else{
} else {
_running = FALSE;
return NULL;
}
}
if(_realtime) {
if (_realtime) {
// wait for next packet timestamp
if(lh.ts.tv_sec|lh.ts.tv_usec){
if (lh.ts.tv_sec | lh.ts.tv_usec) {
long diff = timeval_diff(pkt_header->ts, lh.ts);
if(diff > 0) {
if (diff > 0) {
loggers::get_instance().log("<<< pcap_offline_layer::run: Wait %d msec", diff);
std::this_thread::sleep_for(std::chrono::milliseconds(diff));
loggers::get_instance().log("<<< pcap_offline_layer::run: Wait done");
}
}
}
while(_running && !_resume.try_lock()) {
while (_running && !_resume.try_lock()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
lh = *pkt_header;
......@@ -194,18 +192,19 @@ void* pcap_offline_layer::thread() {
_o_params["timestamp"] = std::to_string(pkt_header->ts.tv_usec);
#endif
_o_data = OCTETSTRING(pkt_header->len, pkt_data);
write(_fd[1], &pkt_count, 1);pkt_count++;
write(_fd[1], &pkt_count, 1);
pkt_count++;
}
// loggers::get_instance().log("<<< pcap_offline_layer::run");
// loggers::get_instance().log("<<< pcap_offline_layer::run");
return NULL;
}
void pcap_offline_layer::send_data(OCTETSTRING& data, params& params) {
void pcap_offline_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log("pcap_offline_layer::send_data: Offline mode, operation was skipped");
}
void pcap_offline_layer::receive_data(OCTETSTRING& data, params& params) {
void pcap_offline_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log(">>> pcap_offline_layer::receive_data: Received %d bytes", data.lengthof());
loggers::get_instance().log_to_hexa("Packet dump", data);
......@@ -214,7 +213,7 @@ void pcap_offline_layer::receive_data(OCTETSTRING& data, params& params) {
}
void pcap_offline_layer::Handle_Fd_Event_Readable(int fd) {
//loggers::get_instance().log(">>> pcap_offline_layer::Handle_Fd_Event_Readable: %d", fd);
// loggers::get_instance().log(">>> pcap_offline_layer::Handle_Fd_Event_Readable: %d", fd);
char c[2];
float duration;
// Process the packet at this layer
......
......@@ -10,11 +10,11 @@
*/
#pragma once
#include <thread>
#include <mutex>
#include <thread>
#include "t_layer.hh"
#include "params.hh"
#include "t_layer.hh"
#include <Octetstring.hh>
......@@ -28,8 +28,8 @@ typedef struct pcap pcap_t;
*/
class pcap_offline_layer : public layer, public PORT {
params _params; //! Layer parameters
pcap_t* _device; //! Device handle
std::thread* _thread; //! Thread handle, used to read PCAP file instead of NIC, used in file mode
pcap_t * _device; //! Device handle
std::thread *_thread; //! Thread handle, used to read PCAP file instead of NIC, used in file mode
std::mutex _resume;
bool _running; //! Set to true when the thread is running, used in file mode
bool _realtime; //! Set to true if realtime delay shall be added between packets
......@@ -41,9 +41,11 @@ class pcap_offline_layer : public layer, public PORT {
std::string _time_key;
static void* run(void* p_this);
static void *run(void *p_this);
public:
void* thread(void);
void *thread(void);
public: //! \publicsection
/*!
* \brief Specialised constructor
......@@ -51,7 +53,7 @@ public: //! \publicsection
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
pcap_offline_layer(const std::string& p_type, const std::string& param);
pcap_offline_layer(const std::string &p_type, const std::string &param);
/*!
* \brief Default destructor
*/
......@@ -64,7 +66,7 @@ public: //! \publicsection
* \param[in] p_data The data to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
*/
virtual void send_data(OCTETSTRING& data, params& params);
virtual void send_data(OCTETSTRING &data, params &params);
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& params);
......@@ -72,7 +74,7 @@ public: //! \publicsection
* \param[in] p_data The bytes formated data received
* \param[in] p_params Some lower layers parameters values when data was received
*/
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void receive_data(OCTETSTRING &data, params &info);
void Handle_Fd_Event_Readable(int fd);
};
......@@ -18,7 +18,7 @@
* \class pcap_offline_layer_factory
* \brief This class provides a factory class to create an pcap_offline_layer class instance
*/
class pcap_offline_layer_factory: public layer_factory {
class pcap_offline_layer_factory : public layer_factory {
static pcap_offline_layer_factory _f; //! Reference to the unique instance of this class
public: //! \publicsection
/*!
......@@ -38,8 +38,5 @@ public: //! \publicsection
* \return 0 on success, -1 otherwise
* \inline
*/
inline virtual layer* create_layer(const std::string& p_type, const std::string& p_param) {
return new pcap_offline_layer(p_type, p_param);
};
inline virtual layer *create_layer(const std::string &p_type, const std::string &p_param) { return new pcap_offline_layer(p_type, p_param); };
}; // End of class pcap_offline_layer_factory