@@ -20,11 +20,15 @@ use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
2020use crate :: detect:: uint:: {
2121 detect_parse_uint_enum, DetectUintData , SCDetectU8Free , SCDetectU8Match , SCDetectU8Parse ,
2222} ;
23- use crate :: detect:: { SIGMATCH_INFO_ENUM_UINT , SIGMATCH_INFO_UINT8 } ;
23+ use crate :: detect:: {
24+ helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer , SIGMATCH_INFO_ENUM_UINT ,
25+ SIGMATCH_INFO_UINT8 ,
26+ } ;
2427use std:: ffi:: CStr ;
2528use std:: os:: raw:: { c_int, c_void} ;
2629use suricata_sys:: sys:: {
27- DetectEngineCtx , DetectEngineThreadCtx , Flow , SCDetectHelperBufferProgressRegister ,
30+ DetectEngineCtx , DetectEngineThreadCtx , Flow , SCDetectBufferSetActiveList ,
31+ SCDetectHelperBufferProgressMpmRegister , SCDetectHelperBufferProgressRegister ,
2832 SCDetectHelperKeywordRegister , SCDetectSignatureSetAppProto , SCSigMatchAppendSMToList ,
2933 SCSigTableAppLiteElmt , SigMatchCtx , Signature ,
3034} ;
@@ -35,6 +39,7 @@ static mut G_NTP_MODE_KW_ID: u16 = 0;
3539static mut G_NTP_MODE_BUFFER_ID : c_int = 0 ;
3640static mut G_NTP_STRATUM_KW_ID : u16 = 0 ;
3741static mut G_NTP_STRATUM_BUFFER_ID : c_int = 0 ;
42+ static mut G_NTP_REFERENCE_ID_BUFFER_ID : c_int = 0 ;
3843
3944#[ derive( Clone , Debug , PartialEq , EnumStringU8 ) ]
4045#[ repr( u8 ) ]
@@ -167,6 +172,27 @@ unsafe extern "C" fn ntp_detect_stratum_match(
167172 return SCDetectU8Match ( tx. stratum , ctx) ;
168173}
169174
175+ unsafe extern "C" fn ntp_detect_reference_id_setup (
176+ de : * mut DetectEngineCtx , s : * mut Signature , _raw : * const std:: os:: raw:: c_char ,
177+ ) -> c_int {
178+ if SCDetectSignatureSetAppProto ( s, ALPROTO_NTP ) != 0 {
179+ return -1 ;
180+ }
181+ if SCDetectBufferSetActiveList ( de, s, G_NTP_REFERENCE_ID_BUFFER_ID ) < 0 {
182+ return -1 ;
183+ }
184+ return 0 ;
185+ }
186+
187+ unsafe extern "C" fn ntp_detect_reference_id_get_data (
188+ tx : * const c_void , _flow_flags : u8 , buffer : * mut * const u8 , buffer_len : * mut u32 ,
189+ ) -> bool {
190+ let tx = cast_pointer ! ( tx, NTPTransaction ) ;
191+ * buffer = tx. reference_id . as_ptr ( ) ;
192+ * buffer_len = tx. reference_id . len ( ) as u32 ;
193+ true
194+ }
195+
170196pub ( super ) unsafe extern "C" fn detect_ntp_register ( ) {
171197 let kw = SCSigTableAppLiteElmt {
172198 name : b"ntp.version\0 " . as_ptr ( ) as * const libc:: c_char ,
@@ -218,12 +244,29 @@ pub(super) unsafe extern "C" fn detect_ntp_register() {
218244 STREAM_TOSERVER | STREAM_TOCLIENT ,
219245 1 ,
220246 ) ;
247+
248+ let kw = SigTableElmtStickyBuffer {
249+ name : String :: from ( "ntp.reference_id" ) ,
250+ desc : String :: from ( "sticky buffer to match on the NTP reference ID" ) ,
251+ url : String :: from ( "/rules/ntp-keywords.html#ntp-reference-id" ) ,
252+ setup : ntp_detect_reference_id_setup,
253+ } ;
254+ let _g_ntp_reference_id_kw_id = helper_keyword_register_sticky_buffer ( & kw) ;
255+ G_NTP_REFERENCE_ID_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister (
256+ b"ntp.reference_id\0 " . as_ptr ( ) as * const libc:: c_char ,
257+ b"NTP reference ID\0 " . as_ptr ( ) as * const libc:: c_char ,
258+ ALPROTO_NTP ,
259+ STREAM_TOSERVER | STREAM_TOCLIENT ,
260+ Some ( ntp_detect_reference_id_get_data) ,
261+ 1 ,
262+ ) ;
221263}
222264
223265#[ cfg( test) ]
224266mod test {
225267 use super :: * ;
226268 use crate :: detect:: uint:: DetectUintMode ;
269+ use crate :: direction:: Direction ;
227270
228271 #[ test]
229272 fn test_ntp_parse_known_mode_strings ( ) {
@@ -273,4 +316,10 @@ mod test {
273316 assert ! ( detect_parse_uint_enum:: <u8 , NTPMode >( "symmetric_private" ) . is_none( ) ) ;
274317 assert ! ( detect_parse_uint_enum:: <u8 , NTPMode >( "256" ) . is_none( ) ) ;
275318 }
319+
320+ #[ test]
321+ fn test_ntp_reference_id_is_network_order_bytes ( ) {
322+ let tx = NTPTransaction :: new ( Direction :: ToServer , 1 , 0x5241_5445 ) ;
323+ assert_eq ! ( & tx. reference_id, b"RATE" ) ;
324+ }
276325}
0 commit comments