From 3da816eb23001343703b3ea8606f634286ca8242 Mon Sep 17 00:00:00 2001 From: Pierre Chifflier Date: Fri, 12 Nov 2021 14:32:09 +0100 Subject: [PATCH] rust/smb: convert parser to nom7 functions (NBSS records) --- rust/src/smb/nbss_records.rs | 74 +++++++++++++++++++----------------- rust/src/smb/smb.rs | 15 +++++--- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/rust/src/smb/nbss_records.rs b/rust/src/smb/nbss_records.rs index 7256c8a91d..e63862cdcb 100644 --- a/rust/src/smb/nbss_records.rs +++ b/rust/src/smb/nbss_records.rs @@ -15,7 +15,10 @@ * 02110-1301, USA. */ -use nom::combinator::rest; +use nom7::bytes::streaming::take; +use nom7::combinator::rest; +use nom7::number::streaming::be_u32; +use nom7::IResult; pub const NBSS_MSGTYPE_SESSION_MESSAGE: u8 = 0x00; pub const NBSS_MSGTYPE_SESSION_REQUEST: u8 = 0x81; @@ -62,36 +65,37 @@ impl<'a> NbssRecord<'a> { } } -named!(pub parse_nbss_record, - do_parse!( - type_and_len: bits!(tuple!( - take_bits!(8u8), - take_bits!(24u32))) - >> data: take!(type_and_len.1 as usize) - >> (NbssRecord { - message_type:type_and_len.0, - length:type_and_len.1, - data:data, - }) -)); - -named!(pub parse_nbss_record_partial, - do_parse!( - type_and_len: bits!(tuple!( - take_bits!(8u8), - take_bits!(24u32))) - >> data: rest - >> (NbssRecord { - message_type:type_and_len.0, - length:type_and_len.1, - data:data, - }) -)); +pub fn parse_nbss_record(i: &[u8]) -> IResult<&[u8], NbssRecord> { + let (i, buf) = be_u32(i)?; + let message_type = (buf >> 24) as u8; + let length = buf & 0xff_ffff; + let (i, data) = take(length as usize)(i)?; + let record = NbssRecord { + message_type, + length, + data, + }; + Ok((i, record)) +} + +pub fn parse_nbss_record_partial(i: &[u8]) -> IResult<&[u8], NbssRecord> { + let (i, buf) = be_u32(i)?; + let message_type = (buf >> 24) as u8; + let length = buf & 0xff_ffff; + let (i, data) = rest(i)?; + let record = NbssRecord { + message_type, + length, + data, + }; + Ok((i, record)) +} #[cfg(test)] mod tests { use super::*; + use nom7::Err; #[test] fn test_parse_nbss_record() { @@ -126,10 +130,10 @@ mod tests { // there should be nothing left assert_eq!(remainder.len(), 0); } - Err(nom::Err::Error((_remainder, err))) => { - panic!("Result should not be an error: {:?}.", err); + Err(Err::Error(err)) => { + panic!("Result should not be an error: {:?}.", err.code); } - Err(nom::Err::Incomplete(_)) => { + Err(Err::Incomplete(_)) => { panic!("Result should not have been incomplete."); } _ => { @@ -170,10 +174,10 @@ mod tests { // there should be nothing left assert_eq!(remainder.len(), 0); } - Err(nom::Err::Error((_remainder, err))) => { - panic!("Result should not be an error: {:?}.", err); + Err(Err::Error(err)) => { + panic!("Result should not be an error: {:?}.", err.code); } - Err(nom::Err::Incomplete(_)) => { + Err(Err::Incomplete(_)) => { panic!("Result should not have been incomplete."); } _ => { @@ -210,10 +214,10 @@ mod tests { // there should be nothing left assert_eq!(remainder.len(), 0); } - Err(nom::Err::Error((_remainder, err))) => { - panic!("Result should not be an error: {:?}.", err); + Err(Err::Error(err)) => { + panic!("Result should not be an error: {:?}.", err.code); } - Err(nom::Err::Incomplete(_)) => { + Err(Err::Incomplete(_)) => { panic!("Result should not have returned as incomplete."); } _ => { diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 2fedf97e2b..393c7868ed 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -32,6 +32,7 @@ use std::ffi::{self, CString}; use std::collections::HashMap; use nom; +use nom7::{Err, Needed}; use crate::core::*; use crate::applayer; @@ -1420,8 +1421,9 @@ impl SMBState { } cur_i = rem; }, - Err(nom::Err::Incomplete(needed)) => { - if let nom::Needed::Size(n) = needed { + Err(Err::Incomplete(needed)) => { + if let Needed::Size(n) = needed { + let n = usize::from(n) + cur_i.len(); // 512 is the minimum for parse_tcp_data_ts_partial if n >= 512 && cur_i.len() < 512 { let total_consumed = i.len() - cur_i.len(); @@ -1433,7 +1435,7 @@ impl SMBState { let total_consumed = i.len() - cur_i.len(); SCLogDebug!("setting consumed {} need {} needed {:?} total input {}", total_consumed, n, needed, i.len()); - let need = n + 4; // Incomplete returns size of data minus NBSS header + let need = n; return AppLayerResult::incomplete(total_consumed as u32, need as u32); } // tracking a write record, which we don't need to @@ -1661,9 +1663,10 @@ impl SMBState { } cur_i = rem; }, - Err(nom::Err::Incomplete(needed)) => { + Err(Err::Incomplete(needed)) => { SCLogDebug!("INCOMPLETE have {} needed {:?}", cur_i.len(), needed); - if let nom::Needed::Size(n) = needed { + if let Needed::Size(n) = needed { + let n = usize::from(n) + cur_i.len(); // 512 is the minimum for parse_tcp_data_tc_partial if n >= 512 && cur_i.len() < 512 { let total_consumed = i.len() - cur_i.len(); @@ -1675,7 +1678,7 @@ impl SMBState { let total_consumed = i.len() - cur_i.len(); SCLogDebug!("setting consumed {} need {} needed {:?} total input {}", total_consumed, n, needed, i.len()); - let need = n + 4; // Incomplete returns size of data minus NBSS header + let need = n; return AppLayerResult::incomplete(total_consumed as u32, need as u32); } // tracking a read record, which we don't need to