/src/suricata8/src/util-spm-bs.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2010 Open Information Security Foundation |
2 | | * |
3 | | * You can copy, redistribute or modify this Program under the terms of |
4 | | * the GNU General Public License version 2 as published by the Free |
5 | | * Software Foundation. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * version 2 along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
15 | | * 02110-1301, USA. |
16 | | */ |
17 | | |
18 | | /** |
19 | | * \file |
20 | | * |
21 | | * \author Victor Julien <victor@inliniac.net> |
22 | | * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com> |
23 | | * |
24 | | * bs is a bruteforce search. It will try to search the pattern |
25 | | * from all characters until the available text len is less |
26 | | * than the length of the pattern. It needs no context but it |
27 | | * time cost is not good. |
28 | | */ |
29 | | |
30 | | #include "suricata-common.h" |
31 | | #include "suricata.h" |
32 | | |
33 | | #include "util-debug.h" |
34 | | #include "util-spm-bs.h" |
35 | | |
36 | | /** |
37 | | * \brief Basic search improved. Limits are better handled, so |
38 | | * it doesn't start searches that wont fit in the remaining buffer |
39 | | * |
40 | | * \param haystack pointer to the buffer to search in |
41 | | * \param haystack_len length limit of the buffer |
42 | | * \param needle pointer to the pattern we ar searching for |
43 | | * \param needle_len length limit of the needle |
44 | | * |
45 | | * \retval ptr to start of the match; NULL if no match |
46 | | */ |
47 | | uint8_t *BasicSearch(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len) |
48 | 17.1k | { |
49 | 17.1k | SCEnter(); |
50 | | |
51 | 17.1k | const uint8_t *h, *n; |
52 | 17.1k | const uint8_t *hmax = haystack + haystack_len; |
53 | 17.1k | const uint8_t *nmax = needle + needle_len; |
54 | | |
55 | 17.1k | if (needle_len == 0 || needle_len > haystack_len) { |
56 | 671 | SCReturnPtr(NULL, "uint8_t"); |
57 | 671 | } |
58 | | |
59 | | //PrintRawDataFp(stdout,needle,needle_len); |
60 | | |
61 | | //PrintRawDataFp(stdout,haystack,haystack_len); |
62 | | |
63 | 13.5M | for (n = needle; nmax - n <= hmax - haystack; haystack++) { |
64 | 13.5M | if (*haystack != *n) { |
65 | 13.3M | continue; |
66 | 13.3M | } |
67 | | |
68 | 174k | SCLogDebug("*haystack == *n, %c == %c", *haystack, *n); |
69 | | |
70 | | /* one byte needles */ |
71 | 174k | if (needle_len == 1) { |
72 | 0 | SCReturnPtr((uint8_t *)haystack, "uint8_t"); |
73 | 0 | } |
74 | | |
75 | 176k | for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) { |
76 | 176k | if (*h != *n) { |
77 | 174k | break; |
78 | 174k | } |
79 | 1.20k | SCLogDebug("*haystack == *n, %c == %c", *haystack, *n); |
80 | | /* if we run out of needle we fully matched */ |
81 | 1.20k | if (n == nmax - 1) { |
82 | 25 | SCReturnPtr((uint8_t *)haystack, "uint8_t"); |
83 | 25 | } |
84 | 1.20k | } |
85 | 174k | n = needle; |
86 | 174k | } |
87 | | |
88 | 16.5k | SCReturnPtr(NULL, "uint8_t"); |
89 | 16.5k | } |
90 | | |
91 | | /** |
92 | | * \brief Basic search case less |
93 | | * |
94 | | * \param haystack pointer to the buffer to search in |
95 | | * \param haystack_len length limit of the buffer |
96 | | * \param needle pointer to the pattern we ar searching for |
97 | | * \param needle_len length limit of the needle |
98 | | * |
99 | | * \retval ptr to start of the match; NULL if no match |
100 | | */ |
101 | | uint8_t *BasicSearchNocase(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len) |
102 | 0 | { |
103 | 0 | const uint8_t *h, *n; |
104 | 0 | const uint8_t *hmax = haystack + haystack_len; |
105 | 0 | const uint8_t *nmax = needle + needle_len; |
106 | |
|
107 | 0 | if (needle_len == 0 || needle_len > haystack_len) |
108 | 0 | return NULL; |
109 | | |
110 | 0 | for (n = needle; nmax - n <= hmax - haystack; haystack++) { |
111 | 0 | if (u8_tolower(*haystack) != u8_tolower(*n)) { |
112 | 0 | continue; |
113 | 0 | } |
114 | | /* one byte needles */ |
115 | 0 | if (needle_len == 1) { |
116 | 0 | return (uint8_t *)haystack; |
117 | 0 | } |
118 | | |
119 | 0 | for (h = haystack+1, n++; nmax - n <= hmax - h ; h++, n++) { |
120 | 0 | if (u8_tolower(*h) != u8_tolower(*n)) { |
121 | 0 | break; |
122 | 0 | } |
123 | | /* if we run out of needle we fully matched */ |
124 | 0 | if (n == nmax - 1) { |
125 | 0 | return (uint8_t *)haystack; |
126 | 0 | } |
127 | 0 | } |
128 | 0 | n = needle; |
129 | 0 | } |
130 | | |
131 | 0 | return NULL; |
132 | 0 | } |
133 | | |
134 | | uint32_t BasicSearchNocaseIndex( |
135 | | const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len) |
136 | 0 | { |
137 | 0 | uint8_t *r = BasicSearchNocase(haystack, haystack_len, needle, needle_len); |
138 | 0 | if (r == NULL) { |
139 | 0 | return haystack_len; |
140 | 0 | } |
141 | 0 | return (uint32_t)(r - haystack); |
142 | 0 | } |