Skip to content

Commit

Permalink
Reworked the Lua-cpp memory management
Browse files Browse the repository at this point in the history
Signed-off-by: Olivier Tilmans <olivier.tilmans@uclouvain.be>
  • Loading branch information
oliviertilmans committed May 22, 2017
1 parent 8778ccc commit 3e133e9
Show file tree
Hide file tree
Showing 41 changed files with 347 additions and 459 deletions.
1 change: 1 addition & 0 deletions src/tracebox/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ noinst_HEADERS = \
lua/lua_ipoption.hpp \
lua/lua_ipv6.h \
lua/lua_ipv6segmentroutingheader.h \
lua/lua_layer.hpp \
lua/lua_packet.hpp \
lua/lua_packetmodifications.h \
lua/lua_raw.h \
Expand Down
142 changes: 78 additions & 64 deletions src/tracebox/PacketModification.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

using namespace std;

static Layer *GetLayer(Packet *pkt, int proto_id)
static Layer *GetLayer(const Packet *pkt, int proto_id)
{
for (Layer *l : *pkt) {
if (l->GetID() == proto_id)
Expand All @@ -20,7 +20,7 @@ static Layer *GetLayer(Packet *pkt, int proto_id)
return NULL;
}

static set<int> GetAllProtos(Packet *p1, Packet *p2)
static set<int> GetAllProtos(const Packet *p1, const Packet *p2)
{
set<int> ret;

Expand All @@ -38,7 +38,7 @@ static set<int> GetAllProtos(Packet *p1, Packet *p2)
}

static void ComputeDifferences(PacketModifications *modifs,
Layer *l1, Layer *l2)
const Layer *l1, const Layer *l2)
{
byte* this_layer = new byte[l1->GetSize()];
byte* that_layer = new byte[l1->GetSize()];
Expand Down Expand Up @@ -68,23 +68,29 @@ static void ComputeDifferences(PacketModifications *modifs,
delete[] that_layer;
}

static PacketModifications* ComputeDifferences(Packet *orig, Packet *modified, bool partial)
static PacketModifications* ComputeDifferences(
std::shared_ptr<Packet> orig_shared, const Packet *modified,
bool partial)
{
PacketModifications *modifs = new PacketModifications(orig, modified, partial);
set<int> protos = GetAllProtos(orig, modified);

for (auto proto : protos) {
Layer *l1 = GetLayer(orig, proto);
Layer *l2 = GetLayer(modified, proto);

if (l1 && l2)
ComputeDifferences(modifs, l1, l2);
else if (l1 && !l2 && !partial)
modifs->push_back(new Deletion(l1));
else if (!l1 && l2)
modifs->push_back(new Addition(l2));
}

PacketModifications *modifs = new PacketModifications(
orig_shared, modified, partial);
if (modified) {
const Packet *orig = orig_shared.get();
const set<int> protos = GetAllProtos(orig, modified);

for (auto proto : protos) {
const Layer *l1 = GetLayer(orig, proto);
const Layer *l2 = GetLayer(modified, proto);

if (l1 && l2)
ComputeDifferences(modifs, l1, l2);
else if (l1 && !l2 && !partial)
modifs->push_back(new Deletion(l1));
else if (!l1 && l2)
modifs->push_back(new Addition(l2));
}
}
return modifs;
}

Expand Down Expand Up @@ -166,47 +172,49 @@ Packet* TrimReplyIPv6(Packet *rcv, bool *partial)
return rcv;
}

PacketModifications* PacketModifications::ComputeModifications(Crafter::Packet *pkt,
Crafter::Packet **rcv)
PacketModifications* PacketModifications::ComputeModifications(
std::shared_ptr<Crafter::Packet> pkt, Crafter::Packet *rcv)
{
ICMPLayer *icmp = (*rcv)->GetLayer<ICMPLayer>();
RawLayer *raw = (*rcv)->GetLayer<RawLayer>();
bool partial = false;
int proto = pkt->GetLayer<IPLayer>()->GetID();

if (icmp && raw) {
Packet *cnt = new Packet((*rcv)->GetTimestamp());
switch (proto) {
case IP::PROTO:
cnt->PacketFromIP(*raw);
/* We might receive an ICMP without the complete
* echoed packet or with ICMP extensions. We thus
* remove undesired parts and parse partial headers.
*/
cnt = TrimReplyIPv4(cnt, &partial);
break;
case IPv6::PROTO:
cnt->PacketFromIPv6(*raw);
cnt = TrimReplyIPv6(cnt, &partial);
break;
default:
delete cnt;
return NULL;
if (rcv) {
ICMPLayer *icmp = rcv->GetLayer<ICMPLayer>();
RawLayer *raw = rcv->GetLayer<RawLayer>();
int proto = pkt->GetLayer<IPLayer>()->GetID();

if (icmp && raw) {
Packet *cnt = new Packet(rcv->GetTimestamp());
switch (proto) {
case IP::PROTO:
cnt->PacketFromIP(*raw);
/* We might receive an ICMP without the complete
* echoed packet or with ICMP extensions. We thus
* remove undesired parts and parse partial headers.
*/
cnt = TrimReplyIPv4(cnt, &partial);
break;
case IPv6::PROTO:
cnt->PacketFromIPv6(*raw);
cnt = TrimReplyIPv6(cnt, &partial);
break;
default:
delete cnt;
cnt = NULL;
}

delete rcv;
rcv = cnt;
}

delete *rcv;
*rcv = cnt;
}

return ComputeDifferences(pkt, *rcv, partial);
return ComputeDifferences(pkt, rcv, partial);
}

Modification::Modification(int proto, std::string name, size_t offset, size_t len) :
layer_proto(proto), name(name), offset(offset), len(len)
Modification::Modification(int proto, std::string name, size_t offset,
size_t len) : layer_proto(proto), name(name), offset(offset), len(len)
{
}

Modification::Modification(int proto, FieldInfo *f1, FieldInfo *f2) : layer_proto(proto)
Modification::Modification(int proto, const FieldInfo *f1,
const FieldInfo *f2) : layer_proto(proto)
{
Layer *l = Protocol::AccessFactory()->GetLayerByID(proto);
std::ostringstream sf1, sf2;
Expand All @@ -222,7 +230,8 @@ Modification::Modification(int proto, FieldInfo *f1, FieldInfo *f2) : layer_prot
field2_repr = sf2.str();
}

Modification::Modification(Layer *l1, Layer *l2) : layer_proto(l1->GetID()), name(l1->GetName()),
Modification::Modification(const Layer *l1, const Layer *l2) :
layer_proto(l1->GetID()), name(l1->GetName()),
offset(0), len(l1->GetSize())
{
std::ostringstream sf1, sf2;
Expand All @@ -241,7 +250,8 @@ void Modification::Print(std::ostream& out, bool verbose) const
out << GetModifRepr();
}

void Modification::Print_JSON(json_object *res, json_object *add, json_object *del, bool verbose) const
void Modification::Print_JSON(json_object *res, json_object *add,
json_object *del, bool verbose) const
{
if (verbose)
{
Expand All @@ -261,8 +271,10 @@ json_object* Modification::GetModifRepr_JSON() const
{
json_object *modif = json_object_new_object();
if (field1_repr != "" && field2_repr != ""){
json_object_object_add(modif,"Expected", json_object_new_string(field1_repr.c_str()));
json_object_object_add(modif,"Received", json_object_new_string(field2_repr.c_str()));
json_object_object_add(modif, "Expected",
json_object_new_string(field1_repr.c_str()));
json_object_object_add(modif, "Received",
json_object_new_string(field2_repr.c_str()));
}
return modif;
}
Expand All @@ -274,7 +286,7 @@ std::string Modification::GetModifRepr() const
return "";
}

Addition::Addition(Layer *l) : Modification(l, l)
Addition::Addition(const Layer *l) : Modification(l, l)
{
}

Expand All @@ -285,13 +297,15 @@ void Addition::Print(std::ostream& out, bool verbose) const
out << " " << field1_repr;
}

void Addition::Print_JSON(json_object *res, json_object *add, json_object *del, bool verbose) const
void Addition::Print_JSON(json_object *res, json_object *add,
json_object *del, bool verbose) const
{
if (verbose)
{
json_object *modif = json_object_new_object();

json_object_object_add(modif,"Info", json_object_new_string(field1_repr.c_str()));
json_object_object_add(modif,"Info",
json_object_new_string(field1_repr.c_str()));

json_object *modif_header = json_object_new_object();
json_object_object_add(modif_header,GetName().c_str(), modif);
Expand All @@ -304,7 +318,7 @@ void Addition::Print_JSON(json_object *res, json_object *add, json_object *del,
}
}

Deletion::Deletion(Layer *l) : Modification(l, l)
Deletion::Deletion(const Layer *l) : Modification(l, l)
{
}

Expand All @@ -315,13 +329,15 @@ void Deletion::Print(std::ostream& out, bool verbose) const
out << " " << field1_repr;
}

void Deletion::Print_JSON(json_object *res, json_object *add, json_object *del, bool verbose) const
void Deletion::Print_JSON(json_object *res, json_object *add,
json_object *del, bool verbose) const
{
if (verbose)
{
json_object *modif = json_object_new_object();

json_object_object_add(modif,"Info", json_object_new_string(field1_repr.c_str()));
json_object_object_add(modif,"Info",
json_object_new_string(field1_repr.c_str()));

json_object *modif_header = json_object_new_object();
json_object_object_add(modif_header,GetName().c_str(), modif);
Expand All @@ -344,7 +360,8 @@ void PacketModifications::Print(std::ostream& out, bool verbose) const
}
}

void PacketModifications::Print_JSON(json_object *res,json_object *icmp, json_object *add, json_object *del, bool verbose) const
void PacketModifications::Print_JSON(json_object *res,json_object *icmp,
json_object *add, json_object *del, bool verbose) const
{
for(const_iterator it = begin() ; it != end() ; it++) {
(*it)->Print_JSON(res, add, del, verbose);
Expand All @@ -353,10 +370,7 @@ void PacketModifications::Print_JSON(json_object *res,json_object *icmp, json_ob

PacketModifications::~PacketModifications()
{
delete orig;

for(const_iterator it = begin() ; it != end() ; it++)
delete *it;

clear();
}
46 changes: 33 additions & 13 deletions src/tracebox/PacketModification.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <json-c/json.h>
#endif

#include <memory>

using namespace Crafter;

class Modification {
Expand Down Expand Up @@ -44,8 +46,8 @@ class Modification {

public:
Modification(int proto, std::string name, size_t offset, size_t len);
Modification(int proto, FieldInfo *f1, FieldInfo *f2);
Modification(Layer *l1, Layer *l2);
Modification(int proto, const FieldInfo *f1, const FieldInfo *f2);
Modification(const Layer *l1, const Layer *l2);

int getOffset() const {
return offset;
Expand All @@ -65,40 +67,58 @@ class Modification {

virtual ~Modification() {}

virtual void Print(std::ostream& out = std::cout, bool verbose = false) const;
virtual void Print(std::ostream& out = std::cout,
bool verbose = false) const;

virtual void Print_JSON(json_object *res = json_object_new_array(), json_object *add = json_object_new_array(), json_object *del = json_object_new_array(), bool verbose = false) const;
virtual void Print_JSON(json_object *res = json_object_new_array(),
json_object *add = json_object_new_array(),
json_object *del = json_object_new_array(),
bool verbose = false) const;
};

struct Addition : public Modification {
Addition(Layer *l);
Addition(const Layer *l);

virtual void Print(std::ostream& out, bool verbose = false) const;

virtual void Print_JSON(json_object *res = json_object_new_array(), json_object *add = json_object_new_array(), json_object *del = json_object_new_array(), bool verbose = false) const;
virtual void Print_JSON(json_object *res = json_object_new_array(),
json_object *add = json_object_new_array(),
json_object *del = json_object_new_array(),
bool verbose = false) const;
};

struct Deletion : public Modification {
Deletion(Layer *l);
Deletion(const Layer *l);

virtual void Print(std::ostream& out, bool verbose = false) const;

virtual void Print_JSON(json_object *res = json_object_new_array(), json_object *add = json_object_new_array(), json_object *del = json_object_new_array(), bool verbose = false) const;
virtual void Print_JSON(json_object *res = json_object_new_array(),
json_object *add = json_object_new_array(),
json_object *del = json_object_new_array(),
bool verbose = false) const;
};

struct PacketModifications : public std::vector<Modification *> {
Packet *orig;
Packet *modif;
const std::shared_ptr<const Packet> orig;
const std::shared_ptr<const Packet> modif;
bool partial;

PacketModifications(Packet *orig, Packet *modif, bool partial=false) : orig(new Packet(*orig)), modif(modif), partial(partial) { }
PacketModifications(const std::shared_ptr<Packet> orig,
const Packet *modif, bool partial=false) :
orig(orig), modif(modif), partial(partial) {}
~PacketModifications();

void Print(std::ostream& out = std::cout, bool verbose = false) const;

static PacketModifications* ComputeModifications(Crafter::Packet *pkt, Crafter::Packet **rcv);
static PacketModifications* ComputeModifications(
const std::shared_ptr<Crafter::Packet> pkt,
Crafter::Packet *rcv);

void Print_JSON(json_object *res = json_object_new_array(), json_object *icmp = json_object_new_array(), json_object *add = json_object_new_array(), json_object *del = json_object_new_array(), bool verbose = false) const;
void Print_JSON(json_object *res = json_object_new_array(),
json_object *icmp = json_object_new_array(),
json_object *add = json_object_new_array(),
json_object *del = json_object_new_array(),
bool verbose = false) const;
};

#endif
4 changes: 3 additions & 1 deletion src/tracebox/examples/test_ftp.tbx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ ip_port = syn:source():gsub("%.", ",")
data = IP / tcp{src=syn:tcp():getsource(), dst=21, seq=syn:tcp():getseq()+1,
ack=synack:tcp():getseq()+1, flags=16} / raw('PORT '.. ip_port .. ',189,68\r\n')

function cb(ttl, rip, pkt, reply, mods)
function cb(ttl, rip, mods)
pkt = mods:original()
reply = mods:received()
if mods and mods:__tostring():find("Raw") then
print("There is a NAT_FTP before " .. rip)
return 1
Expand Down
2 changes: 1 addition & 1 deletion src/tracebox/lua.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Packet *script_packet(std::string& cmd)

lua_getglobal(l, "pkt");
/* As we'll clean the lua state, copy the produced packet */
Packet *pkt = new Packet(*l_packet_ref::get(l, -1));
Packet *pkt = new Packet(*l_packet_ref::extract(l, -1));
if (!pkt)
return NULL;

Expand Down
Loading

0 comments on commit 3e133e9

Please sign in to comment.