11use std:: ptr:: null_mut;
22
33use suricata_ffi:: eve:: { self , SCJsonBuilder } ;
4- use suricata_ffi:: flow:: { self , Flow } ;
4+ use suricata_ffi:: flow:: { self , Flow , FlowStorage } ;
55use suricata_ffi:: jsonbuilder:: JsonBuilder ;
66use suricata_ffi:: thread:: { self , ThreadStorage , ThreadVars } ;
77use suricata_ffi:: { SCLogError , SCLogNotice , SCLogWarning } ;
@@ -13,6 +13,12 @@ struct ThreadState {
1313 flows : u64 ,
1414}
1515
16+ /// Per-flow state stored in Suricata flow storage.
17+ #[ derive( Default ) ]
18+ struct FlowState {
19+ packets : u64 ,
20+ }
21+
1622unsafe extern "C" fn init ( ) {
1723 suricata_ffi:: plugin:: init ( ) ;
1824 SCLogNotice ! ( "Initializing rust example plugin" ) ;
@@ -26,11 +32,18 @@ unsafe extern "C" fn init() {
2632 return ;
2733 }
2834 } ;
35+ let flow_storage = match FlowStorage :: < FlowState > :: register ( "rust-example-flow" ) {
36+ Ok ( storage) => storage,
37+ Err ( err) => {
38+ SCLogError ! ( "Failed to register rust example flow storage: {}" , err) ;
39+ return ;
40+ }
41+ } ;
2942
3043 if let Err ( err) = register_eve_callbacks ( ) {
3144 SCLogError ! ( "Failed to register rust example EVE callbacks: {}" , err) ;
3245 }
33- if let Err ( err) = register_flow_callbacks ( thread_storage) {
46+ if let Err ( err) = register_flow_callbacks ( thread_storage, flow_storage ) {
3447 SCLogError ! ( "Failed to register rust example flow callbacks: {}" , err) ;
3548 }
3649 if let Err ( err) = register_thread_callbacks ( thread_storage) {
@@ -45,10 +58,15 @@ fn register_eve_callbacks() -> Result<(), &'static str> {
4558 eve:: register_callback ( log_eve_wrapped)
4659}
4760
48- fn register_flow_callbacks ( storage : ThreadStorage < ThreadState > ) -> Result < ( ) , & ' static str > {
49- flow:: register_init_callback ( move |tv, f, p| log_flow_init ( storage, tv, f, p) ) ?;
50- flow:: register_update_callback ( log_flow_update) ?;
51- flow:: register_finish_callback ( log_flow_finish) ?;
61+ fn register_flow_callbacks (
62+ thread_storage : ThreadStorage < ThreadState > ,
63+ flow_storage : FlowStorage < FlowState > ,
64+ ) -> Result < ( ) , & ' static str > {
65+ flow:: register_init_callback ( move |tv, f, p| {
66+ log_flow_init ( thread_storage, flow_storage, tv, f, p)
67+ } ) ?;
68+ flow:: register_update_callback ( move |tv, f, p| log_flow_update ( flow_storage, tv, f, p) ) ?;
69+ flow:: register_finish_callback ( move |tv, f| log_flow_finish ( flow_storage, tv, f) ) ?;
5270 Ok ( ( ) )
5371}
5472
@@ -94,13 +112,14 @@ fn on_thread_init(storage: ThreadStorage<ThreadState>, tv: &mut ThreadVars) {
94112}
95113
96114fn log_flow_init (
97- storage : ThreadStorage < ThreadState > ,
115+ thread_storage : ThreadStorage < ThreadState > ,
116+ flow_storage : FlowStorage < FlowState > ,
98117 tv : & mut ThreadVars ,
99118 f : & mut Flow ,
100119 _p : * const Packet ,
101120) {
102121 // Count flows seen by this thread using the per-thread storage.
103- let flows = match storage . get_mut ( tv) {
122+ let flows = match thread_storage . get_mut ( tv) {
104123 Some ( state) => {
105124 state. flows += 1 ;
106125 state. flows
@@ -110,23 +129,48 @@ fn log_flow_init(
110129 0
111130 }
112131 } ;
132+ // Initialize the per-flow storage for this flow.
133+ if let Err ( err) = flow_storage. get_or_insert_with ( f, FlowState :: default) {
134+ SCLogError ! ( "failed to initialize rust example flow storage: {}" , err) ;
135+ }
113136 SCLogNotice ! (
114137 "rust example flow init callback: flow={:p}, thread_flows={}" ,
115138 f. as_ptr( ) ,
116139 flows
117140 ) ;
118141}
119142
120- fn log_flow_update ( _tv : & mut ThreadVars , f : & mut Flow , _p : * mut Packet ) {
143+ fn log_flow_update (
144+ flow_storage : FlowStorage < FlowState > ,
145+ _tv : & mut ThreadVars ,
146+ f : & mut Flow ,
147+ _p : * mut Packet ,
148+ ) {
149+ // Count packets seen on this flow using the per-flow storage.
150+ let packets = match flow_storage. get_mut ( f) {
151+ Some ( state) => {
152+ state. packets += 1 ;
153+ state. packets
154+ }
155+ None => {
156+ SCLogWarning ! ( "rust example flow storage was not initialized" ) ;
157+ 0
158+ }
159+ } ;
121160 SCLogNotice ! (
122- "rust example flow update callback: flow={:p}, packet={:p }" ,
161+ "rust example flow update callback: flow={:p}, flow_packets={ }" ,
123162 f. as_ptr( ) ,
124- _p
163+ packets
125164 ) ;
126165}
127166
128- fn log_flow_finish ( _tv : & mut ThreadVars , f : & mut Flow ) {
129- SCLogNotice ! ( "rust example flow finish callback: flow={:p}" , f. as_ptr( ) ) ;
167+ fn log_flow_finish ( flow_storage : FlowStorage < FlowState > , _tv : & mut ThreadVars , f : & mut Flow ) {
168+ let packets = flow_storage. get ( f) . map ( |state| state. packets ) . unwrap_or ( 0 ) ;
169+ SCLogNotice ! (
170+ "rust example flow finish callback: flow={:p}, flow_packets={}" ,
171+ f. as_ptr( ) ,
172+ packets
173+ ) ;
130174}
131175
132176#[ no_mangle]
0 commit comments