]>
Commit | Line | Data |
---|---|---|
94032d3a JI |
1 | /* Copyright (C) 2017 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 | // This file exposes items from the core "C" code to Rust. | |
19 | ||
3f6624bf | 20 | use std; |
42e5065a | 21 | use crate::filecontainer::*; |
a809f090 | 22 | |
94032d3a | 23 | /// Opaque C types. |
94032d3a JI |
24 | pub enum DetectEngineState {} |
25 | pub enum AppLayerDecoderEvents {} | |
0af9a3a5 | 26 | pub enum AppLayerParserState {} |
94032d3a | 27 | |
efe11dc3 | 28 | // From app-layer-events.h |
3f6624bf | 29 | pub type AppLayerEventType = std::os::raw::c_int; |
efe11dc3 PC |
30 | pub const APP_LAYER_EVENT_TYPE_TRANSACTION : i32 = 1; |
31 | pub const APP_LAYER_EVENT_TYPE_PACKET : i32 = 2; | |
32 | ||
94032d3a | 33 | // From stream.h. |
905d9a1d VJ |
34 | pub const STREAM_START: u8 = 0x01; |
35 | pub const STREAM_EOF: u8 = 0x02; | |
94032d3a JI |
36 | pub const STREAM_TOSERVER: u8 = 0x04; |
37 | pub const STREAM_TOCLIENT: u8 = 0x08; | |
905d9a1d VJ |
38 | pub const STREAM_GAP: u8 = 0x10; |
39 | pub const STREAM_DEPTH: u8 = 0x20; | |
40 | pub const STREAM_MIDSTREAM:u8 = 0x40; | |
94032d3a | 41 | |
e7c0a53c | 42 | // Application layer protocol identifiers (app-layer-protos.h) |
dee972b8 | 43 | pub type AppProto = u16; |
e7c0a53c PC |
44 | |
45 | pub const ALPROTO_UNKNOWN : AppProto = 0; | |
46 | pub static mut ALPROTO_FAILED : AppProto = 0; // updated during init | |
47 | ||
0301ceab VJ |
48 | pub const IPPROTO_TCP : i32 = 6; |
49 | pub const IPPROTO_UDP : i32 = 17; | |
50 | ||
fdab22d9 PA |
51 | macro_rules!BIT_U8 { |
52 | ($x:expr) => (1 << $x); | |
53 | } | |
54 | ||
2e46b5d1 PA |
55 | macro_rules!BIT_U16 { |
56 | ($x:expr) => (1 << $x); | |
57 | } | |
58 | ||
a0e3e2d7 JI |
59 | macro_rules!BIT_U32 { |
60 | ($x:expr) => (1 << $x); | |
61 | } | |
62 | ||
ba1a67e2 JI |
63 | macro_rules!BIT_U64 { |
64 | ($x:expr) => (1 << $x); | |
65 | } | |
66 | ||
d1ea0052 SB |
67 | // Flow flags |
68 | pub const FLOW_DIR_REVERSED: u32 = BIT_U32!(26); | |
69 | ||
e7c0a53c PC |
70 | // Defined in app-layer-protos.h |
71 | extern { | |
72 | pub fn StringToAppProto(proto_name: *const u8) -> AppProto; | |
73 | } | |
74 | ||
94032d3a JI |
75 | // |
76 | // Function types for calls into C. | |
77 | // | |
78 | ||
79 | #[allow(non_snake_case)] | |
80 | pub type SCLogMessageFunc = | |
3f6624bf VJ |
81 | extern "C" fn(level: std::os::raw::c_int, |
82 | filename: *const std::os::raw::c_char, | |
83 | line: std::os::raw::c_uint, | |
84 | function: *const std::os::raw::c_char, | |
85 | code: std::os::raw::c_int, | |
86 | message: *const std::os::raw::c_char) -> std::os::raw::c_int; | |
94032d3a JI |
87 | |
88 | pub type DetectEngineStateFreeFunc = | |
89 | extern "C" fn(state: *mut DetectEngineState); | |
90 | ||
c77c8e70 SB |
91 | pub type AppLayerParserTriggerRawStreamReassemblyFunc = |
92 | extern "C" fn (flow: *const Flow, direction: i32); | |
94032d3a JI |
93 | pub type AppLayerDecoderEventsSetEventRawFunc = |
94 | extern "C" fn (events: *mut *mut AppLayerDecoderEvents, | |
bf1bd407 | 95 | event: u8); |
94032d3a JI |
96 | |
97 | pub type AppLayerDecoderEventsFreeEventsFunc = | |
98 | extern "C" fn (events: *mut *mut AppLayerDecoderEvents); | |
99 | ||
bac8016d | 100 | pub enum SuricataStreamingBufferConfig {} |
a809f090 | 101 | |
a809f090 VJ |
102 | pub type SCFileOpenFileWithId = extern "C" fn ( |
103 | file_container: &FileContainer, | |
104 | sbcfg: &SuricataStreamingBufferConfig, | |
105 | track_id: u32, | |
106 | name: *const u8, name_len: u16, | |
107 | data: *const u8, data_len: u32, | |
45c5030f | 108 | flags: u16) -> i32; |
a809f090 VJ |
109 | pub type SCFileCloseFileById = extern "C" fn ( |
110 | file_container: &FileContainer, | |
111 | track_id: u32, | |
112 | data: *const u8, data_len: u32, | |
113 | flags: u16) -> i32; | |
a809f090 VJ |
114 | pub type SCFileAppendDataById = extern "C" fn ( |
115 | file_container: &FileContainer, | |
116 | track_id: u32, | |
117 | data: *const u8, data_len: u32) -> i32; | |
58af3913 VJ |
118 | pub type SCFileAppendGAPById = extern "C" fn ( |
119 | file_container: &FileContainer, | |
120 | track_id: u32, | |
121 | data: *const u8, data_len: u32) -> i32; | |
a809f090 VJ |
122 | pub type SCFilePrune = extern "C" fn ( |
123 | file_container: &FileContainer); | |
a809f090 VJ |
124 | pub type SCFileContainerRecycle = extern "C" fn ( |
125 | file_container: &FileContainer); | |
126 | ||
71ddc43d VJ |
127 | pub type SCFileSetTx = extern "C" fn ( |
128 | file: &FileContainer, | |
129 | tx_id: u64); | |
a809f090 | 130 | |
94032d3a JI |
131 | // A Suricata context that is passed in from C. This is alternative to |
132 | // using functions from Suricata directly, so they can be wrapped so | |
133 | // Rust unit tests will still compile when they are not linked | |
134 | // directly to the real function. | |
135 | // | |
136 | // This might add a little too much complexity to keep pure Rust test | |
137 | // cases working. | |
138 | #[allow(non_snake_case)] | |
139 | #[repr(C)] | |
140 | pub struct SuricataContext { | |
717b826d | 141 | pub SCLogMessage: SCLogMessageFunc, |
94032d3a JI |
142 | DetectEngineStateFree: DetectEngineStateFreeFunc, |
143 | AppLayerDecoderEventsSetEventRaw: AppLayerDecoderEventsSetEventRawFunc, | |
144 | AppLayerDecoderEventsFreeEvents: AppLayerDecoderEventsFreeEventsFunc, | |
c77c8e70 | 145 | pub AppLayerParserTriggerRawStreamReassembly: AppLayerParserTriggerRawStreamReassemblyFunc, |
a809f090 VJ |
146 | |
147 | pub FileOpenFile: SCFileOpenFileWithId, | |
148 | pub FileCloseFile: SCFileCloseFileById, | |
149 | pub FileAppendData: SCFileAppendDataById, | |
58af3913 | 150 | pub FileAppendGAP: SCFileAppendGAPById, |
a809f090 VJ |
151 | pub FileContainerRecycle: SCFileContainerRecycle, |
152 | pub FilePrune: SCFilePrune, | |
71ddc43d | 153 | pub FileSetTx: SCFileSetTx, |
3ada5e14 JI |
154 | |
155 | pub AppLayerRegisterParser: extern fn(parser: *const crate::applayer::RustParser, alproto: AppProto) -> std::os::raw::c_int, | |
a809f090 VJ |
156 | } |
157 | ||
158 | #[allow(non_snake_case)] | |
159 | #[repr(C)] | |
160 | pub struct SuricataFileContext { | |
161 | pub files_sbcfg: &'static SuricataStreamingBufferConfig, | |
94032d3a JI |
162 | } |
163 | ||
bac8016d JI |
164 | extern { |
165 | pub fn SCGetContext() -> &'static mut SuricataContext; | |
166 | pub fn SCLogGetLogLevel() -> i32; | |
167 | } | |
168 | ||
94032d3a JI |
169 | pub static mut SC: Option<&'static SuricataContext> = None; |
170 | ||
bac8016d | 171 | pub fn init_ffi(context: &'static mut SuricataContext) |
94032d3a JI |
172 | { |
173 | unsafe { | |
174 | SC = Some(context); | |
e7c0a53c | 175 | ALPROTO_FAILED = StringToAppProto("failed\0".as_ptr()); |
94032d3a JI |
176 | } |
177 | } | |
178 | ||
bac8016d JI |
179 | #[no_mangle] |
180 | pub extern "C" fn rs_init(context: &'static mut SuricataContext) | |
181 | { | |
182 | init_ffi(context); | |
183 | } | |
184 | ||
94032d3a JI |
185 | /// DetectEngineStateFree wrapper. |
186 | pub fn sc_detect_engine_state_free(state: *mut DetectEngineState) | |
187 | { | |
188 | unsafe { | |
189 | if let Some(c) = SC { | |
190 | (c.DetectEngineStateFree)(state); | |
191 | } | |
192 | } | |
193 | } | |
194 | ||
c77c8e70 SB |
195 | /// AppLayerParserTriggerRawStreamReassembly wrapper |
196 | pub fn sc_app_layer_parser_trigger_raw_stream_reassembly(flow: *const Flow, direction: i32) { | |
197 | unsafe { | |
198 | if let Some(c) = SC { | |
199 | (c.AppLayerParserTriggerRawStreamReassembly)(flow, direction); | |
200 | } | |
201 | } | |
202 | } | |
203 | ||
94032d3a JI |
204 | /// AppLayerDecoderEventsSetEventRaw wrapper. |
205 | pub fn sc_app_layer_decoder_events_set_event_raw( | |
bf1bd407 | 206 | events: *mut *mut AppLayerDecoderEvents, event: u8) |
94032d3a JI |
207 | { |
208 | unsafe { | |
209 | if let Some(c) = SC { | |
210 | (c.AppLayerDecoderEventsSetEventRaw)(events, event); | |
211 | } | |
212 | } | |
213 | } | |
214 | ||
215 | /// AppLayerDecoderEventsFreeEvents wrapper. | |
216 | pub fn sc_app_layer_decoder_events_free_events( | |
217 | events: *mut *mut AppLayerDecoderEvents) | |
218 | { | |
219 | unsafe { | |
220 | if let Some(c) = SC { | |
221 | (c.AppLayerDecoderEventsFreeEvents)(events); | |
222 | } | |
223 | } | |
224 | } | |
80cafb29 JI |
225 | |
226 | /// Opaque flow type (defined in C) | |
227 | pub enum Flow {} | |
228 | ||
229 | /// Extern functions operating on Flow. | |
230 | extern { | |
231 | pub fn FlowGetLastTimeAsParts(flow: &Flow, secs: *mut u64, usecs: *mut u64); | |
222e5584 JI |
232 | pub fn FlowGetFlags(flow: &Flow) -> u32; |
233 | pub fn FlowGetSourcePort(flow: &Flow) -> u16; | |
234 | pub fn FlowGetDestinationPort(flow: &Flow) -> u16; | |
80cafb29 JI |
235 | } |
236 | ||
237 | /// Rust implementation of Flow. | |
238 | impl Flow { | |
239 | ||
240 | /// Return the time of the last flow update as a `Duration` | |
241 | /// since the epoch. | |
242 | pub fn get_last_time(&mut self) -> std::time::Duration { | |
243 | unsafe { | |
244 | let mut secs: u64 = 0; | |
245 | let mut usecs: u64 = 0; | |
246 | FlowGetLastTimeAsParts(self, &mut secs, &mut usecs); | |
247 | std::time::Duration::new(secs, usecs as u32 * 1000) | |
248 | } | |
249 | } | |
222e5584 JI |
250 | |
251 | /// Return the flow flags. | |
252 | pub fn get_flags(&self) -> u32 { | |
253 | unsafe { FlowGetFlags(self) } | |
254 | } | |
255 | ||
256 | /// Return flow ports | |
257 | pub fn get_ports(&self) -> (u16, u16) { | |
258 | unsafe { (FlowGetSourcePort(self), FlowGetDestinationPort(self)) } | |
259 | } | |
2e46b5d1 | 260 | } |