]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Fixing main Detect() loop ... now gets correct ip_proto()
authorJosh <jrosenba@cisco.com>
Thu, 2 Oct 2014 15:49:44 +0000 (10:49 -0500)
committerJosh <jrosenba@cisco.com>
Thu, 2 Oct 2014 15:49:44 +0000 (10:49 -0500)
src/detection/detect.cc
src/detection/detect.h
src/protocols/packet.cc
src/protocols/packet.h

index 25bc60b9c48e7dbeb327879868ecabb5c4f85a25..8d3e2dafa8d7ba2b7985a47448cb84df0c897a6e 100644 (file)
@@ -301,14 +301,14 @@ int CheckTagging(Packet *p)
  *          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)
@@ -316,55 +316,49 @@ int Detect(Packet * p)
         /* 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(
index 5b0b42227a46cdac6653b0d34e6e18fcb5c0adb7..4a7d5de698b9195791c262efbc362accf89d3707 100644 (file)
@@ -50,7 +50,7 @@ extern THREAD_LOCAL ProfileStats detectPerfStats;
 /* 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);
index 339e9b2e85c6217adf0a8e6b5cc7f5edf42106d1..903ddc3e0e92c40bc929bb9e7b6e4979e45264ee 100644 (file)
@@ -72,3 +72,47 @@ uint8_t Packet::ip_proto_next() const
 
     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;
+}
index 0090ab335e45b1d762c4dad2ab1aa732c43b7dbb..244f3073a0e776ccd5b4364f005dda779f2cb4b0 100644 (file)
@@ -224,11 +224,29 @@ struct SO_PUBLIC Packet
      * 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));