/src/suricata7/src/decode-raw.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2021 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 | | * \ingroup decode |
20 | | * |
21 | | * @{ |
22 | | */ |
23 | | |
24 | | |
25 | | /** |
26 | | * \file |
27 | | * |
28 | | * \author William Metcalf <william.metcalf@gmail.com> |
29 | | * |
30 | | * Decode RAW |
31 | | */ |
32 | | |
33 | | #include "suricata-common.h" |
34 | | #include "decode-raw.h" |
35 | | #include "decode.h" |
36 | | #include "decode-events.h" |
37 | | |
38 | | #include "util-validate.h" |
39 | | #include "util-unittest.h" |
40 | | #include "util-debug.h" |
41 | | |
42 | | int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, |
43 | | const uint8_t *pkt, uint32_t len) |
44 | 507k | { |
45 | 507k | DEBUG_VALIDATE_BUG_ON(pkt == NULL); |
46 | | |
47 | 507k | StatsIncr(tv, dtv->counter_raw); |
48 | | |
49 | | /* If it is ipv4 or ipv6 it should at least be the size of ipv4 */ |
50 | 507k | if (unlikely(len < IPV4_HEADER_LEN)) { |
51 | 108k | ENGINE_SET_INVALID_EVENT(p, IPV4_PKT_TOO_SMALL); |
52 | 108k | return TM_ECODE_FAILED; |
53 | 108k | } |
54 | | |
55 | | |
56 | | |
57 | 398k | if (IP_GET_RAW_VER(pkt) == 4) { |
58 | 249k | if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) { |
59 | 28 | return TM_ECODE_FAILED; |
60 | 28 | } |
61 | 249k | SCLogDebug("IPV4 Packet"); |
62 | 249k | DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), (uint16_t)(GET_PKT_LEN(p))); |
63 | 249k | } else if (IP_GET_RAW_VER(pkt) == 6) { |
64 | 139k | if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) { |
65 | 36 | return TM_ECODE_FAILED; |
66 | 36 | } |
67 | 139k | SCLogDebug("IPV6 Packet"); |
68 | 139k | DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), (uint16_t)(GET_PKT_LEN(p))); |
69 | 139k | } else { |
70 | 9.26k | SCLogDebug("Unknown ip version %d", IP_GET_RAW_VER(pkt)); |
71 | 9.26k | ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV); |
72 | 9.26k | } |
73 | 398k | return TM_ECODE_OK; |
74 | 398k | } |
75 | | |
76 | | #ifdef UNITTESTS |
77 | | #include "util-unittest-helper.h" |
78 | | #include "packet.h" |
79 | | |
80 | | /** DecodeRawtest01 |
81 | | * \brief Valid Raw packet |
82 | | * \retval 0 Expected test value |
83 | | */ |
84 | | static int DecodeRawTest01 (void) |
85 | | { |
86 | | |
87 | | /* IPV6/TCP/no eth header */ |
88 | | uint8_t raw_ip[] = { |
89 | | 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, |
90 | | 0x20, 0x01, 0x06, 0x18, 0x04, 0x00, 0x00, 0x00, |
91 | | 0x00, 0x00, 0x00, 0x00, 0x51, 0x99, 0xcc, 0x70, |
92 | | 0x20, 0x01, 0x06, 0x18, 0x00, 0x01, 0x80, 0x00, |
93 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, |
94 | | 0x8c, 0x9b, 0x00, 0x50, 0x6a, 0xe7, 0x07, 0x36, |
95 | | 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0x30, |
96 | | 0x29, 0x9c, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8c, |
97 | | 0x04, 0x02, 0x08, 0x0a, 0x00, 0xdd, 0x1a, 0x39, |
98 | | 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02 }; |
99 | | Packet *p = PacketGetFromAlloc(); |
100 | | if (unlikely(p == NULL)) |
101 | | return 0; |
102 | | ThreadVars tv; |
103 | | DecodeThreadVars dtv; |
104 | | |
105 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
106 | | memset(&tv, 0, sizeof(ThreadVars)); |
107 | | |
108 | | if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { |
109 | | SCFree(p); |
110 | | return 0; |
111 | | } |
112 | | |
113 | | FlowInitConfig(FLOW_QUIET); |
114 | | |
115 | | DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p)); |
116 | | if (p->ip6h == NULL) { |
117 | | printf("expected a valid ipv6 header but it was NULL: "); |
118 | | FlowShutdown(); |
119 | | SCFree(p); |
120 | | return 0; |
121 | | } |
122 | | |
123 | | PacketRecycle(p); |
124 | | FlowShutdown(); |
125 | | SCFree(p); |
126 | | return 1; |
127 | | |
128 | | } |
129 | | /** DecodeRawtest02 |
130 | | * \brief Valid Raw packet |
131 | | * \retval 0 Expected test value |
132 | | */ |
133 | | static int DecodeRawTest02 (void) |
134 | | { |
135 | | |
136 | | /* IPV4/TCP/no eth header */ |
137 | | uint8_t raw_ip[] = { |
138 | | 0x45, 0x00, 0x00, 0x30, 0x00, 0xad, 0x40, 0x00, |
139 | | 0x7f, 0x06, 0xac, 0xc5, 0xc0, 0xa8, 0x67, 0x02, |
140 | | 0xc0, 0xa8, 0x66, 0x02, 0x0b, 0xc7, 0x00, 0x50, |
141 | | 0x1d, 0xb3, 0x12, 0x37, 0x00, 0x00, 0x00, 0x00, |
142 | | 0x70, 0x02, 0x40, 0x00, 0xb8, 0xc8, 0x00, 0x00, |
143 | | 0x02, 0x04, 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 }; |
144 | | |
145 | | Packet *p = PacketGetFromAlloc(); |
146 | | if (unlikely(p == NULL)) |
147 | | return 0; |
148 | | ThreadVars tv; |
149 | | DecodeThreadVars dtv; |
150 | | |
151 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
152 | | memset(&tv, 0, sizeof(ThreadVars)); |
153 | | |
154 | | if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { |
155 | | SCFree(p); |
156 | | return 0; |
157 | | } |
158 | | |
159 | | FlowInitConfig(FLOW_QUIET); |
160 | | |
161 | | DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p)); |
162 | | if (p->ip4h == NULL) { |
163 | | printf("expected a valid ipv4 header but it was NULL: "); |
164 | | PacketRecycle(p); |
165 | | FlowShutdown(); |
166 | | SCFree(p); |
167 | | return 0; |
168 | | } |
169 | | |
170 | | PacketRecycle(p); |
171 | | FlowShutdown(); |
172 | | SCFree(p); |
173 | | return 1; |
174 | | } |
175 | | /** DecodeRawtest03 |
176 | | * \brief Valid Raw packet |
177 | | * \retval 0 Expected test value |
178 | | */ |
179 | | static int DecodeRawTest03 (void) |
180 | | { |
181 | | |
182 | | /* IPV13 */ |
183 | | uint8_t raw_ip[] = { |
184 | | 0xdf, 0x00, 0x00, 0x3d, 0x49, 0x42, 0x40, 0x00, |
185 | | 0x40, 0x06, 0xcf, 0x8a, 0x0a, 0x1f, 0x03, 0xaf, |
186 | | 0x0a, 0x1f, 0x0a, 0x02, 0xa5, 0xe7, 0xde, 0xad, |
187 | | 0x00, 0x0c, 0xe2, 0x0e, 0x8b, 0xfe, 0x0c, 0xe7, |
188 | | 0x80, 0x18, 0x00, 0xb7, 0xaf, 0xeb, 0x00, 0x00, |
189 | | 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xab, 0x4f, |
190 | | 0x34, 0x40, 0x67, 0x31, 0x3b, 0x63, 0x61, 0x74, |
191 | | 0x20, 0x6b, 0x65, 0x79, 0x3b }; |
192 | | |
193 | | Packet *p = PacketGetFromAlloc(); |
194 | | if (unlikely(p == NULL)) |
195 | | return 0; |
196 | | ThreadVars tv; |
197 | | DecodeThreadVars dtv; |
198 | | |
199 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
200 | | memset(&tv, 0, sizeof(ThreadVars)); |
201 | | |
202 | | if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { |
203 | | SCFree(p); |
204 | | return 0; |
205 | | } |
206 | | |
207 | | FlowInitConfig(FLOW_QUIET); |
208 | | |
209 | | DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p)); |
210 | | if (!ENGINE_ISSET_EVENT(p,IPRAW_INVALID_IPV)) { |
211 | | printf("expected IPRAW_INVALID_IPV to be set but it wasn't: "); |
212 | | FlowShutdown(); |
213 | | SCFree(p); |
214 | | return 0; |
215 | | } |
216 | | PacketRecycle(p); |
217 | | FlowShutdown(); |
218 | | SCFree(p); |
219 | | return 1; |
220 | | } |
221 | | |
222 | | #endif /* UNITTESTS */ |
223 | | |
224 | | /** |
225 | | * \brief Registers Raw unit tests |
226 | | * \todo More Raw tests |
227 | | */ |
228 | | void DecodeRawRegisterTests(void) |
229 | 0 | { |
230 | | #ifdef UNITTESTS |
231 | | UtRegisterTest("DecodeRawTest01", DecodeRawTest01); |
232 | | UtRegisterTest("DecodeRawTest02", DecodeRawTest02); |
233 | | UtRegisterTest("DecodeRawTest03", DecodeRawTest03); |
234 | | #endif /* UNITTESTS */ |
235 | 0 | } |
236 | | /** |
237 | | * @} |
238 | | */ |