bool decode(const RawData&, CodecData&, DecodeData&) override;
void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
uint16_t lyr_len, uint32_t& updated_len) override;
void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
******************** E N C O D E R ******************************
******************************************************************/
bool Ipv4Codec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
- EncState& enc, Buffer& buf)
+ EncState& enc, Buffer& buf, Flow*)
{
if (!buf.allocate(ip::IP4_HEADER_LEN))
return false;
void get_protocol_ids(std::vector<ProtocolId>& v) override;
bool decode(const RawData&, CodecData&, DecodeData&) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
uint16_t lyr_len, uint32_t& updated_len) override;
void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
******************************************************************/
bool Ipv6Codec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
- EncState& enc, Buffer& buf)
+ EncState& enc, Buffer& buf, Flow*)
{
if (!buf.allocate(sizeof(ip::IP6Hdr)))
return false;
void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
bool decode(const RawData&, CodecData&, DecodeData&) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
uint16_t lyr_len, uint32_t& updated_len) override;
void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
//-------------------------------------------------------------------------
bool TcpCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
- EncState& enc, Buffer& buf)
+ EncState& enc, Buffer& buf, Flow*)
{
const tcp::TCPHdr* const hi = reinterpret_cast<const tcp::TCPHdr*>(raw_in);
bool decode(const RawData&, CodecData&, DecodeData&) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
uint16_t lyr_len, uint32_t& updated_len) override;
void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
******************************************************************/
bool UdpCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
- EncState& enc, Buffer& buf)
+ EncState& enc, Buffer& buf, Flow*)
{
// If we enter this function, this packe is some sort of tunnel.
void get_protocol_ids(std::vector<ProtocolId>& v) override;
bool decode(const RawData&, CodecData&, DecodeData&) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
};
}
bool FabricPathCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
- EncState& enc, Buffer& buf)
+ EncState& enc, Buffer& buf, Flow*)
{
// not raw ip -> encode layer 2
bool raw = ( enc.flags & ENC_FLAG_RAW );
#include "protocols/mpls.h"
#include "main/snort_config.h"
#include "log/text_log.h"
+#include "utils/safec.h"
#define CD_MPLS_NAME "mpls"
#define CD_MPLS_HELP "support for multiprotocol label switching"
void get_protocol_ids(std::vector<ProtocolId>& v) override;
bool decode(const RawData&, CodecData&, DecodeData&) override;
+ bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
+ EncState&, Buffer&, Flow*) override;
void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
private:
return true;
}
+bool MplsCodec::encode(const uint8_t* const raw_in, const uint16_t raw_len,
+ EncState& enc, Buffer& buf, Flow* pflow)
+{
+ uint16_t hdr_len = raw_len;
+ const uint8_t* hdr_start = raw_in;
+ if( pflow )
+ {
+ Layer mpls_lyr = pflow->get_mpls_layer_per_dir(enc.forward());
+
+ if( mpls_lyr.length )
+ {
+ hdr_len = mpls_lyr.length;
+ hdr_start = mpls_lyr.start;
+ }
+
+ }
+
+ if (!buf.allocate(hdr_len))
+ return false;
+
+ memcpy_s(buf.data(), hdr_len, hdr_start, hdr_len);
+ enc.next_ethertype = ProtocolId::ETHERTYPE_NOT_SET;
+ enc.next_proto = IpProtocol::PROTO_NOT_SET;
+
+ return true;
+}
/*
* check if reserved labels are used properly
bool decode(const RawData&, CodecData&, DecodeData&) override final;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override final;
+ EncState&, Buffer&, Flow*) override final;
protected:
PPPoECodec(const char* s, PppoepktType type) :
******************************************************************/
bool PPPoECodec::encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer& buf)
+ EncState&, Buffer& buf, Flow*)
{
if (!buf.allocate(raw_len))
return false;
void get_protocol_ids(std::vector<ProtocolId>& v) override;
bool decode(const RawData&, CodecData&, DecodeData&) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
uint16_t lyr_len, uint32_t& updated_len) override;
};
}
bool GtpCodec::encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer& buf)
+ EncState&, Buffer& buf, Flow*)
{
if (buf.allocate(raw_len))
return false;
void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
bool decode(const RawData&, CodecData&, DecodeData&) override;
bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
- EncState&, Buffer&) override;
+ EncState&, Buffer&, Flow*) override;
void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
uint16_t lyr_len, uint32_t& updated_len) override;
//-------------------------------------------------------------------------
bool EthCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
- EncState& enc, Buffer& buf)
+ EncState& enc, Buffer& buf, Flow*)
{
const eth::EtherHdr* hi = reinterpret_cast<const eth::EtherHdr*>(raw_in);
if ( ha_state )
delete ha_state;
+
+ if ( clientMplsLyr.length )
+ {
+ delete[] clientMplsLyr.start;
+ clientMplsLyr.length = 0;
+ }
+ if ( serverMplsLyr.length )
+ {
+ delete[] serverMplsLyr.start;
+ serverMplsLyr.length = 0;
+ }
}
void Flow::reset(bool do_cleanup)
free_application_data();
+ if ( clientMplsLyr.length )
+ {
+ delete[] clientMplsLyr.start;
+ clientMplsLyr.length = 0;
+ }
+ if ( serverMplsLyr.length )
+ {
+ delete[] serverMplsLyr.start;
+ serverMplsLyr.length = 0;
+ }
+
// FIXIT-M cleanup() winds up calling clear()
if ( ssn_client )
{
if ( free_flow_data )
free_application_data();
+ if ( clientMplsLyr.length )
+ {
+ delete[] clientMplsLyr.start;
+ clientMplsLyr.length = 0;
+ }
+ if ( serverMplsLyr.length )
+ {
+ delete[] serverMplsLyr.start;
+ serverMplsLyr.length = 0;
+ }
+
bitop->reset();
ssn_state.ignore_direction = 0;
payloadAppId = application_ids[APP_PROTOID_PAYLOAD];
miscAppId = application_ids[APP_PROTOID_MISC];
}
+
+void Flow::set_mpls_layer_per_dir(Packet* p)
+{
+ const Layer* mpls_lyr = layer::get_mpls_layer(p);
+
+ if ( !mpls_lyr || !(mpls_lyr->start) )
+ return;
+
+ if ( p->packet_flags & PKT_FROM_CLIENT )
+ {
+ if ( !clientMplsLyr.length )
+ {
+ clientMplsLyr.length = mpls_lyr->length;
+ clientMplsLyr.prot_id = mpls_lyr->prot_id;
+ clientMplsLyr.start = new uint8_t[mpls_lyr->length];
+ memcpy((void *)clientMplsLyr.start, mpls_lyr->start, mpls_lyr->length);
+ }
+ }
+ else
+ {
+ if ( !serverMplsLyr.length )
+ {
+ serverMplsLyr.length = mpls_lyr->length;
+ serverMplsLyr.prot_id = mpls_lyr->prot_id;
+ serverMplsLyr.start = new uint8_t[mpls_lyr->length];
+ memcpy((void *)serverMplsLyr.start, mpls_lyr->start, mpls_lyr->length);
+ }
+ }
+}
+
+Layer Flow::get_mpls_layer_per_dir(bool client)
+{
+ if ( client )
+ return clientMplsLyr;
+ else
+ return serverMplsLyr;
+}
int get_expire(const Packet*);
bool expired(const Packet*);
void set_ttl(Packet*, bool client);
+ void set_mpls_layer_per_dir(Packet*);
+ Layer get_mpls_layer_per_dir(bool);
uint32_t update_session_flags( uint32_t flags )
{
Inspector* gadget; // service handler
Inspector* data;
const char* service;
+ Layer clientMplsLyr, serverMplsLyr;
unsigned policy_id;
flow->set_direction(p);
+ // This requires the packet direction to be set
+ if ( p->proto_bits & PROTO_BIT__MPLS )
+ flow->set_mpls_layer_per_dir(p);
+
switch ( flow->flow_state )
{
case Flow::FlowState::SETUP:
struct _daq_pkthdr;
struct Packet;
struct Layer;
+class Flow;
enum CodecSid : uint32_t;
namespace ip
virtual bool encode(const uint8_t* const /*raw_in */,
const uint16_t /*raw_len*/,
EncState&,
- Buffer&)
+ Buffer&, Flow*)
{ return true; }
/*
#include "pp_enc_state_iface.h"
#include "pp_ip_api_iface.h"
#include "pp_raw_buffer_iface.h"
+#include "pp_flow_iface.h"
// FIXIT-M delete this, and make the IpApi arg in codec.update required
static const ip::IpApi default_ip_api {};
auto& rb = RawBufferIface.get(L, 1); // raw_in
auto& es = EncStateIface.get(L, 2);
auto& b = BufferIface.get(L, 3);
+ auto& flow = FlowIface.get(L, 4);
auto& self = CodecIface.get(L);
- bool result = self.encode(get_data(rb), rb.size(), es, b);
+ bool result = self.encode(get_data(rb), rb.size(), es, b, &flow);
lua_pushboolean(L, result);
return nullptr;
}
+static inline const Layer* find_layer(const Layer* lyr,
+ uint8_t num_layers,
+ ProtocolId prot_id1,
+ ProtocolId prot_id2)
+{
+ int tmp = num_layers-1;
+ lyr = &lyr[tmp];
+
+ for (int i = num_layers - 1; i >= 0; i--)
+ {
+ if (lyr->prot_id == prot_id1 ||
+ lyr->prot_id == prot_id2)
+ return lyr;
+ lyr--;
+ }
+ return nullptr;
+}
+
void set_packet_pointer(const Packet* const p)
{ curr_pkt = p; }
find_inner_layer(lyr, num_layers, ProtocolId::ETHERTYPE_EAPOL));
}
+const Layer* get_mpls_layer(const Packet* const p)
+{
+ uint8_t num_layers = p->num_layers;
+ const Layer* lyr = p->layers;
+
+ return find_layer(lyr, num_layers, ProtocolId::ETHERTYPE_MPLS_UNICAST,
+ ProtocolId::ETHERTYPE_MPLS_MULTICAST);
+}
+
const vlan::VlanTagHdr* get_vlan_layer(const Packet* const p)
{
uint8_t num_layers = p->num_layers;
SO_PUBLIC const udp::UDPHdr* get_outer_udp_lyr(const Packet* const);
// return the inner ip layer's index in the p->layers array
SO_PUBLIC int get_inner_ip_lyr_index(const Packet* const p);
+SO_PUBLIC const Layer* get_mpls_layer(const Packet* const p);
// Two versions of this because ip_defrag:: wants to call this on
// its rebuilt packet, not on the current packet. Extra function
const Layer& l = lyrs[i];
ProtocolIndex mapped_prot =
i ? CodecManager::s_proto_map[to_utype(l.prot_id)] : CodecManager::grinder;
- if (!CodecManager::s_protocols[mapped_prot]->encode(l.start, l.length, enc, buf))
+ if (!CodecManager::s_protocols[mapped_prot]->encode(l.start, l.length, enc, buf, p->flow))
{
return false;
}
ProtocolIndex mapped_prot =
i ? CodecManager::s_proto_map[to_utype(l.prot_id)] : CodecManager::grinder;
- if (!CodecManager::s_protocols[mapped_prot]->encode(l.start, l.length, enc, buf))
+ if (!CodecManager::s_protocols[mapped_prot]->encode(l.start, l.length, enc, buf, p->flow))
{
return false;
}