1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2002-2013 Sourcefire, Inc.
4 // Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
5 //
6 // This program is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License Version 2 as published
8 // by the Free Software Foundation. You may not use, modify or distribute
9 // this program under any other version of the GNU General Public License.
10 //
11 // This program is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 //--------------------------------------------------------------------------
20
21 #ifndef PATTERN_MATCH_DATA_H
22 #define PATTERN_MATCH_DATA_H
23
24 #include <sys/time.h>
25 #include <vector>
26
27 #include "framework/ips_option.h" // FIXIT-L not a good dependency
28
29 struct PmdLastCheck
30 {
31 struct timeval ts;
32 uint64_t context_num;
33 uint32_t rebuild_flag;
34 uint16_t run_num;
35 };
36
37 struct PatternMatchData
38 {
39 const char* pattern_buf; // app layer pattern to match on
40
41 // FIXIT-L wasting some memory here:
42 // - this is not used by content option logic directly
43 // - and only used on current eval (not across packets)
44 // (partly mitigated by only allocating if exception_flag is set)
45 //
46 /* Set if fast pattern matcher found a content in the packet,
47 but the rule option specifies a negated content. Only
48 applies to negative contents that are not relative */
49 PmdLastCheck* last_check;
50
51 unsigned pattern_size; // size of app layer pattern
52
53 int offset; // pattern search start offset
54 int depth; // pattern search depth
55
56 enum
57 {
58 NEGATED = 0x01,
59 NO_CASE = 0x02,
60 RELATIVE = 0x04,
61 LITERAL = 0x08,
62 FAST_PAT = 0x10,
63 NO_FP = 0x20,
64 };
65
66 uint16_t flags; // from above enum
67 uint16_t mpse_flags; // passed through to mpse
68
69 uint16_t fp_offset;
70 uint16_t fp_length;
71
72 // not used by ips_content
73 uint8_t pm_type;
74
is_unboundedPatternMatchData75 bool is_unbounded() const
76 { return !depth; }
77
set_fast_patternPatternMatchData78 void set_fast_pattern()
79 { flags |= FAST_PAT; }
80
set_negatedPatternMatchData81 void set_negated()
82 { flags |= NEGATED; }
83
set_no_casePatternMatchData84 void set_no_case()
85 { flags |= NO_CASE; }
86
set_relativePatternMatchData87 void set_relative()
88 { flags |= RELATIVE; }
89
set_literalPatternMatchData90 void set_literal()
91 { flags |= LITERAL; }
92
is_fast_patternPatternMatchData93 bool is_fast_pattern() const
94 { return (flags & FAST_PAT) != 0; }
95
is_negatedPatternMatchData96 bool is_negated() const
97 { return (flags & NEGATED) != 0; }
98
is_no_casePatternMatchData99 bool is_no_case() const
100 { return (flags & NO_CASE) != 0; }
101
is_relativePatternMatchData102 bool is_relative() const
103 { return (flags & RELATIVE) != 0; }
104
is_literalPatternMatchData105 bool is_literal() const
106 { return (flags & LITERAL) != 0; }
107
108 bool can_be_fp() const;
109 };
110
111 typedef std::vector<PatternMatchData*> PatternMatchVector;
112
can_be_fp()113 inline bool PatternMatchData::can_be_fp() const
114 {
115 if ( !pattern_buf or !pattern_size )
116 return false;
117
118 if ( flags & NO_FP )
119 return false;
120
121 if ( !is_negated() )
122 return true;
123
124 // Negative contents can only be considered if they are not
125 // relative and don't have any offset or depth. This is because
126 // the pattern matcher does not take these into consideration and
127 // may find the content in a non-relevant section of the payload
128 // and thus disable the rule when it shouldn't be.
129
130 // Also case sensitive patterns cannot be considered since patterns
131 // are inserted into the pattern matcher without case which may
132 // lead to false negatives.
133
134 if ( is_relative() or !is_no_case() or offset or depth )
135 return false;
136
137 return true;
138 }
139
140 #endif
141
142