1 /* Copyright (C) 2017-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 //! Parser registration functions and common interface 19 20 use std; 21 use crate::core::{DetectEngineState,Flow,AppLayerEventType,AppLayerDecoderEvents,AppProto}; 22 use crate::filecontainer::FileContainer; 23 use crate::applayer; 24 use std::os::raw::{c_void,c_char,c_int}; 25 26 #[repr(C)] 27 #[derive(Debug,PartialEq)] 28 pub struct AppLayerTxConfig { 29 /// config: log flags 30 log_flags: u8, 31 } 32 33 impl AppLayerTxConfig { new() -> Self34 pub fn new() -> Self { 35 Self { 36 log_flags: 0, 37 } 38 } 39 add_log_flags(&mut self, flags: u8)40 pub fn add_log_flags(&mut self, flags: u8) { 41 self.log_flags |= flags; 42 } set_log_flags(&mut self, flags: u8)43 pub fn set_log_flags(&mut self, flags: u8) { 44 self.log_flags = flags; 45 } get_log_flags(&self) -> u846 pub fn get_log_flags(&self) -> u8 { 47 self.log_flags 48 } 49 } 50 51 #[repr(C)] 52 #[derive(Debug,PartialEq)] 53 pub struct AppLayerTxData { 54 /// config: log flags 55 pub config: AppLayerTxConfig, 56 57 /// logger flags for tx logging api 58 logged: LoggerFlags, 59 60 /// track file open/logs so we can know how long to keep the tx 61 pub files_opened: u32, 62 pub files_logged: u32, 63 pub files_stored: u32, 64 65 /// detection engine flags for use by detection engine 66 detect_flags_ts: u64, 67 detect_flags_tc: u64, 68 } 69 70 impl AppLayerTxData { new() -> Self71 pub fn new() -> Self { 72 Self { 73 config: AppLayerTxConfig::new(), 74 logged: LoggerFlags::new(), 75 files_opened: 0, 76 files_logged: 0, 77 files_stored: 0, 78 detect_flags_ts: 0, 79 detect_flags_tc: 0, 80 } 81 } init_files_opened(&mut self)82 pub fn init_files_opened(&mut self) { 83 self.files_opened = 1; 84 } incr_files_opened(&mut self)85 pub fn incr_files_opened(&mut self) { 86 self.files_opened += 1; 87 } 88 } 89 90 #[macro_export] 91 macro_rules!export_tx_data_get { 92 ($name:ident, $type:ty) => { 93 #[no_mangle] 94 pub unsafe extern "C" fn $name(tx: *mut std::os::raw::c_void) 95 -> *mut crate::applayer::AppLayerTxData 96 { 97 let tx = &mut *(tx as *mut $type); 98 &mut tx.tx_data 99 } 100 } 101 } 102 103 #[repr(C)] 104 #[derive(Debug,PartialEq,Copy,Clone)] 105 pub struct AppLayerResult { 106 pub status: i32, 107 pub consumed: u32, 108 pub needed: u32, 109 } 110 111 impl AppLayerResult { 112 /// parser has successfully processed in the input, and has consumed all of it ok() -> AppLayerResult113 pub fn ok() -> AppLayerResult { 114 return AppLayerResult { 115 status: 0, 116 consumed: 0, 117 needed: 0, 118 }; 119 } 120 /// parser has hit an unrecoverable error. Returning this to the API 121 /// leads to no further calls to the parser. err() -> AppLayerResult122 pub fn err() -> AppLayerResult { 123 return AppLayerResult { 124 status: -1, 125 consumed: 0, 126 needed: 0, 127 }; 128 } 129 /// parser needs more data. Through 'consumed' it will indicate how many 130 /// of the input bytes it has consumed. Through 'needed' it will indicate 131 /// how many more bytes it needs before getting called again. 132 /// Note: consumed should never be more than the input len 133 /// needed + consumed should be more than the input len incomplete(consumed: u32, needed: u32) -> AppLayerResult134 pub fn incomplete(consumed: u32, needed: u32) -> AppLayerResult { 135 return AppLayerResult { 136 status: 1, 137 consumed: consumed, 138 needed: needed, 139 }; 140 } 141 is_ok(self) -> bool142 pub fn is_ok(self) -> bool { 143 self.status == 0 144 } is_incomplete(self) -> bool145 pub fn is_incomplete(self) -> bool { 146 self.status == 1 147 } is_err(self) -> bool148 pub fn is_err(self) -> bool { 149 self.status == -1 150 } 151 } 152 153 impl From<bool> for AppLayerResult { from(v: bool) -> Self154 fn from(v: bool) -> Self { 155 if v == false { 156 Self::err() 157 } else { 158 Self::ok() 159 } 160 } 161 } 162 163 impl From<i32> for AppLayerResult { from(v: i32) -> Self164 fn from(v: i32) -> Self { 165 if v < 0 { 166 Self::err() 167 } else { 168 Self::ok() 169 } 170 } 171 } 172 173 /// Rust parser declaration 174 #[repr(C)] 175 pub struct RustParser { 176 /// Parser name. 177 pub name: *const c_char, 178 /// Default port 179 pub default_port: *const c_char, 180 181 /// IP Protocol (core::IPPROTO_UDP, core::IPPROTO_TCP, etc.) 182 pub ipproto: c_int, 183 184 /// Probing function, for packets going to server 185 pub probe_ts: Option<ProbeFn>, 186 /// Probing function, for packets going to client 187 pub probe_tc: Option<ProbeFn>, 188 189 /// Minimum frame depth for probing 190 pub min_depth: u16, 191 /// Maximum frame depth for probing 192 pub max_depth: u16, 193 194 /// Allocation function for a new state 195 pub state_new: StateAllocFn, 196 /// Function called to free a state 197 pub state_free: StateFreeFn, 198 199 /// Parsing function, for packets going to server 200 pub parse_ts: ParseFn, 201 /// Parsing function, for packets going to client 202 pub parse_tc: ParseFn, 203 204 /// Get the current transaction count 205 pub get_tx_count: StateGetTxCntFn, 206 /// Get a transaction 207 pub get_tx: StateGetTxFn, 208 /// Function called to free a transaction 209 pub tx_free: StateTxFreeFn, 210 /// Function returning the current transaction completion status 211 pub tx_get_comp_st: StateGetTxCompletionStatusFn, 212 /// Function returning the current transaction progress 213 pub tx_get_progress: StateGetProgressFn, 214 215 /// Function called to get a detection state 216 pub get_de_state: GetDetectStateFn, 217 /// Function called to set a detection state 218 pub set_de_state: SetDetectStateFn, 219 220 /// Function to get events 221 pub get_events: Option<GetEventsFn>, 222 /// Function to get an event id from a description 223 pub get_eventinfo: Option<GetEventInfoFn>, 224 /// Function to get an event description from an event id 225 pub get_eventinfo_byid: Option<GetEventInfoByIdFn>, 226 227 /// Function to allocate local storage 228 pub localstorage_new: Option<LocalStorageNewFn>, 229 /// Function to free local storage 230 pub localstorage_free: Option<LocalStorageFreeFn>, 231 232 /// Function to get files 233 pub get_files: Option<GetFilesFn>, 234 235 /// Function to get the TX iterator 236 pub get_tx_iterator: Option<GetTxIteratorFn>, 237 238 pub get_tx_data: GetTxDataFn, 239 240 // Function to apply config to a TX. Optional. Normal (bidirectional) 241 // transactions don't need to set this. It is meant for cases where 242 // the requests and responses are not sharing tx. It is then up to 243 // the implementation to make sure the config is applied correctly. 244 pub apply_tx_config: Option<ApplyTxConfigFn>, 245 246 pub flags: u32, 247 248 /// Function to handle the end of data coming on one of the sides 249 /// due to the stream reaching its 'depth' limit. 250 pub truncate: Option<TruncateFn>, 251 } 252 253 /// Create a slice, given a buffer and a length 254 /// 255 /// UNSAFE ! 256 #[macro_export] 257 macro_rules! build_slice { 258 ($buf:ident, $len:expr) => ( unsafe{ std::slice::from_raw_parts($buf, $len) } ); 259 } 260 261 /// Cast pointer to a variable, as a mutable reference to an object 262 /// 263 /// UNSAFE ! 264 #[macro_export] 265 macro_rules! cast_pointer { 266 ($ptr:ident, $ty:ty) => ( unsafe{ &mut *($ptr as *mut $ty) } ); 267 } 268 269 pub type ParseFn = extern "C" fn (flow: *const Flow, 270 state: *mut c_void, 271 pstate: *mut c_void, 272 input: *const u8, 273 input_len: u32, 274 data: *const c_void, 275 flags: u8) -> AppLayerResult; 276 pub type ProbeFn = extern "C" fn (flow: *const Flow, flags: u8, input:*const u8, input_len: u32, rdir: *mut u8) -> AppProto; 277 pub type StateAllocFn = extern "C" fn (*mut c_void, AppProto) -> *mut c_void; 278 pub type StateFreeFn = extern "C" fn (*mut c_void); 279 pub type StateTxFreeFn = extern "C" fn (*mut c_void, u64); 280 pub type StateGetTxFn = extern "C" fn (*mut c_void, u64) -> *mut c_void; 281 pub type StateGetTxCntFn = extern "C" fn (*mut c_void) -> u64; 282 pub type StateGetTxCompletionStatusFn = extern "C" fn (u8) -> c_int; 283 pub type StateGetProgressFn = extern "C" fn (*mut c_void, u8) -> c_int; 284 pub type GetDetectStateFn = extern "C" fn (*mut c_void) -> *mut DetectEngineState; 285 pub type SetDetectStateFn = extern "C" fn (*mut c_void, &mut DetectEngineState) -> c_int; 286 pub type GetEventInfoFn = extern "C" fn (*const c_char, *mut c_int, *mut AppLayerEventType) -> c_int; 287 pub type GetEventInfoByIdFn = extern "C" fn (c_int, *mut *const c_char, *mut AppLayerEventType) -> i8; 288 pub type GetEventsFn = extern "C" fn (*mut c_void) -> *mut AppLayerDecoderEvents; 289 pub type LocalStorageNewFn = extern "C" fn () -> *mut c_void; 290 pub type LocalStorageFreeFn = extern "C" fn (*mut c_void); 291 pub type GetFilesFn = extern "C" fn (*mut c_void, u8) -> *mut FileContainer; 292 pub type GetTxIteratorFn = extern "C" fn (ipproto: u8, alproto: AppProto, 293 state: *mut c_void, 294 min_tx_id: u64, 295 max_tx_id: u64, 296 istate: &mut u64) 297 -> AppLayerGetTxIterTuple; 298 pub type GetTxDataFn = unsafe extern "C" fn(*mut c_void) -> *mut AppLayerTxData; 299 pub type ApplyTxConfigFn = unsafe extern "C" fn (*mut c_void, *mut c_void, c_int, AppLayerTxConfig); 300 pub type TruncateFn = unsafe extern "C" fn (*mut c_void, u8); 301 302 303 // Defined in app-layer-register.h 304 extern { AppLayerRegisterProtocolDetection(parser: *const RustParser, enable_default: c_int) -> AppProto305 pub fn AppLayerRegisterProtocolDetection(parser: *const RustParser, enable_default: c_int) -> AppProto; AppLayerRegisterParser(parser: *const RustParser, alproto: AppProto) -> c_int306 pub fn AppLayerRegisterParser(parser: *const RustParser, alproto: AppProto) -> c_int; 307 } 308 309 // Defined in app-layer-detect-proto.h 310 extern { AppLayerProtoDetectConfProtoDetectionEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int311 pub fn AppLayerProtoDetectConfProtoDetectionEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int; 312 } 313 314 // Defined in app-layer-parser.h 315 pub const APP_LAYER_PARSER_EOF_TS : u8 = BIT_U8!(5); 316 pub const APP_LAYER_PARSER_EOF_TC : u8 = BIT_U8!(6); 317 pub const APP_LAYER_PARSER_NO_INSPECTION : u8 = BIT_U8!(1); 318 pub const APP_LAYER_PARSER_NO_REASSEMBLY : u8 = BIT_U8!(2); 319 pub const APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD : u8 = BIT_U8!(3); 320 pub const APP_LAYER_PARSER_BYPASS_READY : u8 = BIT_U8!(4); 321 322 pub const APP_LAYER_PARSER_OPT_ACCEPT_GAPS: u32 = BIT_U32!(0); 323 pub const APP_LAYER_PARSER_OPT_UNIDIR_TXS: u32 = BIT_U32!(1); 324 325 pub type AppLayerGetTxIteratorFn = extern "C" fn (ipproto: u8, 326 alproto: AppProto, 327 alstate: *mut c_void, 328 min_tx_id: u64, 329 max_tx_id: u64, 330 istate: &mut u64) -> applayer::AppLayerGetTxIterTuple; 331 332 extern { AppLayerParserStateSetFlag(state: *mut c_void, flag: u8)333 pub fn AppLayerParserStateSetFlag(state: *mut c_void, flag: u8); AppLayerParserStateIssetFlag(state: *mut c_void, flag: u8) -> c_int334 pub fn AppLayerParserStateIssetFlag(state: *mut c_void, flag: u8) -> c_int; AppLayerParserConfParserEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int335 pub fn AppLayerParserConfParserEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int; AppLayerParserRegisterGetTxIterator(ipproto: u8, alproto: AppProto, fun: AppLayerGetTxIteratorFn)336 pub fn AppLayerParserRegisterGetTxIterator(ipproto: u8, alproto: AppProto, fun: AppLayerGetTxIteratorFn); AppLayerParserRegisterOptionFlags(ipproto: u8, alproto: AppProto, flags: u32)337 pub fn AppLayerParserRegisterOptionFlags(ipproto: u8, alproto: AppProto, flags: u32); 338 } 339 340 #[repr(C)] 341 pub struct AppLayerGetTxIterTuple { 342 tx_ptr: *mut std::os::raw::c_void, 343 tx_id: u64, 344 has_next: bool, 345 } 346 347 impl AppLayerGetTxIterTuple { with_values(tx_ptr: *mut std::os::raw::c_void, tx_id: u64, has_next: bool) -> AppLayerGetTxIterTuple348 pub fn with_values(tx_ptr: *mut std::os::raw::c_void, tx_id: u64, has_next: bool) -> AppLayerGetTxIterTuple { 349 AppLayerGetTxIterTuple { 350 tx_ptr: tx_ptr, tx_id: tx_id, has_next: has_next, 351 } 352 } not_found() -> AppLayerGetTxIterTuple353 pub fn not_found() -> AppLayerGetTxIterTuple { 354 AppLayerGetTxIterTuple { 355 tx_ptr: std::ptr::null_mut(), tx_id: 0, has_next: false, 356 } 357 } 358 } 359 360 /// LoggerFlags tracks which loggers have already been executed. 361 #[repr(C)] 362 #[derive(Debug,PartialEq)] 363 pub struct LoggerFlags { 364 flags: u32, 365 } 366 367 impl LoggerFlags { 368 new() -> LoggerFlags369 pub fn new() -> LoggerFlags { 370 return LoggerFlags{ 371 flags: 0, 372 } 373 } 374 get(&self) -> u32375 pub fn get(&self) -> u32 { 376 self.flags 377 } 378 set(&mut self, bits: u32)379 pub fn set(&mut self, bits: u32) { 380 self.flags = bits; 381 } 382 383 } 384 385 /// Export a function to get the DetectEngineState on a struct. 386 #[macro_export] 387 macro_rules!export_tx_get_detect_state { 388 ($name:ident, $type:ty) => ( 389 #[no_mangle] 390 pub extern "C" fn $name(tx: *mut std::os::raw::c_void) 391 -> *mut core::DetectEngineState 392 { 393 let tx = cast_pointer!(tx, $type); 394 match tx.de_state { 395 Some(ds) => { 396 return ds; 397 }, 398 None => { 399 return std::ptr::null_mut(); 400 } 401 } 402 } 403 ) 404 } 405 406 /// Export a function to set the DetectEngineState on a struct. 407 #[macro_export] 408 macro_rules!export_tx_set_detect_state { 409 ($name:ident, $type:ty) => ( 410 #[no_mangle] 411 pub extern "C" fn $name(tx: *mut std::os::raw::c_void, 412 de_state: &mut core::DetectEngineState) -> std::os::raw::c_int 413 { 414 let tx = cast_pointer!(tx, $type); 415 tx.de_state = Some(de_state); 416 0 417 } 418 ) 419 } 420