rust/smb: convert parser to nom7 functions (NBSS records)

pull/6705/head
Pierre Chifflier 4 years ago committed by Victor Julien
parent 90f9450971
commit 3da816eb23

@ -15,7 +15,10 @@
* 02110-1301, USA. * 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_MESSAGE: u8 = 0x00;
pub const NBSS_MSGTYPE_SESSION_REQUEST: u8 = 0x81; pub const NBSS_MSGTYPE_SESSION_REQUEST: u8 = 0x81;
@ -62,36 +65,37 @@ impl<'a> NbssRecord<'a> {
} }
} }
named!(pub parse_nbss_record<NbssRecord>, pub fn parse_nbss_record(i: &[u8]) -> IResult<&[u8], NbssRecord> {
do_parse!( let (i, buf) = be_u32(i)?;
type_and_len: bits!(tuple!( let message_type = (buf >> 24) as u8;
take_bits!(8u8), let length = buf & 0xff_ffff;
take_bits!(24u32))) let (i, data) = take(length as usize)(i)?;
>> data: take!(type_and_len.1 as usize) let record = NbssRecord {
>> (NbssRecord { message_type,
message_type:type_and_len.0, length,
length:type_and_len.1, data,
data:data, };
}) Ok((i, record))
)); }
named!(pub parse_nbss_record_partial<NbssRecord>, pub fn parse_nbss_record_partial(i: &[u8]) -> IResult<&[u8], NbssRecord> {
do_parse!( let (i, buf) = be_u32(i)?;
type_and_len: bits!(tuple!( let message_type = (buf >> 24) as u8;
take_bits!(8u8), let length = buf & 0xff_ffff;
take_bits!(24u32))) let (i, data) = rest(i)?;
>> data: rest let record = NbssRecord {
>> (NbssRecord { message_type,
message_type:type_and_len.0, length,
length:type_and_len.1, data,
data:data, };
}) Ok((i, record))
)); }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nom7::Err;
#[test] #[test]
fn test_parse_nbss_record() { fn test_parse_nbss_record() {
@ -126,10 +130,10 @@ mod tests {
// there should be nothing left // there should be nothing left
assert_eq!(remainder.len(), 0); assert_eq!(remainder.len(), 0);
} }
Err(nom::Err::Error((_remainder, err))) => { Err(Err::Error(err)) => {
panic!("Result should not be an 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."); panic!("Result should not have been incomplete.");
} }
_ => { _ => {
@ -170,10 +174,10 @@ mod tests {
// there should be nothing left // there should be nothing left
assert_eq!(remainder.len(), 0); assert_eq!(remainder.len(), 0);
} }
Err(nom::Err::Error((_remainder, err))) => { Err(Err::Error(err)) => {
panic!("Result should not be an 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."); panic!("Result should not have been incomplete.");
} }
_ => { _ => {
@ -210,10 +214,10 @@ mod tests {
// there should be nothing left // there should be nothing left
assert_eq!(remainder.len(), 0); assert_eq!(remainder.len(), 0);
} }
Err(nom::Err::Error((_remainder, err))) => { Err(Err::Error(err)) => {
panic!("Result should not be an 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."); panic!("Result should not have returned as incomplete.");
} }
_ => { _ => {

@ -32,6 +32,7 @@ use std::ffi::{self, CString};
use std::collections::HashMap; use std::collections::HashMap;
use nom; use nom;
use nom7::{Err, Needed};
use crate::core::*; use crate::core::*;
use crate::applayer; use crate::applayer;
@ -1420,8 +1421,9 @@ impl SMBState {
} }
cur_i = rem; cur_i = rem;
}, },
Err(nom::Err::Incomplete(needed)) => { Err(Err::Incomplete(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_ts_partial // 512 is the minimum for parse_tcp_data_ts_partial
if n >= 512 && cur_i.len() < 512 { if n >= 512 && cur_i.len() < 512 {
let total_consumed = i.len() - cur_i.len(); let total_consumed = i.len() - cur_i.len();
@ -1433,7 +1435,7 @@ impl SMBState {
let total_consumed = i.len() - cur_i.len(); let total_consumed = i.len() - cur_i.len();
SCLogDebug!("setting consumed {} need {} needed {:?} total input {}", SCLogDebug!("setting consumed {} need {} needed {:?} total input {}",
total_consumed, n, needed, i.len()); 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); return AppLayerResult::incomplete(total_consumed as u32, need as u32);
} }
// tracking a write record, which we don't need to // tracking a write record, which we don't need to
@ -1661,9 +1663,10 @@ impl SMBState {
} }
cur_i = rem; cur_i = rem;
}, },
Err(nom::Err::Incomplete(needed)) => { Err(Err::Incomplete(needed)) => {
SCLogDebug!("INCOMPLETE have {} needed {:?}", cur_i.len(), 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 // 512 is the minimum for parse_tcp_data_tc_partial
if n >= 512 && cur_i.len() < 512 { if n >= 512 && cur_i.len() < 512 {
let total_consumed = i.len() - cur_i.len(); let total_consumed = i.len() - cur_i.len();
@ -1675,7 +1678,7 @@ impl SMBState {
let total_consumed = i.len() - cur_i.len(); let total_consumed = i.len() - cur_i.len();
SCLogDebug!("setting consumed {} need {} needed {:?} total input {}", SCLogDebug!("setting consumed {} need {} needed {:?} total input {}",
total_consumed, n, needed, i.len()); 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); return AppLayerResult::incomplete(total_consumed as u32, need as u32);
} }
// tracking a read record, which we don't need to // tracking a read record, which we don't need to

Loading…
Cancel
Save