int curr_layer = p->num_layers - 1;
uint8_t ip_proto; // set in function
- while (p->ip_proto_next(curr_layer, ip_proto))
+ while (p->get_ip_proto_next(curr_layer, ip_proto))
{
if (snort_conf->ip_proto_array[ip_proto])
{
bool set(
const sfip_t *cliIP, uint16_t cliPort,
const sfip_t *srvIP, uint16_t srvPort,
- PktType proto);
+ uint8_t proto);
};
inline bool ExpectKey::set(
const sfip_t *cliIP, uint16_t cliPort,
const sfip_t *srvIP, uint16_t srvPort,
- PktType proto )
+ uint8_t proto )
{
bool reverse;
SFIP_RET rval = sfip_compare(cliIP, srvIP);
int ExpectCache::add_flow(
const sfip_t *cliIP, uint16_t cliPort,
const sfip_t *srvIP, uint16_t srvPort,
- PktType protocol, char direction,
+ uint8_t protocol, char direction,
FlowData* fd, int16_t appId)
{
assert( !cliPort || !srvPort );
const sfip_t *dstIP = p->ptrs.ip_api.get_dst();
ExpectKey key;
- bool reversed_key = key.set(dstIP, p->ptrs.dp, srcIP, p->ptrs.sp, p->type());
+ bool reversed_key = key.set(dstIP, p->ptrs.dp, srcIP, p->ptrs.sp, p->get_ip_proto_next());
uint16_t port1;
uint16_t port2;
#ifndef EXPECT_CACHE_H
#define EXPECT_CACHE_H
-#include "framework/codec.h"
#include "sfip/sfip_t.h"
class FlowData;
int add_flow(
const sfip_t *cliIP, uint16_t cliPort,
const sfip_t *srvIP, uint16_t srvPort,
- PktType protocol, char direction,
+ uint8_t protocol, char direction,
FlowData*, int16_t appId = 0);
bool is_expected(Packet*);
const FlowKey* key;
class Session* session;
StreamFlowData* flowdata;
- PktType protocol;
+ uint8_t ip_proto; // FIXIT-M -- do we need both of these?
+ PktType protocol; // ^^
// these fields are always set; not zeroed
Flow* prev, * next;
static THREAD_LOCAL PegCount icmp_count = 0;
static THREAD_LOCAL PegCount ip_count = 0;
-PegCount FlowControl::get_flow_count(PktType proto)
+PegCount FlowControl::get_flow_count(uint8_t proto)
{
switch ( proto )
{
- case PktType::TCP: return tcp_count;
- case PktType::UDP: return udp_count;
- case PktType::ICMP: return icmp_count;
- case PktType::IP: return ip_count;
+ case IPPROTO_TCP: return tcp_count;
+ case IPPROTO_UDP: return udp_count;
+ case IPPROTO_ICMP: return icmp_count;
+ case IPPROTO_IP: return ip_count;
default: return 0;
}
}
// cache foo
//-------------------------------------------------------------------------
-inline FlowCache* FlowControl::get_cache (PktType proto)
+inline FlowCache* FlowControl::get_cache (uint8_t proto)
{
switch ( proto )
{
- case PktType::TCP: return tcp_cache;
- case PktType::UDP: return udp_cache;
- case PktType::ICMP: return icmp_cache;
- case PktType::IP: return ip_cache;
- default: return nullptr;
+ case IPPROTO_TCP: return tcp_cache;
+ case IPPROTO_UDP: return udp_cache;
+ case IPPROTO_ICMP: return icmp_cache;
+ case IPPROTO_IP: return ip_cache;
+ default: return nullptr;
}
}
void FlowControl::delete_flow (Flow* flow, const char* why)
{
- FlowCache* cache = get_cache(flow->protocol);
+ FlowCache* cache = get_cache(flow->ip_proto);
if ( cache )
cache->release(flow, why);
}
-void FlowControl::purge_flows (PktType proto)
+void FlowControl::purge_flows (uint8_t proto)
{
FlowCache* cache = get_cache(proto);
cache->purge();
}
-void FlowControl::prune_flows (PktType proto, Packet* p)
+void FlowControl::prune_flows (uint8_t proto, Packet* p)
{
FlowCache* cache = get_cache(proto);
Active_Resume();
}
-uint32_t FlowControl::max_flows(PktType proto)
+uint32_t FlowControl::max_flows(uint8_t proto)
{
FlowCache* cache = get_cache(proto);
return 0;
}
-void FlowControl::get_prunes (PktType proto, PegCount& prunes)
+void FlowControl::get_prunes (uint8_t proto, PegCount& prunes)
{
FlowCache* cache = get_cache(proto);
prunes = cache->get_prunes();
}
-void FlowControl::reset_prunes (PktType proto)
+void FlowControl::reset_prunes (uint8_t proto)
{
FlowCache* cache = get_cache(proto);
uint32_t mplsId;
uint16_t vlanId;
uint16_t addressSpaceId;
- PktType proto = p->type();
+ uint8_t proto = p->get_ip_proto_next();
if ( p->proto_bits & PROTO_BIT__VLAN )
vlanId = layer::get_vlan_layer(p)->vid();
key->init(ip_api.get_src(), ip_api.get_dst(), ip_api.id(),
proto, vlanId, mplsId, addressSpaceId);
}
- else if (proto == PktType::ICMP)
+ else if (proto == IPPROTO_ICMP)
{
key->init(ip_api.get_src(), p->ptrs.icmph->type, ip_api.get_dst(), 0,
proto, vlanId, mplsId, addressSpaceId);
}
- else if (proto == PktType::IP)
- {
- key->init(ip_api.get_src(), ip_api.proto(), ip_api.get_dst(), p->ptrs.dp,
- proto, vlanId, mplsId, addressSpaceId);
- }
else
{
key->init(ip_api.get_src(), p->ptrs.sp, ip_api.get_dst(), p->ptrs.dp,
int FlowControl::add_expected(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType protocol, char direction,
+ uint8_t protocol, char direction,
FlowData* fd)
{
return exp_cache->add_flow(
int FlowControl::add_expected(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType protocol, int16_t appId,
+ uint8_t protocol, int16_t appId,
FlowData* fd)
{
return exp_cache->add_flow(
void delete_flow(const FlowKey*);
void delete_flow(Flow*, const char* why);
- void purge_flows(PktType proto);
- void prune_flows(PktType proto, Packet*);
+ void purge_flows(uint8_t proto);
+ void prune_flows(uint8_t proto, Packet*);
void timeout_flows(uint32_t flowCount, time_t cur_time);
char expected_flow (Flow*, Packet*);
int add_expected(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType protocol, char direction,
+ uint8_t protocol, char direction,
FlowData*);
int add_expected(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType protocol, int16_t appId,
+ uint8_t protocol, int16_t appId,
FlowData*);
- uint32_t max_flows(PktType proto);
- void get_prunes(PktType proto, PegCount&);
- void reset_prunes(PktType proto);
+ uint32_t max_flows(uint8_t proto);
+ void get_prunes(uint8_t proto, PegCount&);
+ void reset_prunes(uint8_t proto);
- PegCount get_flow_count(PktType);
+ PegCount get_flow_count(uint8_t);
void clear_flow_counts();
private:
- class FlowCache* get_cache(PktType);
+ class FlowCache* get_cache(uint8_t);
void set_key(FlowKey*, Packet*);
unsigned process(FlowCache*, Packet*);
inline void FlowKey::init4(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType proto, uint32_t mplsId, bool order)
+ uint8_t proto, uint32_t mplsId, bool order)
{
const uint32_t *src;
const uint32_t *dst;
- if ( proto == PktType::ICMP )
+ if ( proto == IPPROTO_ICMP )
{
if (srcPort == ICMP_ECHOREPLY)
{
inline void FlowKey::init6(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType proto, uint32_t mplsId, bool order)
+ uint8_t proto, uint32_t mplsId, bool order)
{
const sfip_t *src;
const sfip_t *dst;
- if (proto == PktType::ICMP)
- {
- // FIXIT-M J Need to determine specific protocol
- if ( srcPort == ICMP_ECHOREPLY )
- {
- dstPort = ICMP_ECHO; /* Treat ICMP echo reply the same as request */
- srcPort = 0;
- }
- else if (srcPort == icmp::Icmp6Types::REPLY_6)
- {
- dstPort = icmp::Icmp6Types::ECHO_6; /* Treat ICMPv6 echo reply the same as request */
- srcPort = 0;
- }
- else /* otherwise, every ICMP type gets different key */
- {
- dstPort = 0;
- }
- }
-
-#if 0 /* FIXIT-M J Delete after this has been proven to work */
if ( proto == IPPROTO_ICMP )
{
if (srcPort == ICMP_ECHOREPLY)
dstPort = 0;
}
}
-#endif
src = srcIP;
dst = dstIP;
void FlowKey::init(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType proto, uint16_t vlan,
+ uint8_t proto, uint16_t vlan,
uint32_t mplsId, uint16_t addrSpaceId)
{
/* Because the key is going to be used for hash lookups,
void FlowKey::init(
const sfip_t *srcIP, const sfip_t *dstIP,
- uint32_t id, PktType proto, uint16_t vlan,
+ uint32_t id, uint8_t proto, uint16_t vlan,
uint32_t mplsId, uint16_t addrSpaceId)
{
// to avoid confusing 2 different datagrams or confusing a datagram
else
{
version = 6;
- protocol = PktType::UNKNOWN;
+ protocol = 0;
init6(srcIP, srcPort, dstIP, dstPort, proto, mplsId, false);
}
#include "main/snort_types.h"
#include "hash/sfhashfcn.h"
#include "sfip/sfip_t.h"
-#include "framework/codec.h"
struct FlowKey
{
uint16_t port_l; /* Low Port - 0 if ICMP */
uint16_t port_h; /* High Port - 0 if ICMP */
uint16_t vlan_tag;
- PktType protocol;
+ uint8_t protocol;
uint8_t version;
uint32_t mplsLabel; /* MPLS label */
uint16_t addressSpaceId;
void init(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType proto, uint16_t vlan,
+ uint8_t proto, uint16_t vlan,
uint32_t mplsId, uint16_t addrSpaceId);
void init(
const sfip_t *srcIP, const sfip_t *dstIP,
- uint32_t id, PktType proto, uint16_t vlan,
+ uint32_t id, uint8_t proto, uint16_t vlan,
uint32_t mplsId, uint16_t addrSpaceId);
// XXX If this data structure changes size, compare must be updated!
void init4(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType proto, uint32_t mplsId, bool order = true);
+ uint8_t proto, uint32_t mplsId, bool order = true);
void init6(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType proto, uint32_t mplsId, bool order = true);
+ uint8_t proto, uint32_t mplsId, bool order = true);
};
MODULE_PROFILE_START(ipProtoPerfStats);
- const uint8_t ip_proto = p->ip_proto_next();
+ const uint8_t ip_proto = p->get_ip_proto_next();
switch (ipd->comparison_flag)
{
if (p->has_ip())
{
LogPriorityData(fast_log, event, 0);
- TextLog_Print(fast_log, "{%s} ", protocol_names[p->ip_proto_next()]);
+ TextLog_Print(fast_log, "{%s} ", protocol_names[p->get_ip_proto_next()]);
LogIpAddrs(fast_log, p);
}
// and only 1st 8 used for ip4
sar.src_ip = ntohl(packet->ptrs.ip_api.get_src()->ip32[0]);
sar.dest_ip = ntohl(packet->ptrs.ip_api.get_dst()->ip32[0]);
- sar.protocol = packet->ip_proto_next();
+ sar.protocol = packet->get_ip_proto_next();
if(packet->is_tcp() || packet->is_udp())
{
"<%s> ", PRINT_INTERFACE(DAQ_GetInterfaceSpec()));
}
- uint16_t proto = p->ip_proto_next();
+ uint16_t proto = p->get_ip_proto_next();
if (protocol_names[proto] != NULL)
{
SnortSnprintfAppend(event_string, sizeof(event_string),
}
else
{
- alertdata.protocol = p->ip_proto_next();
+ alertdata.protocol = p->get_ip_proto_next();
if ( p->type() == PktType::ICMP)
{
}
else
{
- alertdata.protocol = p->ip_proto_next();
+ alertdata.protocol = p->get_ip_proto_next();
if ( p->type() == PktType::ICMP)
{
g_tmp_pkt->ps_proto = IPPROTO_IP;
break;
case PS_PROTO_OPEN_PORT:
- g_tmp_pkt->ps_proto = p->ip_proto_next();
+ g_tmp_pkt->ps_proto = p->get_ip_proto_next();
break;
default:
return -1;
return false;
}
}
-
+#if 0
uint8_t Packet::ip_proto_next() const
{
if (is_ip4())
return IPPROTO_ID_RESERVED;
}
+#endif
-bool Packet::ip_proto_next(int &lyr, uint8_t& proto) const
+bool Packet::get_ip_proto_next(int &lyr, uint8_t& proto) const
{
if (lyr < 0)
return false;
uint16_t alt_dsize; /* the dsize of a packet before munging (used for log)*/
uint8_t num_layers; /* index into layers for next encap */
+ uint8_t ip_proto_next; /* the protocol ID after IP and all IP6 extension */
// nothing after this point is zeroed ...
* eth::ip4::udp::teredo::ip6::hop_opts::ipv6_routing::tcp
* this function return 6 == IPPROTO_TCP == IPPROTO_ID_TCP
*/
- uint8_t ip_proto_next() const;
+ inline uint8_t get_ip_proto_next() const
+ { return ip_proto_next; }
/* Similar to above. However, this function
* can be called in a loop to get all of the ip_proto's.
* ....
* }
*/
- bool ip_proto_next(int &lyr, uint8_t& proto) const;
+ bool get_ip_proto_next(int &lyr, uint8_t& proto) const;
inline void reset()
{
}
if (codec_data.proto_bits & (PROTO_BIT__IP | PROTO_BIT__IP6_EXT))
+ {
fpEvalIpProtoOnlyRules(p, codec_data.next_prot_id);
+ p->ip_proto_next = codec_data.next_prot_id;
+ }
// internal statistics and record keeping
push_layer(p, prev_prot_id, raw.data, codec_data.lyr_len);
result = stream.set_application_protocol_id_expected(
&session->clientIP, session->clientPort,
&session->serverIP, session->serverPort,
- p->type(), ftp_data_app_id, fd);
+ p->get_ip_proto_next(), ftp_data_app_id, fd);
if (result < 0)
delete fd;
stream.ignore_session(
&session->clientIP, session->clientPort,
&session->serverIP, session->serverPort,
- p->type(), FtpDataFlowData::flow_id,
+ p->get_ip_proto_next(), FtpDataFlowData::flow_id,
SSN_DIR_BOTH);
}
}
result = stream.set_application_protocol_id_expected(
&session->clientIP, session->clientPort,
&session->serverIP, session->serverPort,
- p->type(), ftp_data_app_id, fd);
+ p->get_ip_proto_next(), ftp_data_app_id, fd);
if (result < 0)
delete fd;
stream.ignore_session(
&session->clientIP, session->clientPort,
&session->serverIP, session->serverPort,
- p->type(), FtpDataFlowData::flow_id,
+ p->get_ip_proto_next(), FtpDataFlowData::flow_id,
SSN_DIR_BOTH);
}
}
void base_sum()
{
- t_stats.tcp = flow_con->get_flow_count(PktType::TCP);
- t_stats.udp = flow_con->get_flow_count(PktType::UDP);
- t_stats.icmp = flow_con->get_flow_count(PktType::ICMP);
- t_stats.ip = flow_con->get_flow_count(PktType::IP);
+ t_stats.tcp = flow_con->get_flow_count(IPPROTO_TCP);
+ t_stats.udp = flow_con->get_flow_count(IPPROTO_UDP);
+ t_stats.icmp = flow_con->get_flow_count(IPPROTO_ICMP);
+ t_stats.ip = flow_con->get_flow_count(IPPROTO_IP);
sum_stats((PegCount*)&g_stats, (PegCount*)&t_stats,
array_size(base_pegs));
void StreamBase::tterm()
{
- flow_con->purge_flows(PktType::TCP);
- flow_con->purge_flows(PktType::UDP);
- flow_con->purge_flows(PktType::ICMP);
- flow_con->purge_flows(PktType::IP);
+ flow_con->purge_flows(IPPROTO_TCP);
+ flow_con->purge_flows(IPPROTO_UDP);
+ flow_con->purge_flows(IPPROTO_ICMP);
+ flow_con->purge_flows(IPPROTO_IP);
delete flow_con;
flow_con = nullptr;
/* Get IP/TCP/UDP/ICMP session from original protocol/port info
* embedded in the ICMP Unreach message.
*/
- skey.protocol = p->type();
+ skey.protocol = p->get_ip_proto_next();
src = iph.get_src();
dst = iph.get_dst();
else
skey.vlan_tag = 0;
- switch (skey.protocol)
+ switch (p->type())
{
case PktType::TCP:
/* Lookup a TCP session */
void icmp_reset()
{
memset(&icmpStats, 0, sizeof(icmpStats));
- flow_con->reset_prunes(PktType::ICMP);
+ flow_con->reset_prunes(IPPROTO_ICMP);
}
* a rebuilt packet later. So don't process it further.
*/
if ((frag_offset != 0) ||
- ((p->ip_proto_next() != IPPROTO_UDP) && (p->ptrs.decode_flags & DECODE_MF)))
+ ((p->get_ip_proto_next() != IPPROTO_UDP) && (p->ptrs.decode_flags & DECODE_MF)))
{
DisableDetect(p);
}
FragRebuild(ft, p);
if (frag_offset != 0 ||
- (p->ip_proto_next() != IPPROTO_UDP && ft->frag_flags & FRAG_REBUILT))
+ (p->get_ip_proto_next() != IPPROTO_UDP && ft->frag_flags & FRAG_REBUILT))
{
/* Need to reset some things here because the
* rebuilt packet will have reset the do_detect
{
if(mem_in_use > FRAG_MEMCAP)
{
- flow_con->prune_flows(PktType::IP, p);
+ flow_con->prune_flows(IPPROTO_IP, p);
}
f = (Fragment *) SnortAlloc(sizeof(Fragment));
{
if(mem_in_use > FRAG_MEMCAP)
{
- flow_con->prune_flows(PktType::IP, p);
+ flow_con->prune_flows(IPPROTO_IP, p);
}
/*
{
if(mem_in_use > FRAG_MEMCAP)
{
- flow_con->prune_flows(PktType::IP, p);
+ flow_con->prune_flows(IPPROTO_IP, p);
}
/*
Flow* Stream::get_session_ptr_from_ip_port(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType ip_protocol, uint16_t vlan, uint32_t mplsId,
+ uint8_t ip_protocol, uint16_t vlan, uint32_t mplsId,
uint16_t addressSpaceId)
{
FlowKey key;
key->init(
p->ptrs.ip_api.get_src(), p->ptrs.sp,
p->ptrs.ip_api.get_dst(), p->ptrs.dp,
- p->type(),
+ p->get_ip_proto_next(),
// if the vlan protocol bit is defined, vlan layer gauranteed to exist
(p->proto_bits & PROTO_BIT__VLAN) ? layer::get_vlan_layer(p)->vid() : 0,
(p->proto_bits & PROTO_BIT__MPLS) ? p->ptrs.mplsHdr.label : 0,
FlowData* Stream::get_application_data_from_ip_port(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType ip_protocol, uint16_t vlan, uint32_t mplsId,
+ uint8_t ip_protocol, uint16_t vlan, uint32_t mplsId,
uint16_t addressSpaceID, unsigned flow_id)
{
Flow* flow;
int Stream::ignore_session(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType protocol, char direction,
+ uint8_t protocol, char direction,
uint32_t flow_id)
{
assert(flow_con);
int Stream::set_application_protocol_id_expected(
const sfip_t *srcIP, uint16_t srcPort,
const sfip_t *dstIP, uint16_t dstPort,
- PktType protocol, int16_t appId,
+ uint8_t protocol, int16_t appId,
FlowData* fd)
{
assert(flow_con);
*/
int ignore_session(
const sfip_t *addr1, uint16_t p1, const sfip_t *addr2, uint16_t p2,
- PktType proto, char dir, uint32_t ppId);
+ uint8_t proto, char dir, uint32_t ppId);
/* Resume inspection for session.
*/
* -1 on failure
*/
int set_application_protocol_id_expected(
- const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, PktType proto,
+ const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, uint8_t proto,
int16_t appId, FlowData*);
/** Retrieve application session data based on the lookup tuples for
* Application Data reference (pointer)
*/
static FlowData* get_application_data_from_ip_port(
- const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, PktType proto,
+ const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, uint8_t proto,
uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId, unsigned flow_id);
/* Get the application data from the session key
* Stream session pointer
*/
static Flow* get_session_ptr_from_ip_port(
- const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, PktType proto,
+ const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, uint8_t proto,
uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId);
/* Delete the session if it is in the closed session state.
tcp_memcap->dealloc(size);
return NULL;
}
- flow_con->prune_flows(PktType::TCP, p);
+ flow_con->prune_flows(IPPROTO_TCP, p);
}
ss = (StreamSegment*)SnortAlloc(size);
void tcp_reset()
{
- flow_con->reset_prunes(PktType::TCP);
+ flow_con->reset_prunes(IPPROTO_TCP);
}
void tcp_show(StreamTcpConfig* tcp_config)
void udp_reset()
{
- flow_con->reset_prunes(PktType::UDP);
+ flow_con->reset_prunes(IPPROTO_UDP);
}