]> git.ipfire.org Git - people/ms/suricata.git/blame - rust/src/core.rs
smb: recognizes file deletion over SMB2
[people/ms/suricata.git] / rust / src / core.rs
CommitLineData
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 20use std;
42e5065a 21use crate::filecontainer::*;
a809f090 22
94032d3a 23/// Opaque C types.
94032d3a
JI
24pub enum DetectEngineState {}
25pub enum AppLayerDecoderEvents {}
0af9a3a5 26pub enum AppLayerParserState {}
94032d3a 27
efe11dc3 28// From app-layer-events.h
3f6624bf 29pub type AppLayerEventType = std::os::raw::c_int;
efe11dc3
PC
30pub const APP_LAYER_EVENT_TYPE_TRANSACTION : i32 = 1;
31pub const APP_LAYER_EVENT_TYPE_PACKET : i32 = 2;
32
94032d3a 33// From stream.h.
905d9a1d
VJ
34pub const STREAM_START: u8 = 0x01;
35pub const STREAM_EOF: u8 = 0x02;
94032d3a
JI
36pub const STREAM_TOSERVER: u8 = 0x04;
37pub const STREAM_TOCLIENT: u8 = 0x08;
905d9a1d
VJ
38pub const STREAM_GAP: u8 = 0x10;
39pub const STREAM_DEPTH: u8 = 0x20;
40pub const STREAM_MIDSTREAM:u8 = 0x40;
94032d3a 41
e7c0a53c 42// Application layer protocol identifiers (app-layer-protos.h)
dee972b8 43pub type AppProto = u16;
e7c0a53c
PC
44
45pub const ALPROTO_UNKNOWN : AppProto = 0;
46pub static mut ALPROTO_FAILED : AppProto = 0; // updated during init
47
0301ceab
VJ
48pub const IPPROTO_TCP : i32 = 6;
49pub const IPPROTO_UDP : i32 = 17;
50
fdab22d9
PA
51macro_rules!BIT_U8 {
52 ($x:expr) => (1 << $x);
53}
54
2e46b5d1
PA
55macro_rules!BIT_U16 {
56 ($x:expr) => (1 << $x);
57}
58
a0e3e2d7
JI
59macro_rules!BIT_U32 {
60 ($x:expr) => (1 << $x);
61}
62
ba1a67e2
JI
63macro_rules!BIT_U64 {
64 ($x:expr) => (1 << $x);
65}
66
d1ea0052
SB
67// Flow flags
68pub const FLOW_DIR_REVERSED: u32 = BIT_U32!(26);
69
e7c0a53c
PC
70// Defined in app-layer-protos.h
71extern {
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)]
80pub 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
88pub type DetectEngineStateFreeFunc =
89 extern "C" fn(state: *mut DetectEngineState);
90
c77c8e70
SB
91pub type AppLayerParserTriggerRawStreamReassemblyFunc =
92 extern "C" fn (flow: *const Flow, direction: i32);
94032d3a
JI
93pub type AppLayerDecoderEventsSetEventRawFunc =
94 extern "C" fn (events: *mut *mut AppLayerDecoderEvents,
bf1bd407 95 event: u8);
94032d3a
JI
96
97pub type AppLayerDecoderEventsFreeEventsFunc =
98 extern "C" fn (events: *mut *mut AppLayerDecoderEvents);
99
bac8016d 100pub enum SuricataStreamingBufferConfig {}
a809f090 101
a809f090
VJ
102pub 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
109pub 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
114pub type SCFileAppendDataById = extern "C" fn (
115 file_container: &FileContainer,
116 track_id: u32,
117 data: *const u8, data_len: u32) -> i32;
58af3913
VJ
118pub type SCFileAppendGAPById = extern "C" fn (
119 file_container: &FileContainer,
120 track_id: u32,
121 data: *const u8, data_len: u32) -> i32;
a809f090
VJ
122pub type SCFilePrune = extern "C" fn (
123 file_container: &FileContainer);
a809f090
VJ
124pub type SCFileContainerRecycle = extern "C" fn (
125 file_container: &FileContainer);
126
71ddc43d
VJ
127pub 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)]
140pub 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)]
160pub struct SuricataFileContext {
161 pub files_sbcfg: &'static SuricataStreamingBufferConfig,
94032d3a
JI
162}
163
bac8016d
JI
164extern {
165 pub fn SCGetContext() -> &'static mut SuricataContext;
166 pub fn SCLogGetLogLevel() -> i32;
167}
168
94032d3a
JI
169pub static mut SC: Option<&'static SuricataContext> = None;
170
bac8016d 171pub 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]
180pub extern "C" fn rs_init(context: &'static mut SuricataContext)
181{
182 init_ffi(context);
183}
184
94032d3a
JI
185/// DetectEngineStateFree wrapper.
186pub 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
196pub 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.
205pub 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.
216pub 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)
227pub enum Flow {}
228
229/// Extern functions operating on Flow.
230extern {
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.
238impl 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}