From: Josh Date: Fri, 1 Aug 2014 17:30:05 +0000 (-0400) Subject: updating packet. Still minor updates X-Git-Tag: 3.0.0-233~1430^2~1^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=70e4fcd6202aa16b4e258912318a484289e7f1cf;p=thirdparty%2Fsnort3.git updating packet. Still minor updates --- diff --git a/doc/differences.txt b/doc/differences.txt index 2803f4987..09a0db63e 100644 --- a/doc/differences.txt +++ b/doc/differences.txt @@ -93,7 +93,7 @@ Snort++ differs from Snort in the following ways: uricontent:"foo" --> http_uri; content:"foo" * deleted urilen raw and norm; must use http_raw_uri and http_uri instead * deleted unused http_encode option -* content suboption http_* are no full option and should be place before content +* content suboption http_* are not full option and should be place before content * the following pcre options have been deleted: use sticky buffers instead B, U, P, H, M, C, I, D, K, S, Y diff --git a/src/codecs/decode_module.h b/src/codecs/decode_module.h index 06eedd508..d1eddc94e 100644 --- a/src/codecs/decode_module.h +++ b/src/codecs/decode_module.h @@ -201,6 +201,7 @@ enum CodecSid { DECODE_ERSPAN3_DGRAM_LT_HDR, DECODE_AUTH_HDR_TRUNC, DECODE_AUTH_HDR_BAD_LEN, + DECODE_TOO_MANY_LAYERS, DECODE_INDEX_MAX }; diff --git a/src/codecs/ip/cd_dstopts.cc b/src/codecs/ip/cd_dstopts.cc index 2a80b2e10..9053e5d2d 100644 --- a/src/codecs/ip/cd_dstopts.cc +++ b/src/codecs/ip/cd_dstopts.cc @@ -117,7 +117,7 @@ void Ipv6DSTOptsCodec::get_protocol_ids(std::vector& v) bool Ipv6DSTOptsCodec::update(Packet* p, Layer* lyr, uint32_t* len) { - if ( lyr == (p->layers + p->next_layer - 1) ) + if ( lyr == (p->layers + p->num_layers - 1) ) *len += p->dsize; *len += lyr->length; diff --git a/src/codecs/ip/cd_gre.cc b/src/codecs/ip/cd_gre.cc index 0eb04559d..ba803b90e 100644 --- a/src/codecs/ip/cd_gre.cc +++ b/src/codecs/ip/cd_gre.cc @@ -103,14 +103,7 @@ bool GreCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, return false; } - if (p->encapsulated) - { - /* discard packet - multiple GRE encapsulation */ - /* not sure if this is ever used but I am assuming it is not */ - codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, - raw_pkt, raw_len); - return false; - } + p->encapsulations++; /* Note: Since GRE doesn't have a field to indicate header length and * can contain a few options, we need to walk through the header to diff --git a/src/codecs/ip/cd_hopopts.cc b/src/codecs/ip/cd_hopopts.cc index c99eb46f6..d2f5d877d 100644 --- a/src/codecs/ip/cd_hopopts.cc +++ b/src/codecs/ip/cd_hopopts.cc @@ -115,7 +115,7 @@ void Ipv6HopOptsCodec::get_protocol_ids(std::vector& v) bool Ipv6HopOptsCodec::update(Packet* p, Layer* lyr, uint32_t* len) { - if ( lyr == (p->layers + p->next_layer - 1) ) + if ( lyr == (p->layers + p->num_layers - 1) ) *len += p->dsize; *len += lyr->length; diff --git a/src/codecs/ip/cd_icmp6.cc b/src/codecs/ip/cd_icmp6.cc index ed13f121e..54a7369fc 100644 --- a/src/codecs/ip/cd_icmp6.cc +++ b/src/codecs/ip/cd_icmp6.cc @@ -334,7 +334,7 @@ static void DecodeICMPEmbeddedIP6(const uint8_t *pkt, const uint32_t len, Packet // uint16_t orig_frag_offset; /* lay the IP struct over the raw data */ - ipv6::IP6RawHdr* hdr = (ipv6::IP6RawHdr*)pkt; + const ipv6::IP6RawHdr* hdr = reinterpret_cast(pkt); DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP6: ip header" " starts at: %p, length is %lu\n", hdr, diff --git a/src/codecs/ip/cd_ipv4.cc b/src/codecs/ip/cd_ipv4.cc index 03122f1eb..e5e26b446 100644 --- a/src/codecs/ip/cd_ipv4.cc +++ b/src/codecs/ip/cd_ipv4.cc @@ -180,22 +180,18 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, return false; } - if (p->family != NO_IP) + if (p->encapsulations) { - if (p->encapsulated) - { + if (p->encapsulations) codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, raw_pkt, raw_len); - return false; - } - else - { - p->encapsulated = 1; - p->outer_iph = p->iph; - p->outer_ip_data = p->ip_data; - p->outer_ip_dsize = p->ip_dsize; - } + + p->encapsulations++; + p->outer_iph = p->iph; + p->outer_ip_data = p->ip_data; + p->outer_ip_dsize = p->ip_dsize; + } /* lay the IP struct over the raw data */ @@ -311,7 +307,7 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, * Zero these options so they aren't associated with this inner IP * since p->iph will be pointing to this inner IP */ - if (p->encapsulated) + if (p->encapsulations) { p->ip_options_data = NULL; p->ip_options_len = 0; @@ -692,7 +688,7 @@ bool Ipv4Codec::update(Packet* p, Layer* lyr, uint32_t* len) *len += ipv4::get_pkt_len(h); - if ( i + 1 == p->next_layer ) + if ( i + 1 == p->num_layers ) { *len += p->dsize; } @@ -724,7 +720,7 @@ void Ipv4Codec::format(EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) if ( f & ENC_FLAG_DEF ) { int i = lyr - c->layers; - if ( i + 1 == p->next_layer ) + if ( i + 1 == p->num_layers ) { lyr->length = sizeof(*ch); ch->ip_len = htons(lyr->length); diff --git a/src/codecs/ip/cd_ipv6.cc b/src/codecs/ip/cd_ipv6.cc index 47404c104..d0748462b 100644 --- a/src/codecs/ip/cd_ipv6.cc +++ b/src/codecs/ip/cd_ipv6.cc @@ -162,22 +162,13 @@ bool Ipv6Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, // This will need to go if (p->family != NO_IP) { - /* Snort currently supports only 2 IP layers. Any more will fail to be - decoded. */ - if (p->encapsulated) - { - + if (p->encapsulations) codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, raw_pkt, raw_len); - goto decodeipv6_fail; - } - else - { - p->encapsulated = 1; - p->outer_iph = p->iph; - p->outer_ip_data = p->ip_data; - p->outer_ip_dsize = p->ip_dsize; - } + + p->outer_iph = p->iph; + p->outer_ip_data = p->ip_data; + p->outer_ip_dsize = p->ip_dsize; } payload_len = ntohs(hdr->ip6plen) + ipv6::hdr_len(); @@ -216,7 +207,7 @@ bool Ipv6Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, sfiph_build(p, hdr, AF_INET6); /* Remove outer IP options */ - if (p->encapsulated) + if (p->encapsulations) { p->ip_options_data = NULL; p->ip_options_len = 0; @@ -624,7 +615,7 @@ bool Ipv6Codec::update (Packet* p, Layer* lyr, uint32_t* len) } else { - if ( i + 1 == p->next_layer ) + if ( i + 1 == p->num_layers ) *len += lyr->length + p->dsize; // w/o all extension headers, can't use just the @@ -654,7 +645,7 @@ void Ipv6Codec::format(EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) if ( f & ENC_FLAG_DEF ) { int i = lyr - c->layers; - if ( i + 1 == p->next_layer ) + if ( i + 1 == p->num_layers ) { uint8_t* b = (uint8_t*)p->ip6_extensions[p->ip6_frag_index].data; if ( b ) lyr->length = b - p->layers[i].start; diff --git a/src/codecs/link/cd_erspan2.cc b/src/codecs/link/cd_erspan2.cc index 1acea62ba..cdd00e7f1 100644 --- a/src/codecs/link/cd_erspan2.cc +++ b/src/codecs/link/cd_erspan2.cc @@ -91,14 +91,8 @@ bool Erspan2Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, return false; } - if (p->encapsulated) - { - /* discard packet - multiple encapsulation */ - /* not sure if this is ever used but I am assuming it is not */ - codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, - raw_pkt, raw_len); - return false; - } + p->encapsulations++; + /* Check that this is in fact ERSpan Type 2. */ diff --git a/src/codecs/link/cd_erspan3.cc b/src/codecs/link/cd_erspan3.cc index 369ca523b..0466d48d9 100644 --- a/src/codecs/link/cd_erspan3.cc +++ b/src/codecs/link/cd_erspan3.cc @@ -115,14 +115,7 @@ bool Erspan3Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, return false; } - if (p->encapsulated) - { - /* discard packet - multiple encapsulation */ - /* not sure if this is ever used but I am assuming it is not */ - codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, - raw_pkt, raw_len); - return false; - } + p->encapsulations++; /* Check that this is in fact ERSpan Type 3. */ diff --git a/src/codecs/link/cd_vlan.cc b/src/codecs/link/cd_vlan.cc index 6a5ca791a..f6db4fe05 100644 --- a/src/codecs/link/cd_vlan.cc +++ b/src/codecs/link/cd_vlan.cc @@ -157,9 +157,22 @@ bool VlanCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, } else { + uint16_t vid = vlan::vth_vlan(vh); + + // Vlan IDs 0 and 4095 are reserved. + if (vid == 0 || vid == 4095) + { + codec_events::decoder_event(p, DECODE_BAD_VLAN); + + // TBD add decoder drop event for VLAN hdr len issue + p->iph = NULL; + p->family = NO_IP; + return false; + } + + lyr_len = sizeof(vlan::VlanTagHdr); next_prot_id = ntohs(vh->vth_proto); - } p->proto_bits |= PROTO_BIT__VLAN; diff --git a/src/codecs/misc/cd_gtp.cc b/src/codecs/misc/cd_gtp.cc index c458fe0f4..f8ee9a41a 100644 --- a/src/codecs/misc/cd_gtp.cc +++ b/src/codecs/misc/cd_gtp.cc @@ -90,22 +90,16 @@ bool GtpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len, uint8_t next_hdr_type; uint8_t version; uint8_t ip_ver; - GTPHdr *hdr; + const GTPHdr *hdr; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Start GTP decoding.\n");); - hdr = (GTPHdr *) raw_pkt; + p->encapsulations++; + + hdr = reinterpret_cast(raw_pkt); + + - if (p->GTPencapsulated) - { - codec_events::decoder_alert_encapsulated(p, DECODE_GTP_MULTIPLE_ENCAPSULATION, - raw_pkt, raw_len); - return false; - } - else - { - p->GTPencapsulated = 1; - } /*Check the length*/ if (raw_len < GTP_MIN_LEN) return false; diff --git a/src/codecs/root/root_ppp.cc b/src/codecs/root/root_ppp.cc index ad93a5d2c..dc33f4959 100644 --- a/src/codecs/root/root_ppp.cc +++ b/src/codecs/root/root_ppp.cc @@ -26,13 +26,11 @@ #include "config.h" #endif -#include "generators.h" -#include "protocols/packet.h" -#include "static_include.h" -#include "root_ppp.h" -#include "../decoder_includes.h" -#include "protocols/root/root_chdlc.h" +#include "framework/codec.h" + + +static int DLT_PPP = 51; /* @@ -55,18 +53,6 @@ void DecodePppPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; int hlen = 0; - PROFILE_VARS; - - PREPROC_PROFILE_START(decodePerfStats); - - dc.total_processed++; - - memset(p, 0, PKT_ZERO_LEN); - - p->pkth = pkthdr; - p->pkt = pkt; - - DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); if(cap_len < 2) { @@ -89,7 +75,6 @@ void DecodePppPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) DecodePppPktEncapsulated(p->pkt + hlen, cap_len - hlen, p); - PREPROC_PROFILE_END(decodePerfStats); return; } diff --git a/src/events/event_queue.cc b/src/events/event_queue.cc index 5058858b3..949957aca 100644 --- a/src/events/event_queue.cc +++ b/src/events/event_queue.cc @@ -133,7 +133,7 @@ int SnortEventqAdd(OptTreeNode* otn) EventNode* en = (EventNode*)sfeventq_event_alloc(event_queue[qIndex]); - if ( !en ) + if ( en ) return -1; en->otn = otn; diff --git a/src/log/log_text.cc b/src/log/log_text.cc index 66306f73e..6063caa6a 100644 --- a/src/log/log_text.cc +++ b/src/log/log_text.cc @@ -408,23 +408,23 @@ void Log2ndHeader(TextLog* log, Packet* p) switch(DAQ_GetBaseProtocol()) { case DLT_EN10MB: /* Ethernet */ - if(p && (p->next_layer > 0)) + if(p && (p->num_layers > 0)) LogEthHeader(log, p); break; #ifndef NO_NON_ETHER_DECODER #ifdef DLT_IEEE802_11 case DLT_IEEE802_11: - if(p && (p->next_layer > 0)) + if(p && (p->num_layers > 0)) LogWifiHeader(log, p); break; #endif case DLT_IEEE802: /* Token Ring */ - if(p && (p->next_layer > 0)) + if(p && (p->num_layers > 0)) LogTrHeader(log, p); break; #ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: - if (p && (p->next_layer > 0)) + if (p && (p->num_layers > 0)) LogSLLHeader(log, p); /* Linux cooked sockets */ break; #endif @@ -1019,8 +1019,8 @@ static void LogICMPEmbeddedIP(TextLog* log, Packet *p) orig_p->dp = p->orig_dp; orig_p->icmph = p->orig_icmph; orig_p->iph_api = p->orig_iph_api; - orig_p->ip4h = p->orig_ip4h; - orig_p->ip6h = p->orig_ip6h; +// orig_p->ip4h = p->orig_ip4h; +// orig_p->ip6h = p->orig_ip6h; orig_p->family = p->orig_family; if(orig_p->iph != NULL) @@ -1494,8 +1494,8 @@ void LogNetData (TextLog* log, const uint8_t* data, const int len, Packet *p) if(p && ScObfuscate() ) { - int next_layer = p->next_layer; - for ( i = 0; i < next_layer; i++ ) + int num_layers = p->num_layers; + for ( i = 0; i < num_layers; i++ ) { if ( p->layers[i].proto == PROTO_IP4 || p->layers[i].proto == PROTO_IP6 diff --git a/src/main/modules.cc b/src/main/modules.cc index d2eaefc3e..1fc35dd40 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -815,6 +815,9 @@ bool ActiveModule::set(const char*, Value& v, SnortConfig* sc) else if ( v.is("react") ) sc->react_page = SnortStrdup(v.get_string()); + else + return false; + return true; } @@ -1022,6 +1025,9 @@ static const Parameter network_params[] = { "new_ttl", Parameter::PT_INT, "1:255", "1", "use this value for responses and when normalizing" }, + { "max_encapsulations", Parameter::PT_INT, "-1:32", "-1", + "maximum number of encapsulations per packet" }, + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; @@ -1054,6 +1060,9 @@ bool NetworkModule::set(const char*, Value& v, SnortConfig* sc) else if ( v.is("new_ttl") ) p->new_ttl = (uint8_t)v.get_long(); + else if ( v.is("max_encapsulations") ) + sc->max_encapsulations = v.get_long(); + else return false; diff --git a/src/main/snort.h b/src/main/snort.h index 9bce3a96b..8c00f59c6 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -548,10 +548,15 @@ static inline uint32_t ScSoRuleMemcap(void) return snort_conf->so_rule_memcap; } -static inline bool ScTunnelBypassEnabled (uint8_t proto) +static inline bool ScTunnelBypassEnabled(uint8_t proto) { return !(snort_conf->tunnel_mask & proto); } +static inline int8_t ScMaxEncapsulations(void) +{ + return snort_conf->max_encapsulations; +} + #endif diff --git a/src/main/snort_config.h b/src/main/snort_config.h index 85e49dd65..7437b60b1 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -137,6 +137,7 @@ struct SnortConfig uint8_t enable_gtp; char *gtp_ports; uint8_t enable_esp; + int8_t max_encapsulations; int pkt_snaplen; diff --git a/src/managers/packet_manager.cc b/src/managers/packet_manager.cc index f20352f5f..2a97f3498 100644 --- a/src/managers/packet_manager.cc +++ b/src/managers/packet_manager.cc @@ -38,6 +38,8 @@ #include "protocols/ipv4.h" #include "protocols/ipv6.h" #include "codecs/ip/ipv6_util.h" +#include "codecs/codec_events.h" +#include "codecs/decode_module.h" // Encoder FOO #ifdef HAVE_DUMBNET_H @@ -106,9 +108,9 @@ static inline void push_layer(Packet *p, uint32_t len, Codec *const cd) { - if ( p->next_layer < LAYER_MAX ) + if ( p->num_layers < LAYER_MAX ) { - Layer& lyr = p->layers[p->next_layer++]; + Layer& lyr = p->layers[p->num_layers++]; lyr.proto = cd->get_proto_id(); lyr.prot_id = prot_id; lyr.start = (uint8_t*)hdr_start; @@ -121,45 +123,6 @@ static inline void push_layer(Packet *p, } } -static inline uint8_t* get_inner_ip_hdr(const Packet *p) -{ - const Layer *layers = p->layers; - - for (int i = p->next_layer-1; i >= 0; i--) - { - switch(layers[i].prot_id) - { - case ETHERTYPE_IPV4: - case ETHERTYPE_IPV6: - case IPPROTO_ID_IPIP: - case IPPROTO_ID_IPV6: - return layers[i].start; - default: - break; - } - } - return nullptr; -} - -static inline int get_inner_ip_lyr(const Packet *p) -{ - const Layer *layers = p->layers; - - for (int i = p->next_layer-1; i >= 0; i--) - { - switch(layers[i].prot_id) - { - case ETHERTYPE_IPV4: - case ETHERTYPE_IPV6: - case IPPROTO_ID_IPIP: - case IPPROTO_ID_IPV6: - return i; - default: - break; - } - } - return -1; -} /* * Begin search from index 1. 0 is a special case in that it is the default @@ -193,9 +156,9 @@ static const uint8_t* encode_packet( obuf.size = sizeof(s_pkt); // setting convenience pointers - enc->layer = p->next_layer; + enc->layer = p->num_layers; enc->p = p; - enc->ip_hdr = get_inner_ip_hdr(p); + enc->ip_hdr = p->layers[layer::get_inner_ip_lyr(p)].start; if ( ipv4::is_ipv4(*(enc->ip_hdr))) enc->ip_len = ipv4::get_pkt_len((IPHdr*) enc->ip_hdr); @@ -206,7 +169,7 @@ static const uint8_t* encode_packet( const Layer *lyrs = p->layers; - for(int i = p->next_layer-1; i >= 0; i--) + for(int i = p->num_layers-1; i >= 0; i--) { // lots of room for improvement const Layer *l = &lyrs[i]; @@ -455,6 +418,15 @@ void PacketManager::decode( // loop until the protocol id is no longer valid while(s_protocols[mapped_prot]->decode(pkt, len, p, lyr_len, prot_id)) { + // must be done here after decode and before push for case layer + // LAYER_MAX+1 is invalid or the default codec + if ( p->num_layers == LAYER_MAX ) + { + codec_events::decoder_event(p, DECODE_TOO_MANY_LAYERS); + PREPROC_PROFILE_END(decodePerfStats); + return false; + } + // internal statistics and record keeping push_layer(p, prev_prot_id, pkt, lyr_len, s_protocols[mapped_prot]); s_stats[mapped_prot + stat_offset]++; @@ -484,6 +456,12 @@ void PacketManager::decode( p->packet_flags |= PKT_TRUST; } + if (ScMaxEncapsulations() != -1 && + p->encapsulations > ScMaxEncapsulations()) + { + codec_events::decoder_event(p, DECODE_IP_MULTIPLE_ENCAPSULATION); + } + if (p->ip6_extension_count > 0) ipv6_util::CheckIPv6ExtensionOrder(p); @@ -570,7 +548,7 @@ SO_PUBLIC int PacketManager::encode_format_with_daq_info ( int i; Layer* lyr; int len; - int num_layers = p->next_layer; + int num_layers = p->num_layers; DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)c->pkth; uint8_t* pkt = (uint8_t*)c->pkt; @@ -601,7 +579,7 @@ SO_PUBLIC int PacketManager::encode_format_with_daq_info ( if ( f & ENC_FLAG_NET ) { - num_layers = get_inner_ip_lyr(p) + 1; + num_layers = layer::get_inner_ip_lyr(p) + 1; // TBD: is this an extraneous check? if (num_layers == 0) @@ -629,7 +607,7 @@ SO_PUBLIC int PacketManager::encode_format_with_daq_info ( } // setup payload info - c->next_layer = num_layers; + c->num_layers = num_layers; c->data = lyr->start + lyr->length; len = c->data - c->pkt; @@ -696,7 +674,7 @@ SO_PUBLIC void PacketManager::encode_update (Packet* p) p->actual_ip_len = 0; Layer *lyr = p->layers; - for ( i = p->next_layer - 1; i >= 0; i-- ) + for ( i = p->num_layers - 1; i >= 0; i-- ) { Layer *l = lyr + i; diff --git a/src/network_inspectors/binder/binder.cc b/src/network_inspectors/binder/binder.cc index 358ad8a83..ad3de6c06 100644 --- a/src/network_inspectors/binder/binder.cc +++ b/src/network_inspectors/binder/binder.cc @@ -29,6 +29,8 @@ using namespace std; #include "stream/stream_splitter.h" #include "managers/inspector_manager.h" #include "protocols/packet.h" +#include "protocols/vlan.h" +#include "protocols/layer.h" #include "stream/stream_api.h" #include "time/profiler.h" #include "utils/stats.h" @@ -174,6 +176,7 @@ int Binder::check_rules(Flow* flow, Packet* p) unsigned i, sz = bindings.size(); Port port = (p->packet_flags & PKT_FROM_CLIENT) ? p->dp : p->sp; + uint16_t vlan = vlan::vth_vlan(layer::get_vlan_layer(p)); for ( i = 0; i < sz; i++ ) { diff --git a/src/network_inspectors/normalize/norm.cc b/src/network_inspectors/normalize/norm.cc index 52fd8713f..4bd82f731 100644 --- a/src/network_inspectors/normalize/norm.cc +++ b/src/network_inspectors/normalize/norm.cc @@ -99,7 +99,7 @@ static const uint8_t MAX_EOL_PAD[TCP_OPTLENMAX] = { // go from inner to outer int Norm_Packet (NormalizerConfig* c, Packet* p) { - uint8_t lyr = p->next_layer; + uint8_t lyr = p->num_layers; int changes = 0; while ( lyr > 0 ) diff --git a/src/packet_io/active.cc b/src/packet_io/active.cc index 76d86afaa..e6677fc54 100644 --- a/src/packet_io/active.cc +++ b/src/packet_io/active.cc @@ -79,8 +79,8 @@ static int s_enabled = 0; static inline PROTO_ID GetInnerProto (const Packet* p) { - if ( !p->next_layer ) return PROTO_MAX; - return ( p->layers[p->next_layer-1].proto ); + if ( !p->num_layers ) return PROTO_MAX; + return ( p->layers[p->num_layers-1].proto ); } //-------------------------------------------------------------------- diff --git a/src/protocols/layer.cc b/src/protocols/layer.cc index c01fb7d0b..1441fda51 100644 --- a/src/protocols/layer.cc +++ b/src/protocols/layer.cc @@ -21,6 +21,8 @@ #include "protocols/packet.h" +#include "protocols/ipv4.h" +#include "protocols/ipv6.h" namespace layer { @@ -53,45 +55,45 @@ static inline const uint8_t *find_layer(const Layer *lyr, return nullptr; } -const arp::EtherARP* get_arp_layer(const Packet* p) +const arp::EtherARP* get_arp_layer(const Packet* const p) { - uint8_t num_layers = p->next_layer; + uint8_t num_layers = p->num_layers; const Layer *lyr = p->layers; return reinterpret_cast( find_layer(lyr, num_layers, ETHERTYPE_ARP, ETHERTYPE_REVARP)); } -const gre::GREHdr* get_gre_layer(const Packet* p) +const gre::GREHdr* get_gre_layer(const Packet* const p) { - uint8_t num_layers = p->next_layer; + uint8_t num_layers = p->num_layers; const Layer *lyr = p->layers; return reinterpret_cast( find_layer(lyr, num_layers, IPPROTO_ID_GRE)); } -const eapol::EtherEapol* get_eapol_layer(const Packet* p) +const eapol::EtherEapol* get_eapol_layer(const Packet* const p) { - uint8_t num_layers = p->next_layer; + uint8_t num_layers = p->num_layers; const Layer *lyr = p->layers; return reinterpret_cast( find_layer(lyr, num_layers, ETHERTYPE_EAPOL)); } -const vlan::VlanTagHdr* get_vlan_layer(const Packet* p) +const vlan::VlanTagHdr* get_vlan_layer(const Packet* const p) { - uint8_t num_layers = p->next_layer; + uint8_t num_layers = p->num_layers; const Layer *lyr = p->layers; return reinterpret_cast( find_layer(lyr, num_layers, ETHERTYPE_8021Q)); } -const eth::EtherHdr* get_eth_layer(const Packet* p) +const eth::EtherHdr* get_eth_layer(const Packet* const p) { - uint8_t num_layers = p->next_layer; + uint8_t num_layers = p->num_layers; const Layer *lyr = p->layers; // First, search for the inner eth layer (transbridging) @@ -102,12 +104,54 @@ const eth::EtherHdr* get_eth_layer(const Packet* p) return eh ? eh : reinterpret_cast(get_root_layer(p)); } -const uint8_t* get_root_layer(const Packet* p) +const uint8_t* get_root_layer(const Packet* const p) { // since token ring is the grinder, its the begining of the packet. - if (p->next_layer > 0) + if (p->num_layers > 0) return p->layers[0].start; return nullptr; } + +uint8_t get_outer_ip_next_pro(const Packet* const p) +{ + const Layer* layers = p->layers; + const int max_layers = p->num_layers; + + for (int i = 0; i < max_layers; i++) + { + switch(layers[i].prot_id) + { + case ETHERTYPE_IPV4: + case IPPROTO_ID_IPIP: + return reinterpret_cast(layers[i].start)->ip_proto; + case ETHERTYPE_IPV6: + case IPPROTO_ID_IPV6: + return reinterpret_cast(layers[i].start)->next; + default: + break; + } + } +} + +int get_inner_ip_lyr(const Packet* const p) +{ + const Layer* layers = p->layers; + + for (int i = p->num_layers-1; i >= 0; i--) + { + switch(layers[i].prot_id) + { + case ETHERTYPE_IPV4: + case ETHERTYPE_IPV6: + case IPPROTO_ID_IPIP: + case IPPROTO_ID_IPV6: + return i; + default: + break; + } + } + return -1; +} + } // namespace layer diff --git a/src/protocols/layer.h b/src/protocols/layer.h index 5bf3e4f6a..e76a0b6ef 100644 --- a/src/protocols/layer.h +++ b/src/protocols/layer.h @@ -64,19 +64,22 @@ struct EtherHdr; } -// code maintained in header to ensure files to not depend on this library namespace layer { +// all of these functions will begin search from layer 0, +// and will return the first function they find. + -// signatures. No need to go searching for the correct function const arp::EtherARP* get_arp_layer(const Packet*); const vlan::VlanTagHdr* get_vlan_layer(const Packet*); const gre::GREHdr* get_gre_layer(const Packet*); const eapol::EtherEapol* get_eapol_layer(const Packet*); const eth::EtherHdr* get_eth_layer(const Packet*); -const uint8_t* get_root_layer(const Packet*); +const uint8_t* get_root_layer(const Packet* const); +int get_inner_ip_lyr(const Packet* const p); +uint16_t get_outer_ip_next_proto(const Packet* const); } // namespace layer diff --git a/src/protocols/packet.h b/src/protocols/packet.h index cf400c8ea..ac93f401d 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -109,6 +109,7 @@ extern "C" { #define PKT_FILE_EVENT_SET 0x04000000 #define PKT_ESP_LYR_PRESENT 0x08000000 +#define PKT_UNUSED_FLAGS 0xF0000000 // 0x40000000 are available #define PKT_PDU_FULL (PKT_PDU_HEAD | PKT_PDU_TAIL) @@ -205,12 +206,11 @@ struct Packet //vvv----------------------------- ipv4::IP4Hdr *ip4h, *orig_ip4h; ipv6::IP6Hdr *ip6h, *orig_ip6h; - icmp6::ICMP6Hdr *icmp6h, *orig_icmp6h; + icmp6::ICMP6Hdr *icmp6h; IPH_API* iph_api; IPH_API* orig_iph_api; IPH_API* outer_iph_api; - IPH_API* outer_orig_iph_api; int family; int orig_family; @@ -256,9 +256,9 @@ struct Packet uint8_t ip6_frag_index; uint8_t error_flags; /* flags indicate checksum errors, bad TTLs, etc. */ - uint8_t encapsulated; - uint8_t GTPencapsulated; - uint8_t next_layer; /* index into layers for next encap */ + uint8_t num_layers; /* index into layers for next encap */ + uint8_t decode_flags; /* flags used while decoding */ + uint8_t encapsulations; /* thh curent number of encapsulations */ // nothing after this point is zeroed ... ipv4::IpOptions ip_options[IP_OPTMAX]; /* ip options decode structure */ diff --git a/src/sfip/sf_iph.cc b/src/sfip/sf_iph.cc index 323b61813..c2d1f62c3 100644 --- a/src/sfip/sf_iph.cc +++ b/src/sfip/sf_iph.cc @@ -463,15 +463,11 @@ void sfiph_orig_build(Packet *p, const void *hdr, int family) /* If iph_api is already set, we've been here before. * That means this is a nested IP. */ if (p->orig_iph_api && (p->orig_iph_api->ver == IPH_API_V4)) - { memcpy(&p->outer_orig_ip4h, &p->inner_orig_ip4h, sizeof(IP4Hdr)); - p->outer_orig_iph_api = p->orig_iph_api; - } + else if (p->orig_iph_api && (p->orig_iph_api->ver == IPH_API_V6)) - { memcpy(&p->outer_orig_ip6h, &p->inner_orig_ip6h, sizeof(IP6Hdr)); - p->outer_orig_iph_api = p->orig_iph_api; - } + _set_callbacks(p, family, CALLBACK_ICMP_ORIG); diff --git a/src/stream/ip/ip_defrag.cc b/src/stream/ip/ip_defrag.cc index c2d2271c3..147a37071 100644 --- a/src/stream/ip/ip_defrag.cc +++ b/src/stream/ip/ip_defrag.cc @@ -889,7 +889,7 @@ static void FragRebuild(FragTracker *ft, Packet *p) PREPROC_PROFILE_START(fragRebuildPerfStats); - if ( p->encapsulated ) + if ( p->encapsulations ) dpkt = encap_defrag_pkt; else dpkt = defrag_pkt;