From: Pierre Chifflier Date: Thu, 31 Oct 2019 14:33:57 +0000 (+0100) Subject: rust: Add types annotation when required X-Git-Tag: suricata-6.0.0-beta1~700 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3ddd7127caed711f963a25ef8af1519a74169d6;p=thirdparty%2Fsuricata.git rust: Add types annotation when required Unfortunately, the transition to nom 5 (and functions instead of macros) has side-effects, one of them being requiring lots of types annotations when using a parsing, for ex in a match instruction. --- diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index ddb5119902..ead5a6bcba 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -25,6 +25,7 @@ use crate::applayer::LoggerFlags; use crate::core; use crate::dns::parser; +use nom::IResult; use nom::number::complete::be_u16; /// DNS record types. @@ -445,8 +446,8 @@ impl DNSState { let mut count = 0; while self.request_buffer.len() > 0 { - let size = match be_u16(&self.request_buffer) { - Ok((_, len)) => len, + let size = match be_u16(&self.request_buffer) as IResult<&[u8],_> { + Ok((_, len)) => i32::from(len), _ => 0 } as usize; SCLogDebug!("Have {} bytes, need {} to parse", @@ -486,8 +487,8 @@ impl DNSState { let mut count = 0; while self.response_buffer.len() > 0 { - let size = match be_u16(&self.response_buffer) { - Ok((_, len)) => len, + let size = match be_u16(&self.response_buffer) as IResult<&[u8],_> { + Ok((_, len)) => i32::from(len), _ => 0 } as usize; if size > 0 && self.response_buffer.len() >= size + 2 { @@ -535,7 +536,7 @@ fn probe(input: &[u8]) -> (bool, bool) { /// Probe TCP input to see if it looks like DNS. pub fn probe_tcp(input: &[u8]) -> (bool, bool) { - match be_u16(input) { + match be_u16(input) as IResult<&[u8],_> { Ok((rem, _)) => { return probe(rem); }, diff --git a/rust/src/dns/parser.rs b/rust/src/dns/parser.rs index 3dc1f6a485..fd4d3cba68 100644 --- a/rust/src/dns/parser.rs +++ b/rust/src/dns/parser.rs @@ -19,6 +19,7 @@ use nom::IResult; use nom::error::ErrorKind; +use nom::multi::length_data; use nom::number::complete::{be_u8, be_u16, be_u32}; use nom; use crate::dns::dns::*; @@ -69,7 +70,7 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8], pos = &pos[1..]; break; } else if len & 0b1100_0000 == 0 { - match length_data!(pos, be_u8) { + match length_data(be_u8)(pos) as IResult<&[u8],_> { Ok((rem, label)) => { if name.len() > 0 { name.push('.' as u8); @@ -83,14 +84,14 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8], } } } else if len & 0b1100_0000 == 0b1100_0000 { - match be_u16(pos) { + match be_u16(pos) as IResult<&[u8],_> { Ok((rem, leader)) => { - let offset = leader & 0x3fff; - if offset as usize > message.len() { + let offset = usize::from(leader) & 0x3fff; + if offset > message.len() { return Err(nom::Err::Error( error_position!(pos, ErrorKind::OctDigit))); } - pos = &message[offset as usize..]; + pos = &message[offset..]; if pivot == start { pivot = rem; } diff --git a/rust/src/ftp/mod.rs b/rust/src/ftp/mod.rs index b8352f02e0..76b4910e1c 100644 --- a/rust/src/ftp/mod.rs +++ b/rust/src/ftp/mod.rs @@ -31,7 +31,7 @@ use crate::log::*; named!(getu16, map_res!( map_res!( - sep!(digit1, multispace0), + delimited!(multispace0, digit1, multispace0), str::from_utf8 ), FromStr::from_str @@ -46,7 +46,7 @@ named!(parse_u16, named!(pub ftp_active_port, do_parse!( tag!("PORT") >> - sep!(digit1, multispace0) >> tag!(",") >> digit1 >> tag!(",") >> + delimited!(multispace0, digit1, multispace0) >> tag!(",") >> digit1 >> tag!(",") >> digit1 >> tag!(",") >> digit1 >> tag!(",") >> part1: verify!(parse_u16, |&v| v <= std::u8::MAX as u16) >> tag!(",") >> diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 61004681ca..91f0aa57ec 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -20,6 +20,7 @@ use std; use std::ffi::{CStr,CString}; use nom; +use nom::IResult; use nom::number::complete::be_u32; use der_parser::der::der_read_element_header; use kerberos_parser::krb5_parser; @@ -477,7 +478,7 @@ pub extern "C" fn rs_krb5_probing_parser_tcp(_flow: *const Flow, { let slice = build_slice!(input,input_len as usize); if slice.len() <= 14 { return unsafe{ALPROTO_FAILED}; } - match be_u32(slice) { + match be_u32(slice) as IResult<&[u8],u32> { Ok((rem, record_mark)) => { // protocol implementations forbid very large requests if record_mark > 16384 { return unsafe{ALPROTO_FAILED}; } @@ -550,7 +551,7 @@ pub extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow, let mut cur_i = tcp_buffer; while cur_i.len() > 0 { if state.record_ts == 0 { - match be_u32(cur_i) { + match be_u32(cur_i) as IResult<&[u8],u32> { Ok((rem,record)) => { state.record_ts = record as usize; cur_i = rem; @@ -608,7 +609,7 @@ pub extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow, let mut cur_i = tcp_buffer; while cur_i.len() > 0 { if state.record_tc == 0 { - match be_u32(cur_i) { + match be_u32(cur_i) as IResult<&[u8],_> { Ok((rem,record)) => { state.record_tc = record as usize; cur_i = rem; diff --git a/rust/src/nfs/nfs2.rs b/rust/src/nfs/nfs2.rs index 4db30f1b44..c13155862f 100644 --- a/rust/src/nfs/nfs2.rs +++ b/rust/src/nfs/nfs2.rs @@ -24,6 +24,7 @@ use crate::nfs::types::*; use crate::nfs::rpc_records::*; use crate::nfs::nfs2_records::*; +use nom::IResult; use nom::number::complete::be_u32; impl NFSState { @@ -109,7 +110,7 @@ impl NFSState { }, } } else { - let stat = match be_u32(&r.prog_data) { + let stat = match be_u32(&r.prog_data) as IResult<&[u8],_> { Ok((_, stat)) => { stat as u32 } diff --git a/rust/src/nfs/nfs3.rs b/rust/src/nfs/nfs3.rs index 7b83c6c724..3abb675715 100644 --- a/rust/src/nfs/nfs3.rs +++ b/rust/src/nfs/nfs3.rs @@ -25,6 +25,7 @@ use crate::nfs::types::*; use crate::nfs::rpc_records::*; use crate::nfs::nfs3_records::*; +use nom::IResult; use nom::number::complete::be_u32; impl NFSState { @@ -327,7 +328,7 @@ impl NFSState { } // for all other record types only parse the status else { - let stat = match be_u32(&r.prog_data) { + let stat = match be_u32(&r.prog_data) as IResult<&[u8],_> { Ok((_, stat)) => { stat as u32 } diff --git a/rust/src/nfs/rpc_records.rs b/rust/src/nfs/rpc_records.rs index 053756f622..d9c779adb8 100644 --- a/rust/src/nfs/rpc_records.rs +++ b/rust/src/nfs/rpc_records.rs @@ -17,6 +17,7 @@ //! Nom parsers for RPCv2 +use nom::IResult; use nom::combinator::rest; use nom::number::complete::be_u32; @@ -120,12 +121,16 @@ pub struct RpcPacketHeader<> { pub msgtype: u32, } +fn parse_bits(i:&[u8]) -> IResult<&[u8],(u8,u32)> { + bits!(i, + tuple!( + take_bits!(1u8), // is_last + take_bits!(31u32))) // len +} + named!(pub parse_rpc_packet_header, do_parse!( - fraghdr: bits!(tuple!( - take_bits!(1u8), // is_last - take_bits!(31u32))) // len - + fraghdr: parse_bits >> xid: be_u32 >> msgtype: be_u32 >> ( diff --git a/rust/src/rdp/parser.rs b/rust/src/rdp/parser.rs index f0d598233c..8967996cc8 100644 --- a/rust/src/rdp/parser.rs +++ b/rust/src/rdp/parser.rs @@ -27,7 +27,8 @@ //! * x.691-spec: use nom::IResult; -use nom::error::{make_error, ErrorKind}; +use nom::bytes::complete::take; +use nom::combinator::{opt, map_opt, map_res}; use nom::number::complete::{be_u16, be_u8, le_u16, le_u32, le_u8}; use crate::rdp::error::RdpError; use crate::rdp::util::{ @@ -480,19 +481,19 @@ pub fn parse_t123_tpkt(input: &[u8]) -> IResult<&[u8], T123Tpkt, RdpError> { return Ok((i4, T123Tpkt { child })); } +fn take_4_4_bits(input: &[u8]) -> IResult<&[u8], (u8,u8), RdpError> { + map!(input, be_u8, |b| (b >> 4, b & 0xf)) +} + /// rdp-spec, section 2.2.1.1 fn parse_x224_connection_request( input: &[u8], ) -> IResult<&[u8], X224ConnectionRequest, RdpError> { let (i1, length) = verify!(input, be_u8, |&x| x != 0xff)?; // 0xff is reserved - let (i2, cr_cdt) = bits!( - i1, - tuple!( - verify!(take_bits!(4u8), |&x| x - == X224Type::ConnectionRequest as u8), - verify!(take_bits!(4u8), |&x| x == 0 || x == 1) - ) - )?; + let (i2, cr_cdt) = take_4_4_bits(input)?; + let _ = verify!(i1, value!(cr_cdt.0), |&x| x + == X224Type::ConnectionRequest as u8)?; + let _ = verify!(i1, value!(cr_cdt.1), |&x| x == 0 || x == 1)?; let (i3, dst_ref) = verify!(i2, be_u16, |&x| x == 0)?; let (i4, src_ref) = try_parse!(i3, be_u16); let (i5, class_options) = bits!( @@ -503,9 +504,7 @@ fn parse_x224_connection_request( ) )?; // less cr_cdt (u8), dst_ref (u16), src_ref (u16), class_options (u8) - if length < 6 { - return make_error(i5, ErrorKind::Verify)?; - } + let _ = verify!(i1, value!(length), |&x| x >= 6)?; let i6 = i5; let sz = length - 6; @@ -575,12 +574,8 @@ fn parse_x224_connection_request_class_0( fn parse_rdp_cookie(input: &[u8]) -> IResult<&[u8], RdpCookie, RdpError> { do_parse! { input, - _key: verify!( - take!(8), - |x| x == b"Cookie: ") - >> _name: verify!( - take!(9), - |x| x == b"mstshash=") + _key: tag!(b"Cookie: ") + >> _name: tag!(b"mstshash=") >> bytes: take_until_and_consume!("\r\n") >> s: map_res!(value!(bytes), std::str::from_utf8) >> (RdpCookie{ mstshash: String::from(s) }) @@ -616,14 +611,10 @@ fn parse_x224_connection_confirm( input: &[u8], ) -> IResult<&[u8], X224ConnectionConfirm, RdpError> { let (i1, length) = verify!(input, be_u8, |&x| x != 0xff)?; // 0xff is reserved - let (i2, cr_cdt) = bits!( - i1, - tuple!( - verify!(take_bits!(4u8), |&x| x - == X224Type::ConnectionConfirm as u8), - verify!(take_bits!(4u8), |&x| x == 0 || x == 1) - ) - )?; + let (i2, cr_cdt) = take_4_4_bits(input)?; + let _ = verify!(i1, value!(cr_cdt.0), |&x| x + == X224Type::ConnectionConfirm as u8)?; + let _ = verify!(i1, value!(cr_cdt.1), |&x| x == 0 || x == 1)?; let (i3, dst_ref) = verify!(i2, be_u16, |&x| x == 0)?; let (i4, src_ref) = try_parse!(i3, be_u16); let (i5, class_options) = bits!( @@ -635,9 +626,7 @@ fn parse_x224_connection_confirm( )?; // less cr_cdt (u8), dst_ref (u16), src_ref (u16), class_options (u8) - if length < 6 { - return make_error(i5, ErrorKind::Verify)?; - } + let _ = verify!(i1, value!(length), |&x| x >= 6)?; let i6 = i5; let sz = length - 6; @@ -744,15 +733,18 @@ fn parse_negotiation_failure( /// x224-spec, section 13.7 fn parse_x223_data_class_0(input: &[u8]) -> IResult<&[u8], X223Data, RdpError> { - let (i1, _length) = verify!(input, be_u8, |&x| x == 2)?; - let (i2, _dt_x_roa) = bits!( - i1, - tuple!( - verify!(take_bits!(4u8), |&x| x == 0xf), - verify!(take_bits!(3u8), |&x| x == 0), - verify!(take_bits!(1u8), |&x| x == 0) + fn parser(input: &[u8]) -> IResult<&[u8], (u8,u8,u8), RdpError> { + bits!( + input, + tuple!( + verify!(take_bits!(4u8), |&x| x == 0xf), + verify!(take_bits!(3u8), |&x| x == 0), + verify!(take_bits!(1u8), |&x| x == 0) + ) ) - )?; + } + let (i1, _length) = verify!(input, be_u8, |&x| x == 2)?; + let (i2, _dt_x_roa) = parser(i1)?; let (i3, _eot) = verify!(i2, be_u8, |&x| x == 0x80)?; // @@ -889,14 +881,14 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { // let (j13, post_beta2_color_depth) = - match opt!(j12, map_opt!(le_u16, num::FromPrimitive::from_u16)) { + match opt!(j12, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j12, None), }; let (j14, client_product_id) = match post_beta2_color_depth { None => (j13, None), - Some(_) => match opt!(j13, le_u16) { + Some(_) => match opt!(j13, le_u16) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j13, None), }, @@ -904,7 +896,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j15, serial_number) = match client_product_id { None => (j14, None), - Some(_) => match opt!(j14, le_u32) { + Some(_) => match opt!(j14, le_u32) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j14, None), }, @@ -913,7 +905,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j16, high_color_depth) = match serial_number { None => (j15, None), Some(_) => { - match opt!(j15, map_opt!(le_u16, num::FromPrimitive::from_u16)) { + match opt!(j15, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j15, None), } @@ -923,7 +915,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j17, supported_color_depth) = match high_color_depth { None => (j16, None), Some(_) => { - match opt!(j16, map_opt!(le_u16, SupportedColorDepth::from_bits)) { + match opt!(j16, map_opt!(le_u16, SupportedColorDepth::from_bits)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j16, None), } @@ -933,7 +925,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j18, early_capability_flags) = match supported_color_depth { None => (j17, None), Some(_) => { - match opt!(j17, map_opt!(le_u16, EarlyCapabilityFlags::from_bits)) { + match opt!(j17, map_opt!(le_u16, EarlyCapabilityFlags::from_bits)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j17, None), } @@ -942,7 +934,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j19, client_dig_product_id) = match early_capability_flags { None => (j18, None), - Some(_) => match opt!(j18, map_res!(take!(64), le_slice_to_string)) { + Some(_) => match opt(map_res(take(64usize), le_slice_to_string))(j18) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j18, None), }, @@ -951,7 +943,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j20, connection_hint) = match client_dig_product_id { None => (j19, None), Some(_) => { - match opt!(j19, map_opt!(le_u8, num::FromPrimitive::from_u8)) { + match opt(map_opt(le_u8, num::FromPrimitive::from_u8))(j19) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j19, None), } @@ -960,7 +952,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j21, pad) = match connection_hint { None => (j20, None), - Some(_) => match opt!(j20, take!(1)) { + Some(_) => match opt(take(1usize))(j20) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j20, None), }, @@ -969,7 +961,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j22, server_selected_protocol) = match pad { None => (j21, None), Some(_) => { - match opt!(j21, map_opt!(le_u32, ProtocolFlags::from_bits)) { + match opt!(j21, map_opt!(le_u32, ProtocolFlags::from_bits)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j21, None), } @@ -978,7 +970,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j23, desktop_physical_width) = match server_selected_protocol { None => (j22, None), - Some(_) => match opt!(j22, map_opt!(le_u32, millimeters_to_opt)) { + Some(_) => match opt!(j22, map_opt!(le_u32, millimeters_to_opt)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j22, None), }, @@ -986,7 +978,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j24, desktop_physical_height) = match desktop_physical_width { None => (j23, None), - Some(_) => match opt!(j23, map_opt!(le_u32, millimeters_to_opt)) { + Some(_) => match opt!(j23, map_opt!(le_u32, millimeters_to_opt)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j23, None), }, @@ -995,7 +987,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j25, desktop_orientation) = match desktop_physical_height { None => (j24, None), Some(_) => { - match opt!(j24, map_opt!(le_u16, num::FromPrimitive::from_u16)) { + match opt!(j24, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j24, None), } @@ -1004,7 +996,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (j26, desktop_scale_factor) = match desktop_orientation { None => (j25, None), - Some(_) => match opt!(j25, map_opt!(le_u32, desktop_scale_to_opt)) { + Some(_) => match opt!(j25, map_opt!(le_u32, desktop_scale_to_opt)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j25, None), }, @@ -1012,7 +1004,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> { let (_j27, device_scale_factor) = match desktop_scale_factor { None => (j26, None), - Some(_) => match opt!(j26, map_opt!(le_u32, device_scale_to_opt)) { + Some(_) => match opt!(j26, map_opt!(le_u32, device_scale_to_opt)) as IResult<&[u8],_> { Ok((rem, obj)) => (rem, obj), _ => (j26, None), }, diff --git a/rust/src/sip/parser.rs b/rust/src/sip/parser.rs index b8877fc71d..4edee68a89 100644 --- a/rust/src/sip/parser.rs +++ b/rust/src/sip/parser.rs @@ -161,7 +161,7 @@ named!(pub sip_take_line<&[u8], Option >, pub fn parse_headers(mut input: &[u8]) -> IResult<&[u8], HashMap> { let mut headers_map: HashMap = HashMap::new(); loop { - match crlf(input) { + match crlf(input) as IResult<&[u8],_> { Ok((_, _)) => { break; } diff --git a/rust/src/smb/dcerpc_records.rs b/rust/src/smb/dcerpc_records.rs index fa47a0cfda..24992d635e 100644 --- a/rust/src/smb/dcerpc_records.rs +++ b/rust/src/smb/dcerpc_records.rs @@ -206,19 +206,29 @@ pub struct DceRpcRecord<'a> { pub data: &'a[u8], } +fn parse_dcerpc_flags1(i:&[u8]) -> IResult<&[u8],(u8,u8,u8)> { + bits!(i, + tuple!( + take_bits!(6u8), + take_bits!(1u8), // last (1) + take_bits!(1u8))) // first (2) +} + +fn parse_dcerpc_flags2(i:&[u8]) -> IResult<&[u8],(u32,u32,u32)> { + bits!(i, + tuple!( + take_bits!(3u32), + take_bits!(1u32), // endianess + take_bits!(28u32))) +} + named!(pub parse_dcerpc_record, do_parse!( version_major: le_u8 >> version_minor: le_u8 >> packet_type: le_u8 - >> packet_flags: bits!(tuple!( - take_bits!(6u8), - take_bits!(1u8), // last (1) - take_bits!(1u8))) // first (2) - >> data_rep: bits!(tuple!( - take_bits!(3u32), - take_bits!(1u32), // endianess - take_bits!(28u32))) + >> packet_flags: parse_dcerpc_flags1 + >> data_rep: parse_dcerpc_flags2 >> endian: value!(if data_rep.1 == 0 { Endianness::Big } else { Endianness::Little }) >> frag_len: u16!(endian) >> _auth: u16!(endian) diff --git a/rust/src/smb/ntlmssp_records.rs b/rust/src/smb/ntlmssp_records.rs index 1f614c3bb0..52ca9ee9cb 100644 --- a/rust/src/smb/ntlmssp_records.rs +++ b/rust/src/smb/ntlmssp_records.rs @@ -15,6 +15,7 @@ * 02110-1301, USA. */ +use nom::IResult; use nom::combinator::rest; use nom::number::complete::{le_u8, le_u16, le_u32}; @@ -57,6 +58,10 @@ pub struct NTLMSSPAuthRecord<'a> { pub version: Option, } +fn parse_ntlm_auth_nego_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u32)> { + bits!(i, tuple!(take_bits!(6u8),take_bits!(1u8),take_bits!(25u32))) +} + named!(pub parse_ntlm_auth_record, do_parse!( _lm_blob_len: le_u16 @@ -83,7 +88,7 @@ named!(pub parse_ntlm_auth_record, >> _ssnkey_blob_maxlen: le_u16 >> _ssnkey_blob_offset: le_u32 - >> nego_flags: bits!(tuple!(take_bits!(6u8),take_bits!(1u8),take_bits!(25u32))) + >> nego_flags: parse_ntlm_auth_nego_flags >> version: cond!(nego_flags.1==1, parse_ntlm_auth_version) // subtrack 12 as idenfier (8) and type (4) are cut before we are called diff --git a/rust/src/smb/smb2_records.rs b/rust/src/smb/smb2_records.rs index ebfe441311..69fede11bc 100644 --- a/rust/src/smb/smb2_records.rs +++ b/rust/src/smb/smb2_records.rs @@ -67,6 +67,20 @@ impl<'a> Smb2Record<'a> { } } +fn parse_smb2_request_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u8,u32,u8,u8,u8,u8)> { + bits!(i, + tuple!( + take_bits!(2u8), // reserved / unused + take_bits!(1u8), // replay op + take_bits!(1u8), // dfs op + take_bits!(24u32), // reserved / unused + take_bits!(1u8), // signing + take_bits!(1u8), // chained + take_bits!(1u8), // async + take_bits!(1u8) // response + )) +} + named!(pub parse_smb2_request_record, do_parse!( _server_component: tag!(b"\xfeSMB") @@ -76,16 +90,7 @@ named!(pub parse_smb2_request_record, >> _reserved: take!(2) >> command: le_u16 >> _credits_requested: le_u16 - >> flags: bits!(tuple!( - take_bits!(2u8), // reserved / unused - take_bits!(1u8), // replay op - take_bits!(1u8), // dfs op - take_bits!(24u32), // reserved / unused - take_bits!(1u8), // signing - take_bits!(1u8), // chained - take_bits!(1u8), // async - take_bits!(1u8) // response - )) + >> flags: parse_smb2_request_flags >> chain_offset: le_u32 >> message_id: le_u64 >> _process_id: le_u32 @@ -507,16 +512,7 @@ named!(pub parse_smb2_response_record, >> nt_status: le_u32 >> command: le_u16 >> _credit_granted: le_u16 - >> flags: bits!(tuple!( - take_bits!(2u8), // reserved / unused - take_bits!(1u8), // replay op - take_bits!(1u8), // dfs op - take_bits!(24u32), // reserved / unused - take_bits!(1u8), // signing - take_bits!(1u8), // chained - take_bits!(1u8), // async - take_bits!(1u8) // response - )) + >> flags: parse_smb2_request_flags >> chain_offset: le_u32 >> message_id: le_u64 >> _process_id: cond!(flags.6==0, le_u32)