]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/smb: convert parser to nom7 functions (DCERPC records)
authorPierre Chifflier <chifflier@wzdftpd.net>
Sun, 14 Nov 2021 16:18:14 +0000 (17:18 +0100)
committerVictor Julien <vjulien@oisf.net>
Mon, 13 Dec 2021 12:06:21 +0000 (13:06 +0100)
rust/src/smb/dcerpc_records.rs

index 8d0b07faf98ba5acd1bf39b0dc3de582a04cad4e..57bbdf830a69d3e296267cadf99c4f75fbebc678 100644 (file)
  */
 
 use crate::smb::error::SmbError;
-use nom;
-use nom::IResult;
-use nom::combinator::rest;
-use nom::number::Endianness;
-use nom::number::streaming::{be_u16, le_u8, le_u16, le_u32};
+use nom7::bits::{bits, streaming::take as take_bits};
+use nom7::bytes::streaming::take;
+use nom7::combinator::{cond, rest};
+use nom7::error::Error;
+use nom7::multi::count;
+use nom7::number::Endianness;
+use nom7::number::streaming::{be_u16, le_u8, le_u16, le_u32, u16, u32};
+use nom7::sequence::tuple;
+use nom7::IResult;
 
 #[derive(Debug,PartialEq)]
 pub struct DceRpcResponseRecord<'a> {
@@ -30,7 +34,7 @@ pub struct DceRpcResponseRecord<'a> {
 /// parse a packet type 'response' DCERPC record. Implemented
 /// as function to be able to pass the fraglen in.
 pub fn parse_dcerpc_response_record(i:&[u8], frag_len: u16 )
-    -> IResult<&[u8], DceRpcResponseRecord, SmbError>
+    -> nom::IResult<&[u8], DceRpcResponseRecord, SmbError>
 {
     if frag_len < 24 {
         return Err(nom::Err::Error(SmbError::RecordTooSmall));
@@ -53,8 +57,9 @@ pub struct DceRpcRequestRecord<'a> {
 /// parse a packet type 'request' DCERPC record. Implemented
 /// as function to be able to pass the fraglen in.
 pub fn parse_dcerpc_request_record(i:&[u8], frag_len: u16, little: bool)
-    -> IResult<&[u8], DceRpcRequestRecord, SmbError>
+    -> nom::IResult<&[u8], DceRpcRequestRecord, SmbError>
 {
+    use nom::number::Endianness;
     if frag_len < 24 {
         return Err(nom::Err::Error(SmbError::RecordTooSmall));
     }
@@ -77,37 +82,37 @@ pub struct DceRpcBindIface<'a> {
     pub ver_min: u16,
 }
 
-named!(pub parse_dcerpc_bind_iface<DceRpcBindIface>,
-    do_parse!(
-            _ctx_id: le_u16
-        >>  _num_trans_items: le_u8
-        >>  take!(1) // reserved
-        >>  interface: take!(16)
-        >>  ver: le_u16
-        >>  ver_min: le_u16
-        >>  take!(20)
-        >> (DceRpcBindIface {
-                iface:interface,
-                ver:ver,
-                ver_min:ver_min,
-            })
-));
-
-named!(pub parse_dcerpc_bind_iface_big<DceRpcBindIface>,
-    do_parse!(
-            _ctx_id: le_u16
-        >>  _num_trans_items: le_u8
-        >>  take!(1) // reserved
-        >>  interface: take!(16)
-        >>  ver_min: be_u16
-        >>  ver: be_u16
-        >>  take!(20)
-        >> (DceRpcBindIface {
-                iface:interface,
-                ver:ver,
-                ver_min:ver_min,
-            })
-));
+pub fn parse_dcerpc_bind_iface(i: &[u8]) -> IResult<&[u8], DceRpcBindIface> {
+    let (i, _ctx_id) = le_u16(i)?;
+    let (i, _num_trans_items) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, interface) = take(16_usize)(i)?;
+    let (i, ver) = le_u16(i)?;
+    let (i, ver_min) = le_u16(i)?;
+    let (i, _) = take(20_usize)(i)?;
+    let res = DceRpcBindIface {
+        iface:interface,
+        ver,
+        ver_min,
+    };
+    Ok((i, res))
+}
+
+pub fn parse_dcerpc_bind_iface_big(i: &[u8]) -> IResult<&[u8], DceRpcBindIface> {
+    let (i, _ctx_id) = le_u16(i)?;
+    let (i, _num_trans_items) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, interface) = take(16_usize)(i)?;
+    let (i, ver_min) = be_u16(i)?;
+    let (i, ver) = be_u16(i)?;
+    let (i, _) = take(20_usize)(i)?;
+    let res = DceRpcBindIface {
+        iface:interface,
+        ver,
+        ver_min,
+    };
+    Ok((i, res))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct DceRpcBindRecord<'a> {
@@ -115,33 +120,33 @@ pub struct DceRpcBindRecord<'a> {
     pub ifaces: Vec<DceRpcBindIface<'a>>,
 }
 
-named!(pub parse_dcerpc_bind_record<DceRpcBindRecord>,
-    do_parse!(
-            _max_xmit_frag: le_u16
-        >>  _max_recv_frag: le_u16
-        >>  _assoc_group: take!(4)
-        >>  num_ctx_items: le_u8
-        >>  take!(3) // reserved
-        >>  ifaces: count!(parse_dcerpc_bind_iface, num_ctx_items as usize)
-        >> (DceRpcBindRecord {
-                num_ctx_items:num_ctx_items,
-                ifaces:ifaces,
-           })
-));
-
-named!(pub parse_dcerpc_bind_record_big<DceRpcBindRecord>,
-    do_parse!(
-            _max_xmit_frag: be_u16
-        >>  _max_recv_frag: be_u16
-        >>  _assoc_group: take!(4)
-        >>  num_ctx_items: le_u8
-        >>  take!(3) // reserved
-        >>  ifaces: count!(parse_dcerpc_bind_iface_big, num_ctx_items as usize)
-        >> (DceRpcBindRecord {
-                num_ctx_items:num_ctx_items,
-                ifaces:ifaces,
-           })
-));
+pub fn parse_dcerpc_bind_record(i: &[u8]) -> IResult<&[u8], DceRpcBindRecord> {
+    let (i, _max_xmit_frag) = le_u16(i)?;
+    let (i, _max_recv_frag) = le_u16(i)?;
+    let (i, _assoc_group) = take(4_usize)(i)?;
+    let (i, num_ctx_items) = le_u8(i)?;
+    let (i, _) = take(3_usize)(i)?; // reserved
+    let (i, ifaces) = count(parse_dcerpc_bind_iface, num_ctx_items as usize)(i)?;
+    let record = DceRpcBindRecord {
+        num_ctx_items,
+        ifaces,
+    };
+    Ok((i, record))
+}
+
+pub fn parse_dcerpc_bind_record_big(i: &[u8]) -> IResult<&[u8], DceRpcBindRecord> {
+    let (i, _max_xmit_frag) = be_u16(i)?;
+    let (i, _max_recv_frag) = be_u16(i)?;
+    let (i, _assoc_group) = take(4_usize)(i)?;
+    let (i, num_ctx_items) = le_u8(i)?;
+    let (i, _) = take(3_usize)(i)?; // reserved
+    let (i, ifaces) = count(parse_dcerpc_bind_iface_big, num_ctx_items as usize)(i)?;
+    let record = DceRpcBindRecord {
+        num_ctx_items,
+        ifaces,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct DceRpcBindAckResult<'a> {
@@ -151,19 +156,19 @@ pub struct DceRpcBindAckResult<'a> {
     pub syntax_version: u32,
 }
 
-named!(pub parse_dcerpc_bindack_result<DceRpcBindAckResult>,
-    do_parse!(
-            ack_result: le_u16
-        >>  ack_reason: le_u16
-        >>  transfer_syntax: take!(16)
-        >>  syntax_version: le_u32
-        >> (DceRpcBindAckResult {
-                ack_result:ack_result,
-                ack_reason:ack_reason,
-                transfer_syntax:transfer_syntax,
-                syntax_version:syntax_version,
-            })
-));
+pub fn parse_dcerpc_bindack_result(i: &[u8]) -> IResult<&[u8], DceRpcBindAckResult> {
+    let (i, ack_result) = le_u16(i)?;
+    let (i, ack_reason) = le_u16(i)?;
+    let (i, transfer_syntax) = take(16_usize)(i)?;
+    let (i, syntax_version) = le_u32(i)?;
+    let res = DceRpcBindAckResult {
+        ack_result,
+        ack_reason,
+        transfer_syntax,
+        syntax_version,
+    };
+    Ok((i, res))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct DceRpcBindAckRecord<'a> {
@@ -171,22 +176,22 @@ pub struct DceRpcBindAckRecord<'a> {
     pub results: Vec<DceRpcBindAckResult<'a>>,
 }
 
-named!(pub parse_dcerpc_bindack_record<DceRpcBindAckRecord>,
-    do_parse!(
-            _max_xmit_frag: le_u16
-        >>  _max_recv_frag: le_u16
-        >>  _assoc_group: take!(4)
-        >>  sec_addr_len: le_u16
-        >>  take!(sec_addr_len)
-        >>  cond!((sec_addr_len+2) % 4 != 0, take!(4 - (sec_addr_len+2) % 4))
-        >>  num_results: le_u8
-        >>  take!(3) // padding
-        >>  results: count!(parse_dcerpc_bindack_result, num_results as usize)
-        >> (DceRpcBindAckRecord {
-                num_results:num_results,
-                results:results,
-           })
-));
+pub fn parse_dcerpc_bindack_record(i: &[u8]) -> IResult<&[u8], DceRpcBindAckRecord> {
+    let (i, _max_xmit_frag) = le_u16(i)?;
+    let (i, _max_recv_frag) = le_u16(i)?;
+    let (i, _assoc_group) = take(4_usize)(i)?;
+    let (i, sec_addr_len) = le_u16(i)?;
+    let (i, _) = take(sec_addr_len)(i)?;
+    let (i, _) = cond((sec_addr_len+2) % 4 != 0, take(4 - (sec_addr_len+2) % 4))(i)?;
+    let (i, num_results) = le_u8(i)?;
+    let (i, _) = take(3_usize)(i)?; // padding
+    let (i, results) = count(parse_dcerpc_bindack_result, num_results as usize)(i)?;
+    let record = DceRpcBindAckRecord {
+        num_results,
+        results,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct DceRpcRecord<'a> {
@@ -207,42 +212,42 @@ pub struct DceRpcRecord<'a> {
 }
 
 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)
+    bits::<_, _, Error<(&[u8], usize)>, _, _>(tuple((
+        take_bits(6u8),
+        take_bits(1u8),   // last (1)
+        take_bits(1u8),
+    )))(i)
 }
 
 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<DceRpcRecord>,
-    do_parse!(
-            version_major: le_u8
-        >>  version_minor: le_u8
-        >>  packet_type: le_u8
-        >>  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)
-        >>  call_id: u32!(endian)
-        >>  data:rest
-        >> (DceRpcRecord {
-                version_major:version_major,
-                version_minor:version_minor,
-                packet_type:packet_type,
-                first_frag:packet_flags.2==1,
-                last_frag:packet_flags.1==1,
-                frag_len: frag_len,
-                little_endian:data_rep.1==1,
-                call_id:call_id,
-                data:data,
-           })
-));
+    bits::<_, _, Error<(&[u8], usize)>, _, _>(tuple((
+       take_bits(3u32),
+       take_bits(1u32),     // endianess
+       take_bits(28u32),
+    )))(i)
+}
+
+pub fn parse_dcerpc_record(i: &[u8]) -> IResult<&[u8], DceRpcRecord> {
+    let (i, version_major) = le_u8(i)?;
+    let (i, version_minor) = le_u8(i)?;
+    let (i, packet_type) = le_u8(i)?;
+    let (i, packet_flags) = parse_dcerpc_flags1(i)?;
+    let (i, data_rep) = parse_dcerpc_flags2(i)?;
+    let endian = if data_rep.1 == 0 { Endianness::Big } else { Endianness::Little };
+    let (i, frag_len) = u16(endian)(i)?;
+    let (i, _auth) = u16(endian)(i)?;
+    let (i, call_id) = u32(endian)(i)?;
+    let (i, data) = rest(i)?;
+    let record = DceRpcRecord {
+        version_major,
+        version_minor,
+        packet_type,
+        first_frag: packet_flags.2 == 1,
+        last_frag: packet_flags.1 == 1,
+        frag_len,
+        little_endian: data_rep.1 == 1,
+        call_id,
+        data,
+    };
+    Ok((i, record))
+}