#include "snort.h"
#include "packet_io/active.h"
-void codec_events::exec_udp_chksm_drop (Packet *)
+void codec_events::exec_udp_chksm_drop (const Packet* const/*p*/)
{
if( ScInlineMode() && ScUdpChecksumDrops() )
{
}
}
-void codec_events::exec_tcp_chksm_drop (Packet*)
+void codec_events::exec_tcp_chksm_drop (const Packet* const /*p*/)
{
if( ScInlineMode() && ScTcpChecksumDrops() )
{
}
}
-void codec_events::decoder_event(Packet *p, CodecSid sid)
+void codec_events::decoder_event(const Packet* const p, CodecSid sid)
{
if ( p->packet_flags & PKT_REBUILT_STREAM )
return;
SnortEventqAdd(GID_DECODE, sid);
}
-void codec_events::exec_ip_chksm_drop (Packet*)
+void codec_events::exec_ip_chksm_drop (const Packet* const /*p*/)
{
// TBD only set policy csum drop if policy inline
// and delete this inline mode check
}
}
-void codec_events::exec_icmp_chksm_drop (Packet*)
+void codec_events::exec_icmp_chksm_drop (const Packet* const /*p*/)
{
if( ScInlineMode() && ScIcmpChecksumDrops() )
{
}
}
-void codec_events::decoder_alert_encapsulated(
- Packet *p, CodecSid sid, const uint8_t *pkt, uint32_t len)
+void codec_events::decoder_alert_encapsulated(Packet* const p,
+ CodecSid sid,
+ const uint8_t *pkt,
+ uint32_t len)
{
decoder_event(p, sid);
namespace codec_events
{
-void exec_ip_chksm_drop(Packet*);
-void exec_udp_chksm_drop (Packet*);
-void exec_tcp_chksm_drop (Packet*);
-void exec_icmp_chksm_drop (Packet*);
-void decoder_event(Packet* p, CodecSid);
+void exec_ip_chksm_drop (const Packet* const);
+void exec_udp_chksm_drop (const Packet*const);
+void exec_tcp_chksm_drop (const Packet* const);
+void exec_icmp_chksm_drop (const Packet* const);
+void decoder_event(const Packet* p, CodecSid const);
void decoder_alert_encapsulated(
- Packet*, CodecSid, const uint8_t* pkt, uint32_t len);
+ Packet* const, CodecSid, const uint8_t* pkt, uint32_t len);
} //namespace codec_events
{
/* Attempt to decode the inner payload.
There is a small chance that an encrypted next_header would become a
- different valid next_header. The PKT_UNSURE_ENCAP flag tells the next
+ different valid next_header. The DECODE__UNSURE_ENCAP flag tells the next
decoder stage to silently ignore invalid headers. */
- p->packet_flags |= PKT_UNSURE_ENCAP;
+ p->decode_flags |= DECODE__UNSURE_ENCAP;
const_cast<uint32_t&>(raw_len) -= (ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN);
- p->packet_flags |= PKT_ESP_LYR_PRESENT;
+ p->decode_flags |= DECODE__ESP;
}
else
{
bool Ipv6FragCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
Packet *p, uint16_t &lyr_len, uint16_t &next_prot_id)
{
- const IP6Frag *ip6frag_hdr = reinterpret_cast<const IP6Frag *>(raw_pkt);
+ const IP6Frag* ip6frag_hdr = reinterpret_cast<const IP6Frag*>(raw_pkt);
fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p, IPPROTO_ID_FRAGMENT);
ipv6_util::CheckIPv6ExtensionOrder(p);
p->ip6_frag_index = p->ip6_extension_count;
p->ip_frag_start = raw_pkt + sizeof(IP6Frag);
- p->df = 0;
- p->rf = IP6F_RES(ip6frag_hdr);
- p->mf = IP6F_MF(ip6frag_hdr);
- p->frag_offset = IP6F_OFFSET(ip6frag_hdr);
+ p->decode_flags &= ~DECODE__DF;
+
+ if (ipv6::is_mf_set(ip6frag_hdr))
+ p->decode_flags |= DECODE__MF;
+
+ if (ipv6::is_res_set(ip6frag_hdr))
+ p->decode_flags |= DECODE__RF;
- if ( p->frag_offset || p->mf )
+
+ p->frag_offset = IP6F_OFFSET(ip6frag_hdr);
+ if (p->frag_offset || (p->decode_flags & DECODE__MF))
{
- p->frag_flag = 1;
+ p->decode_flags |= DECODE__FRAG;
}
else
{
lyr_len = sizeof(IP6Frag);
p->ip_frag_len = (uint16_t)(raw_len - lyr_len);
- if ( p->frag_flag && ((p->frag_offset > 0) ||
+ if ( (p->decode_flags & DECODE__FRAG) && ((p->frag_offset > 0) ||
(ip6frag_hdr->ip6f_nxt != IPPROTO_UDP)) )
{
/* For non-zero offset frags, we stop decoding after the
DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
"WARNING: Truncated IP4 header (%d bytes).\n", raw_len););
- if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)
+ if ((p->decode_flags & DECODE__UNSURE_ENCAP) == 0)
codec_events::decoder_event(p, DECODE_IP4_HDR_TRUNC);
p->iph = NULL;
*/
if(ipv4::get_version((IPHdr*)raw_pkt) != 4)
{
- if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)
+ if ((p->decode_flags & DECODE__UNSURE_ENCAP) == 0)
codec_events::decoder_event(p, DECODE_NOT_IPV4_DGRAM);
p->iph = NULL;
* get the values of the reserved, more
* fragments and don't fragment flags
*/
- p->rf = (uint8_t)((p->frag_offset & 0x8000) >> 15);
- p->df = (uint8_t)((p->frag_offset & 0x4000) >> 14);
- p->mf = (uint8_t)((p->frag_offset & 0x2000) >> 13);
+ if (p->frag_offset & 0x8000)
+ p->decode_flags |= DECODE__RF;
+
+ if (p->frag_offset & 0x4000)
+ p->decode_flags |= DECODE__DF;
+
+ if (p->frag_offset & 0x2000)
+ p->decode_flags |= DECODE__MF;
/* mask off the high bits in the fragment offset field */
p->frag_offset &= 0x1FFF;
- if ( p->df && p->frag_offset )
+ if ((p->decode_flags & DECODE__DF) && p->frag_offset )
codec_events::decoder_event(p, DECODE_IP4_DF_OFFSET);
if ( p->frag_offset + p->actual_ip_len > IP_MAXPACKET )
codec_events::decoder_event(p, DECODE_IP4_LEN_OFFSET);
- if(p->frag_offset || p->mf)
+ if(p->frag_offset || (p->decode_flags & DECODE__MF))
{
if ( !ip_len)
{
codec_events::decoder_event(p, DECODE_ZERO_LENGTH_FRAG);
- p->frag_flag = 0;
+ p->decode_flags &= ~DECODE__FRAG;
}
else
{
/* set the packet fragment flag */
- p->frag_flag = 1;
+ p->decode_flags |= DECODE__FRAG;
p->ip_frag_start = raw_pkt + hlen;
p->ip_frag_len = (uint16_t)ip_len;
}
}
else
{
- p->frag_flag = 0;
+ p->decode_flags &= ~DECODE__FRAG;
}
- if( p->mf && p->df )
+ if( (p->decode_flags & DECODE__MF) && (p->decode_flags & DECODE__DF))
{
codec_events::decoder_event(p, DECODE_BAD_FRAGBITS);
}
/* if this packet isn't a fragment
* or if it is, its a UDP packet and offset is 0 */
- if(!(p->frag_flag) ||
- (p->frag_flag && (p->frag_offset == 0) &&
+ if(!(p->decode_flags & DECODE__FRAG) ||
+ ((p->decode_flags & DECODE__FRAG) && (p->frag_offset == 0) &&
(p->iph->ip_proto == IPPROTO_UDP)))
{
DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP header length: %lu\n",
} // namespace
-static inline void IPV6MiscTests(Packet *p);
-static void CheckIPV6Multicast(Packet *p);
-static inline int CheckTeredoPrefix(ipv6::IP6RawHdr *hdr);
+static inline void IPV6MiscTests(const Packet* const p);
+static void CheckIPV6Multicast(const Packet* const p);
+static inline int CheckTeredoPrefix(const ipv6::IP6RawHdr* const hdr);
/********************************************************************
************************* PRIVATE FUNCTIONS **********************
bool Ipv6Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
Packet *p, uint16_t &lyr_len, uint16_t &next_prot_id)
{
- ipv6::IP6RawHdr *hdr;
+ const ipv6::IP6RawHdr *hdr;
uint32_t payload_len;
hdr = reinterpret_cast<ipv6::IP6RawHdr*>(const_cast<uint8_t*>(raw_pkt));
if(raw_len < ipv6::hdr_len())
{
- if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)
+ if ((p->decode_flags & DECODE__UNSURE_ENCAP) == 0)
codec_events::decoder_event(p, DECODE_IPV6_TRUNCATED);
// Taken from prot_ipv4.cc
/* Verify version in IP6 Header agrees */
if(!is_ip6_hdr_ver(hdr))
{
- if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)
+ if ((p->decode_flags & DECODE__UNSURE_ENCAP) == 0)
codec_events::decoder_event(p, DECODE_IPV6_IS_NOT);
goto decodeipv6_fail;
{
if (payload_len > raw_len)
{
- if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)
+ if ((p->decode_flags & DECODE__UNSURE_ENCAP) == 0)
codec_events::decoder_event(p, DECODE_IPV6_DGRAM_GT_CAPLEN);
goto decodeipv6_fail;
/* lay the IP struct over the raw data */
// this is ugly but necessary to keep the rest of the code happy
- p->inner_iph = p->iph = reinterpret_cast<IPHdr *>(const_cast<uint8_t*>(raw_pkt));
+ p->inner_iph = p->iph = reinterpret_cast<const IPHdr *>(raw_pkt);
/* Build Packet structure's version of the IP6 header */
sfiph_build(p, hdr, AF_INET6);
*
* Returns: void function
*/
-static inline void IPV6MiscTests(Packet *p)
+static inline void IPV6MiscTests(const Packet* const p)
{
/*
* Some IP Header tests
/* Check for multiple IPv6 Multicast-related alerts */
-static void CheckIPV6Multicast(Packet *p)
+static void CheckIPV6Multicast(const Packet* const p)
{
ipv6::MulticastScope multicast_scope;
/* Teredo packets need to have one of their IPs use either the Teredo prefix,
or a link-local prefix (in the case of Router Solicitation messages) */
-static inline int CheckTeredoPrefix(ipv6::IP6RawHdr *hdr)
+static inline int CheckTeredoPrefix(const ipv6::IP6RawHdr* const hdr)
{
/* Check if src address matches 2001::/32 */
if ((hdr->ip6_src.s6_addr[0] == 0x20) &&
{
/* Don't drop the packet if this is encapuslated in Teredo or ESP.
Just get rid of the TCP header and stop decoding. */
- if (p->packet_flags & PKT_UNSURE_ENCAP)
+ if (p->decode_flags & DECODE__UNSURE_ENCAP)
{
p->tcph = NULL;
return false;
/* set the ptr to the start of the UDP header */
p->udph = reinterpret_cast<const udp::UDPHdr*>(raw_pkt);
- if (!p->frag_flag)
+ if (!(p->decode_flags & DECODE__FRAG))
{
uhlen = ntohs(p->udph->uh_len);
}
{
/* Don't drop the packet if this was ESP or Teredo.
Just stop decoding. */
- if (p->packet_flags & PKT_UNSURE_ENCAP)
+ if (p->decode_flags & DECODE__UNSURE_ENCAP)
{
PopUdp(p);
return false;
if (ScGTPDecoding() &&
(ScIsGTPPort(p->sp)||ScIsGTPPort(p->dp)))
{
- if ( !p->frag_flag )
+ if ( !(p->decode_flags & DECODE__FRAG) )
next_prot_id = PROTOCOL_GTP;
}
else if (teredo::is_teredo_port(p->sp) ||
teredo::is_teredo_port(p->dp) ||
ScDeepTeredoInspection())
{
- if ( !p->frag_flag )
+ if ( !(p->decode_flags & DECODE__FRAG) )
next_prot_id = PROTOCOL_TEREDO;
}
if (raw_len > 0)
{
- p->packet_flags |= PKT_UNSURE_ENCAP;
+ p->decode_flags |= DECODE__UNSURE_ENCAP;
ip_ver = *(raw_pkt + GTP_MIN_LEN) & 0xF0;
if (ip_ver == 0x40)
Active_SetTunnelBypass();
if ((!teredo::is_teredo_port(p->sp)) && (!teredo::is_teredo_port(p->dp)))
- p->packet_flags |= PKT_UNSURE_ENCAP;
+ p->decode_flags |= DECODE__UNSURE_ENCAP;
next_prot_id = IPPROTO_IPV6;
return true;
addressSpaceId = 0;
#endif
- if ( p->frag_flag )
+ if ( (p->decode_flags & DECODE__FRAG) )
{
key->init(GET_SRC_IP(p), GET_DST_IP(p), GET_IPH_ID(p),
proto, vlanId, mplsId, addressSpaceId);
// Get the codec's name
inline const char* get_name(){return name; };
+ // Several codecs are for convenience. So, tell Snort++ not to print any info
+ virtual bool dump_at_startup(){ return true; };
+ // used for backwards compatability.
+ virtual PROTO_ID get_proto_id() { return PROTO_AH; };
// Registers this Codec's data link type (as defined by libpcap)
virtual void get_data_link_type(std::vector<int>&) {};
// Register the code's protocol ID's and Ethertypes
virtual bool update(Packet*, Layer*, uint32_t* /*len*/) { return true; };
// formatter
virtual void format(EncodeFlags, const Packet* /*orig*/, Packet* /*clone*/, Layer*) {};
- // used for backwards compatability.
- virtual PROTO_ID get_proto_id() { return PROTO_AH; };
protected:
/* if there's data in this packet */
if(p != NULL)
{
- if((p->dsize != 0 && p->data != NULL) || p->frag_flag != 1)
+ if((p->dsize != 0 && p->data != NULL) || (!(p->decode_flags & DECODE__FRAG)))
{
session = OpenSessionFile(p);
FILE *ret;
- if(p->frag_flag)
+ if(p->decode_flags & DECODE__FRAG)
{
return NULL;
}
const u_char *end;
char conv[] = "0123456789ABCDEF"; /* xlation lookup table */
- if(p->dsize == 0 || p->data == NULL || p->frag_flag)
+ if(p->dsize == 0 || p->data == NULL || (p->decode_flags & DECODE__FRAG))
return;
idx = p->data;
if (!IPH_IS_VALID(p))
return;
- if (p->frag_flag
+ if ((p->decode_flags & DECODE__FRAG)
|| ((GET_IPH_PROTO(p) != IPPROTO_TCP)
&& (GET_IPH_PROTO(p) != IPPROTO_UDP)))
{
}
/* print fragment info if necessary */
- if(p->frag_flag)
+ if(p->decode_flags & DECODE__FRAG)
{
TextLog_Print(log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n",
(p->frag_offset & 0x1FFF),
uint8_t save_ip_option_count = p->ip_option_count;
IP4Hdr *save_ip4h = p->ip4h;
IP6Hdr *save_ip6h = p->ip6h;
- uint8_t save_frag_flag = p->frag_flag;
+ uint8_t save_frag_flag = (p->decode_flags & DECODE__FRAG);
uint16_t save_sp, save_dp;
p->family = p->outer_family;
p->ip_option_count = 0;
p->ip4h = &p->outer_ip4h;
p->ip6h = &p->outer_ip6h;
- p->frag_flag = 0;
+ p->decode_flags &= ~DECODE__FRAG;
if (p->proto_bits & PROTO_BIT__TEREDO)
{
p->ip_option_count = save_ip_option_count;
p->ip4h = save_ip4h;
p->ip6h = save_ip6h;
- p->frag_flag = save_frag_flag;
+ p->decode_flags |= save_frag_flag;
}
/*-------------------------------------------------------------------
LogIPHeader(log, p);
/* if this isn't a fragment, print the other header info */
- if ( !p->frag_flag )
+ if (!(p->decode_flags & DECODE__FRAG))
{
switch (GET_IPH_PROTO(p))
{
LogIPHeader(full_log, p);
/* if this isn't a fragment, print the other header info */
- if(!p->frag_flag)
+ if(!(p->decode_flags & DECODE__FRAG))
{
switch(GET_IPH_PROTO(p))
{
"{%d} ", GET_IPH_PROTO(p));
}
- if (p->frag_flag
+ if ((p->decode_flags & DECODE__FRAG)
|| ((GET_IPH_PROTO(p) != IPPROTO_TCP)
&& (GET_IPH_PROTO(p) != IPPROTO_UDP)))
{
uint8_t mapped_prot = grinder;
uint16_t prev_prot_id = FINISHED_DECODE;
uint16_t lyr_len = 0;
- uint32_t len = 0;
+ uint32_t len;
DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n",
// if the final protocol ID is not the default codec, a Codec failed
if (prev_prot_id != FINISHED_DECODE)
{
- if (!(p->packet_flags & PKT_UNSURE_ENCAP))
+ if (!(p->decode_flags & DECODE__UNSURE_ENCAP))
{
// if the codec exists, it failed
if(s_proto_map[prev_prot_id])
s_stats[other_codecs]++;
}
- if (p->packet_flags & PKT_ESP_LYR_PRESENT)
+ if (p->decode_flags & DECODE__ESP)
p->packet_flags |= PKT_TRUST;
}
ipv6_util::CheckIPv6ExtensionOrder(p);
s_stats[mapped_prot + stat_offset]++;
- p->packet_flags &= (uint32_t)~PKT_ESP_LYR_PRESENT; // cleanup just in case.
p->dsize = (uint16_t)len;
p->data = pkt;
Layer* lyr;
int len;
int num_layers = p->num_layers;
+
+ // TODO -- remove
DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)c->pkth;
uint8_t* pkt = (uint8_t*)c->pkt;
memset(c, 0, PKT_ZERO_LEN);
+ // TODO -- remove
c->raw_ip6h = nullptr;
- c->pkth = pkth;
- c->pkt = pkt;
+// c->pkth = pkth;
+// c->pkt = pkt;
#ifdef HAVE_DAQ_ADDRESS_SPACE_ID
pkth->ingress_index = phdr->ingress_index;
c->pseudo_type = type;
c->user_policy_id = p->user_policy_id; // cooked packet gets same policy as raw
- switch ( type )
- {
- case PSEUDO_PKT_SMB_SEG:
- case PSEUDO_PKT_DCE_SEG:
- case PSEUDO_PKT_DCE_FRAG:
- case PSEUDO_PKT_SMB_TRANS:
- c->packet_flags |= PKT_REASSEMBLED_OLD;
- break;
- default:
- break;
- }
-
// setup pkt capture header
pkth->caplen = len;
pkth->pktlen = len;
const uint8_t *data;
};
+// This must be a standard layour struct!
struct IPHdr
{
uint8_t ip_verhl; /* version & header length */
#define IP6F_MF_MASK 0x0001 /* more-fragments flag */
#define IP6F_OFFSET(fh) ((ntohs((fh)->ip6f_offlg) & IP6F_OFFSET_MASK) >> 3)
-#define IP6F_RES(fh) (fh)->ip6f_reserved
-#define IP6F_MF(fh) (ntohs((fh)->ip6f_offlg) & IP6F_MF_MASK )
/* to store references to IP6 Extension Headers */
struct IP6Option
return (static_cast<MulticastScope>(ch) == MulticastScope::IP6_MULTICAST_SCOPE_GLOBAL);
}
-inline bool is_ip6_hdr_ver(IP6RawHdr *hdr)
-{
- return ((ntohl(hdr->ip6_vtf) >> 28) == 6);
-}
+inline bool is_ip6_hdr_ver(const IP6RawHdr* const hdr)
+{ return ((ntohl(hdr->ip6_vtf) >> 28) == 6); }
inline size_t min_ext_len()
-{
- return detail::MIN_EXT_LEN;
-}
+{ return detail::MIN_EXT_LEN; }
-} // namespace
+inline bool is_mf_set(const IP6Frag* const fh)
+{ return (ntohs(fh->ip6f_offlg) & IP6F_MF_MASK); }
+
+inline bool is_res_set(const IP6Frag* const fh)
+{ return fh->ip6f_reserved; }
+
+//#define IP6F_RES(fh) (fh)->ip6f_reserved
+
+} // namespace ipv6
break;
}
}
+ return -1;
}
int get_inner_ip_lyr(const Packet* const p)
#define PKT_PDU_HEAD 0x00000100 /* start of PDU */
#define PKT_PDU_TAIL 0x00000200 /* end of PDU */
-#define PKT_UNSURE_ENCAP 0x00000400 /* packet may have incorrect encapsulation layer. */
- /* don't alert if "next layer" is invalid. */
-#define PKT_HTTP_DECODE 0x00000800 /* this packet has normalized http */
+#define PKT_HTTP_DECODE 0x00000400 /* this packet has normalized http */
-#define PKT_IGNORE 0x00001000 /* this packet should be ignored, based on port */
-#define PKT_TRUST 0x00002000 /* this packet should fallback to being whitelisted if no other verdict was specified */
-#define PKT_ALLOW_MULTIPLE_DETECT 0x00004000 /* packet has either pipelined mime attachements */
+#define PKT_IGNORE 0x00000800 /* this packet should be ignored, based on port */
+#define PKT_TRUST 0x00001000 /* this packet should fallback to being whitelisted if no other verdict was specified */
+#define PKT_ALLOW_MULTIPLE_DETECT 0x00002000 /* packet has either pipelined mime attachements */
/* or pipeline http requests */
-#define PKT_PAYLOAD_OBFUSCATE 0x00008000
+#define PKT_PAYLOAD_OBFUSCATE 0x00004000
-#define PKT_STATELESS 0x00010000 /* Packet has matched a stateless rule */
-#define PKT_PASS_RULE 0x00020000 /* this packet has matched a pass rule */
-#define PKT_IP_RULE 0x00040000 /* this packet is being evaluated against an IP rule */
-#define PKT_IP_RULE_2ND 0x00080000 /* this packet is being evaluated against an IP rule */
+#define PKT_STATELESS 0x00008000 /* Packet has matched a stateless rule */
+#define PKT_PASS_RULE 0x00010000 /* this packet has matched a pass rule */
+#define PKT_IP_RULE 0x00020000 /* this packet is being evaluated against an IP rule */
+#define PKT_IP_RULE_2ND 0x00040000 /* this packet is being evaluated against an IP rule */
-#define PKT_PSEUDO 0x00100000 /* is a pseudo packet */
-#define PKT_MODIFIED 0x00200000 /* packet had normalizations, etc. */
-#define PKT_RESIZED 0x00300000 /* packet has new size; must set modified too */
+#define PKT_PSEUDO 0x00080000 /* is a pseudo packet */
+#define PKT_MODIFIED 0x00100000 /* packet had normalizations, etc. */
+#define PKT_RESIZED 0x00180000 /* packet has new size; must set modified too */
// neither of these flags will be set for (full) retransmissions or non-data segments
// a partial overlap results in out of sequence condition
// out of sequence condition is sticky
-#define PKT_STREAM_ORDER_OK 0x00800000 /* this segment is in order, w/o gaps */
-#define PKT_STREAM_ORDER_BAD 0x01000000 /* this stream had at least one gap */
-#define PKT_REASSEMBLED_OLD 0x02000000 /* for backwards compat with so rules */
+#define PKT_STREAM_ORDER_OK 0x00200000 /* this segment is in order, w/o gaps */
+#define PKT_STREAM_ORDER_BAD 0x00400000 /* this stream had at least one gap */
-#define PKT_FILE_EVENT_SET 0x04000000
-#define PKT_ESP_LYR_PRESENT 0x08000000
-#define PKT_UNUSED_FLAGS 0xF0000000
+#define PKT_FILE_EVENT_SET 0x00800000
+#define PKT_UNUSED_FLAGS 0xff000000
// 0x40000000 are available
#define PKT_PDU_FULL (PKT_PDU_HEAD | PKT_PDU_TAIL)
-#define REASSEMBLED_PACKET_FLAGS (PKT_REBUILT_STREAM|PKT_REASSEMBLED_OLD)
enum PseudoPacketType{
PSEUDO_PKT_IP,
const uint8_t IP6_EXTMAX = 8;
const uint8_t MIN_TTL = 64;
const uint8_t MAX_TTL = 255;
+const uint8_t LAYER_MAX = 32;
} ;
-const uint8_t LAYER_MAX = 32;
struct Packet
{
- const DAQ_PktHdr_t *pkth; // packet meta data
- const uint8_t *pkt; // raw packet data
//vvv------------------------------------------------
// TODO convenience stuff to be refactored for layers
int16_t application_protocol_ordinal;
- uint8_t frag_flag; /* flag to indicate a fragmented packet */
- uint8_t mf; /* more fragments flag */
- uint8_t df; /* don't fragment flag */
- uint8_t rf; /* IP reserved bit */
-
uint8_t ip_option_count; /* number of options in this packet */
uint8_t tcp_option_count;
uint8_t ip6_extension_count;
uint8_t encapsulations; /* thh curent number of encapsulations */
// nothing after this point is zeroed ...
+ const DAQ_PktHdr_t *pkth; // packet meta data
+ const uint8_t *pkt; // raw packet data
+
ipv4::IpOptions ip_options[IP_OPTMAX]; /* ip options decode structure */
Options tcp_options[TCP_OPTLENMAX]; /* tcp options decode struct */
IP6Option ip6_extensions[IP6_EXTMAX]; /* IPv6 Extension References */
+
+
const uint8_t *ip_frag_start;
const uint8_t *ip_options_data;
const uint8_t *tcp_options_data;
};
-#define PKT_ZERO_LEN offsetof(Packet, ip_options)
+#define PKT_ZERO_LEN offsetof(Packet, pkth)
#define PROTO_BIT__NONE 0x0000
#define PROTO_BIT__IP 0x0001
#define PROTO_BIT__MPLS 0x0080
#define PROTO_BIT__VLAN 0x0100
#define PROTO_BIT__ETH 0x0200
+#define PROTO_BIT__FREE 0x7c00
#define PROTO_BIT__OTHER 0x8000
#define PROTO_BIT__ALL 0xffff
+/* Decode Flags */
+#define DECODE__FRAG 0x01 /* flag to indicate a fragmented packet */
+#define DECODE__MF 0x02 /* more fragments flag */
+#define DECODE__DF 0x04 /* don't fragment flag */
+#define DECODE__RF 0x08 /* IP reserved bit */
+#define DECODE__ESP 0x10 /* flag to indicate an ESP layer has been seen */
+#define DECODE__UNSURE_ENCAP 0x20 /* packet may have incorrect encapsulation layer. */
+ /* don't alert if "next layer" is invalid. */
+#define DECODE__FREE 0xC0
+
#define IsIP(p) (IPH_IS_VALID(p))
#define IsTCP(p) (IsIP(p) && p->tcph)
#define IsICMP(p) (IsIP(p) && p->icmph)
#define GET_INNER_SRC_IP(p) (IS_IP6(p) ? (&((p)->inner_ip6h.ip_src)):(&((p)->inner_ip4h.ip_src)))
#define GET_INNER_DST_IP(p) (IS_IP6(p) ? (&((p)->inner_ip6h.ip_dst)):(&((p)->inner_ip4h.ip_dst)))
-#define GET_OUTER_SRC_IP(p) (IS_OUTER_IP6(p) ? (&((p)->outer_ip6h.ip_src)):(&((p)->outer_ip4h.ip_src)))
-#define GET_OUTER_DST_IP(p) (IS_OUTER_IP6(p) ? (&((p)->outer_ip6h.ip_dst)):(&((p)->outer_ip4h.ip_dst)))
+
static inline int sfip_equal (snort_ip* ip1, snort_ip* ip2)
{
if ( ip1->family != ip2->family )
break;
case IPPROTO_UDP:
- if ( p->frag_flag )
+ if ( p->decode_flags & DECODE__FRAG )
flow_con->process_ip(p);
if ( p->udph )
uint16_t endOfThisFrag;
/* set the frag flag if this is the first fragment */
- if(p->mf && p->frag_offset == 0)
+ if((p->decode_flags & DECODE__MF) && p->frag_offset == 0)
{
ft->frag_flags |= FRAG_GOT_FIRST;
DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Got first frag\n"););
}
- else if((!p->mf) && (p->frag_offset > 0)) /* set for last frag too */
+ else if((!(p->decode_flags & DECODE__MF)) && (p->frag_offset > 0)) /* set for last frag too */
{
/* Use the actual length here, because packet may have been
* truncated. Don't want to try to copy more than we actually
{
//Snort may need to raise a separate event if
//only trimmed length is tiny.
- if(p->mf)
+ if(p->decode_flags & DECODE__MF)
{
///detect tiny fragments before processing overlaps.
if (engine->min_fragment_length)
* clear the packet fragment fields
*/
((IPHdr *)dpkt->iph)->ip_off = 0x0000;
- dpkt->frag_flag = 0;
+ dpkt->decode_flags &= ~DECODE__FRAG;
DEBUG_WRAP(DebugMessage(DEBUG_FRAG,
"[^^] Walking fraglist:\n"););
* tell the rest of the system that this is a rebuilt fragment
*/
dpkt->packet_flags |= PKT_REBUILT_FRAG;
- dpkt->frag_flag = 0;
+ dpkt->decode_flags &= ~DECODE__FRAG;
dpkt->dsize = (uint16_t)ft->calculated_size;
PacketManager::encode_update(dpkt);
// preconditions - what we registered for
assert(IPH_IS_VALID(p) && !(p->error_flags & PKT_ERR_CKSUM_IP));
- assert(p->frag_flag);
+ assert(p->decode_flags & DECODE__FRAG);
/*
* First case: if frag offset is 0 & UDP, let that packet go
* Disable Inspection since we'll look at the payload in
* a rebuilt packet later. So don't process it further.
*/
- if ((p->frag_offset != 0) || ((GET_IPH_PROTO(p) != IPPROTO_UDP) && (p->mf)))
+ if ((p->frag_offset != 0) ||
+ ((GET_IPH_PROTO(p) != IPPROTO_UDP) && (p->decode_flags & DECODE__MF)))
+ {
DisableDetect(p);
+ }
/*
* pkt's not going to make it to the engine, bail
#ifdef DEBUG
LogMessage("WARNING: Excessive IP fragment overlap, "
"(More: %u, offset: %u, offsetSize: %u).\n",
- p->mf, (p->frag_offset<<3), p->ip_frag_len);
+ (p->decode_flags & DECODE__MF),
+ (p->frag_offset<<3), p->ip_frag_len);
#endif
t_stats.discards++;
MODULE_PROFILE_END(fragPerfStats);
/*
* might have last frag...
*/
- if(!p->mf)
+ if(!(p->decode_flags & DECODE__MF))
{
if ((frag_end > ft->calculated_size) &&
(firstLastOk == FRAG_LAST_OFFSET_ADJUST))
((ft->frag_flags & FRAG_GOT_LAST) &&
frag_end != ft->calculated_size))
{
- if (!p->mf)
+ if (!(p->decode_flags & DECODE__MF))
{
/*
* teardrop attack...
((ft->frag_flags & FRAG_GOT_LAST) &&
frag_end != ft->calculated_size))
{
- if (!p->mf)
+ if (!(p->decode_flags & DECODE__MF))
{
/*
* teardrop attack...
frag_end = f->offset + fragLength;
f->ord = ft->ordinal++;
f->data = f->fptr; /* ptr to adjusted start position */
- if (!p->mf)
+ if (!(p->decode_flags & DECODE__MF))
{
f->last = 1;
}
return 0;
}
- if ( p->frag_flag )
+ if ( p->decode_flags & DECODE__FRAG )
{
Defrag* d = get_defrag(flow->ssn_server);
d->process(p, &tracker);