* 0 == no detection
*
***************************************************************************/
-int Detect(Packet * p)
+bool Detect(Packet * p)
{
int detected = 0;
PROFILE_VARS;
if ((p == NULL) || !p->ptrs.ip_api.is_valid())
{
- return 0;
+ return false;
}
if (p->packet_flags & PKT_PASS_RULE)
/* If we've already seen a pass rule on this,
* no need to continue do inspection.
*/
- return 0;
+ return false;
}
// FIXIT-M: Curently, if a rule is found on any IP layer, we
// perform the detect routine on the entire packet.
// Instead, we should only perform detect on that
// layer!!
- bool proto_found = false;
- ip::IpApi tmp_api;
- int8_t curr_layer = p->num_layers - 1;
- while (layer::set_inner_ip_api(p, tmp_api, curr_layer))
+ int curr_layer = p->num_layers - 1;
+ uint8_t ip_proto; // set in function
+
+ while (p->ip_proto_next(curr_layer, ip_proto))
{
- // FIXIT-H J We may be checking for an IP6 extension!
- if (snort_conf->ip_proto_array[tmp_api.proto()])
+ if (snort_conf->ip_proto_array[ip_proto])
{
- proto_found = true;
- break;
- }
- }
-
- if (!proto_found)
- return 0;
+# ifdef PPM_MGR
+ /*
+ * Packet Performance Monitoring
+ * (see if preprocessing took too long)
+ */
+ if( PPM_PKTS_ENABLED() )
+ {
+ PPM_GET_TIME();
+ PPM_PACKET_TEST();
+ if( PPM_PACKET_ABORT_FLAG() )
+ return false;
+ }
+# endif /* PPM_MGR */
-#ifdef PPM_MGR
- /*
- * Packet Performance Monitoring
- * (see if preprocessing took too long)
- */
- if( PPM_PKTS_ENABLED() )
- {
- PPM_GET_TIME();
- PPM_PACKET_TEST();
+ /*
+ ** This is where we short circuit so
+ ** that we can do IP checks.
+ */
+ MODULE_PROFILE_START(detectPerfStats);
+ detected = fpEvalPacket(p);
+ MODULE_PROFILE_END(detectPerfStats);
- if( PPM_PACKET_ABORT_FLAG() )
- return 0;
+ return detected;
+ }
}
-#endif
-
- /*
- ** This is where we short circuit so
- ** that we can do IP checks.
- */
- MODULE_PROFILE_START(detectPerfStats);
- detected = fpEvalPacket(p);
- MODULE_PROFILE_END(detectPerfStats);
- return detected;
+ return false;
}
int CheckAddrPort(
/* detection/manipulation funcs */
void snort_ignore(Packet*);
void snort_inspect(Packet*);
-SO_PUBLIC int Detect(Packet *);
+SO_PUBLIC bool Detect(Packet *);
void CallOutputPlugins(Packet *);
int EvalPacket(ListHead *, int, Packet * );
int EvalHeader(RuleTreeNode *, Packet *, int);
return IPPROTO_ID_RESERVED;
}
+
+static inline bool is_ip_protocol(const uint16_t proto)
+{
+ switch(proto)
+ {
+ case IPPROTO_ID_HOPOPTS:
+ case IPPROTO_ID_DSTOPTS:
+ case IPPROTO_ID_ROUTING:
+ case IPPROTO_ID_FRAGMENT:
+ case IPPROTO_ID_AUTH:
+ case IPPROTO_ID_ESP:
+ case IPPROTO_ID_MOBILITY:
+ case IPPROTO_ID_IPIP:
+ case IPPROTO_ID_IPV6:
+ case ETHERTYPE_IPV4:
+ case ETHERTYPE_IPV6:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool Packet::ip_proto_next(int &lyr, uint8_t& proto) const
+{
+ if (lyr < 0)
+ return false;
+
+ // lyr[0] will always return false
+ // walk past any ip6 options/IP protocols
+ while (is_ip_protocol(layers[lyr].prot_id))
+ --lyr;
+
+ while (lyr >= 0)
+ {
+ if (is_ip_protocol(layers[lyr].prot_id))
+ return true;
+ else
+ proto = layers[lyr].prot_id;
+
+ --lyr;
+ }
+
+ return false;
+}
* can frequently be an IP extension. Therefore, this function
* return the protocol ID of the first protocol after all the
* IP layers. For instance, if the stack is
- * eth::ip6::hop_opts::ipv6_routing::UDP
- * this function return 17 == IPPROTO_UDP == IPPROTO_ID_UDP
+ * 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;
+ /* Similar to above. However, this function
+ * can be called in a loop to get all of the ip_proto's.
+ * NOTE: Will only return protocols of validly decoded layers.
+ *
+ * PARAMS:
+ * lyr - zero based layer from which to start searching outward.
+ * will always point to an IP protocol or IP extension.
+ * ip_proto - the ip_proto (read above) for the next, outermost IP layer
+ * EXAMPLE:
+ *
+ * int lyr = p->num_layers - 1;
+ * while ( ip_proto_next(lyr, ip_proto))
+ * {
+ * ....
+ * }
+ */
+ bool ip_proto_next(int &lyr, uint8_t& proto) const;
+
inline void reset()
{
memset(&flow, '\0', offsetof(Packet, pkth));