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

index 57bbdf830a69d3e296267cadf99c4f75fbebc678..4cfd40c567f59b606d20023f6c086addee6a094d 100644 (file)
@@ -24,7 +24,7 @@ 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;
+use nom7::{Err, IResult};
 
 #[derive(Debug,PartialEq)]
 pub struct DceRpcResponseRecord<'a> {
@@ -34,18 +34,15 @@ 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 )
-    -> nom::IResult<&[u8], DceRpcResponseRecord, SmbError>
+    -> IResult<&[u8], DceRpcResponseRecord, SmbError>
 {
     if frag_len < 24 {
-        return Err(nom::Err::Error(SmbError::RecordTooSmall));
+        return Err(Err::Error(SmbError::RecordTooSmall));
     }
-    do_parse!(i,
-                take!(8)
-            >>  data:take!(frag_len - 24)
-            >> (DceRpcResponseRecord {
-                    data:data,
-               })
-    )
+    let (i, _) = take(8_usize)(i)?;
+    let (i, data) = take(frag_len - 24)(i)?;
+    let record = DceRpcResponseRecord { data };
+    Ok((i, record))
 }
 
 #[derive(Debug,PartialEq)]
@@ -57,22 +54,17 @@ 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)
-    -> nom::IResult<&[u8], DceRpcRequestRecord, SmbError>
+    -> IResult<&[u8], DceRpcRequestRecord, SmbError>
 {
-    use nom::number::Endianness;
     if frag_len < 24 {
-        return Err(nom::Err::Error(SmbError::RecordTooSmall));
+        return Err(Err::Error(SmbError::RecordTooSmall));
     }
-    do_parse!(i,
-                take!(6)
-            >>  endian: value!(if little { Endianness::Little } else { Endianness::Big })
-            >>  opnum: u16!(endian)
-            >>  data:take!(frag_len - 24)
-            >> (DceRpcRequestRecord {
-                    opnum:opnum,
-                    data:data,
-               })
-    )
+    let (i, _) = take(6_usize)(i)?;
+    let endian = if little { Endianness::Little } else { Endianness::Big };
+    let (i, opnum) = u16(endian)(i)?;
+    let (i, data) = take(frag_len - 24)(i)?;
+    let record = DceRpcRequestRecord { opnum, data };
+    Ok((i, record))
 }
 
 #[derive(Debug,PartialEq)]
index ab9c86367439f7ff5c839f6ca183c61c6b1f4ccd..352c275ad77ea18e17c93d8692fb2be9170a75b5 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 // Author: Pierre Chifflier <chifflier@wzdftpd.net>
-use nom::error::{ErrorKind, ParseError};
+use nom7::error::{ErrorKind, ParseError};
 
 #[derive(Debug)]
 pub enum SmbError {
index 393c7868ed215bc83add5d9cfd6a735aa151475b..e9fa49b2524e7e27a1309937c8ba8900f79e8717 100644 (file)
@@ -31,7 +31,6 @@ use std::ffi::{self, CString};
 
 use std::collections::HashMap;
 
-use nom;
 use nom7::{Err, Needed};
 
 use crate::core::*;
@@ -1649,7 +1648,7 @@ impl SMBState {
                                     }
                                 }
                             },
-                            Err(nom::Err::Incomplete(_)) => {
+                            Err(Err::Incomplete(_)) => {
                                 // not enough data to contain basic SMB hdr
                                 // TODO event: empty NBSS_MSGTYPE_SESSION_MESSAGE
                             },
index b81ebee944257679f74706cba63e045423a47dee..ec4149d3b2b3f7048db244eddd76c6b71ff0f17c 100644 (file)
@@ -19,8 +19,6 @@
  * - check all parsers for calls on non-SUCCESS status
  */
 
-use nom;
-
 use crate::core::*;
 
 use crate::smb::smb::*;
@@ -31,6 +29,8 @@ use crate::smb::files::*;
 use crate::smb::smb1_records::*;
 use crate::smb::smb1_session::*;
 
+use nom7::Err;
+
 // https://msdn.microsoft.com/en-us/library/ee441741.aspx
 pub const SMB1_COMMAND_CREATE_DIRECTORY:        u8 = 0x00;
 pub const SMB1_COMMAND_DELETE_DIRECTORY:        u8 = 0x01;
@@ -251,13 +251,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                                             true
 
                                         },
-                                        Err(nom::Err::Incomplete(_n)) => {
+                                        Err(Err::Incomplete(_n)) => {
                                             SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", _n);
                                             events.push(SMBEvent::MalformedData);
                                             false
                                         },
-                                        Err(nom::Err::Error(_e)) |
-                                        Err(nom::Err::Failure(_e)) => {
+                                        Err(Err::Error(_e)) |
+                                        Err(Err::Failure(_e)) => {
                                             SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", _e);
                                             events.push(SMBEvent::MalformedData);
                                             false
@@ -279,13 +279,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                                             tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
                                             true
                                         },
-                                        Err(nom::Err::Incomplete(_n)) => {
+                                        Err(Err::Incomplete(_n)) => {
                                             SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME INCOMPLETE {:?}", _n);
                                             events.push(SMBEvent::MalformedData);
                                             false
                                         },
-                                        Err(nom::Err::Error(_e)) |
-                                        Err(nom::Err::Failure(_e)) => {
+                                        Err(Err::Error(_e)) |
+                                        Err(Err::Failure(_e)) => {
                                             SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME ERROR {:?}", _e);
                                             events.push(SMBEvent::MalformedData);
                                             false
@@ -295,13 +295,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                                     false
                                 }
                             },
-                            Err(nom::Err::Incomplete(_n)) => {
+                            Err(Err::Incomplete(_n)) => {
                                 SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS INCOMPLETE {:?}", _n);
                                 events.push(SMBEvent::MalformedData);
                                 false
                             },
-                            Err(nom::Err::Error(_e)) |
-                            Err(nom::Err::Failure(_e)) => {
+                            Err(Err::Error(_e)) |
+                            Err(Err::Failure(_e)) => {
                                 SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS ERROR {:?}", _e);
                                 events.push(SMBEvent::MalformedData);
                                 false
@@ -334,13 +334,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                                             true
 
                                         },
-                                        Err(nom::Err::Incomplete(_n)) => {
+                                        Err(Err::Incomplete(_n)) => {
                                             SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", _n);
                                             events.push(SMBEvent::MalformedData);
                                             false
                                         },
-                                        Err(nom::Err::Error(_e)) |
-                                        Err(nom::Err::Failure(_e)) => {
+                                        Err(Err::Error(_e)) |
+                                        Err(Err::Failure(_e)) => {
                                             SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", _e);
                                             events.push(SMBEvent::MalformedData);
                                             false
@@ -367,13 +367,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                                             tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
                                             true
                                         },
-                                        Err(nom::Err::Incomplete(_n)) => {
+                                        Err(Err::Incomplete(_n)) => {
                                             SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME INCOMPLETE {:?}", _n);
                                             events.push(SMBEvent::MalformedData);
                                             false
                                         },
-                                        Err(nom::Err::Error(_e)) |
-                                        Err(nom::Err::Failure(_e)) => {
+                                        Err(Err::Error(_e)) |
+                                        Err(Err::Failure(_e)) => {
                                             SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME ERROR {:?}", _e);
                                             events.push(SMBEvent::MalformedData);
                                             false
@@ -383,13 +383,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                                     false
                                 }
                             },
-                            Err(nom::Err::Incomplete(_n)) => {
+                            Err(Err::Incomplete(_n)) => {
                                 SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS INCOMPLETE {:?}", _n);
                                 events.push(SMBEvent::MalformedData);
                                 false
                             },
-                            Err(nom::Err::Error(_e)) |
-                            Err(nom::Err::Failure(_e)) => {
+                            Err(Err::Error(_e)) |
+                            Err(Err::Failure(_e)) => {
                                 SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS ERROR {:?}", _e);
                                 events.push(SMBEvent::MalformedData);
                                 false
@@ -399,13 +399,13 @@ fn smb1_request_record_one<'b>(state: &mut SMBState, r: &SmbRecord<'b>, command:
                         false
                     }
                 },
-                Err(nom::Err::Incomplete(_n)) => {
+                Err(Err::Incomplete(_n)) => {
                     SCLogDebug!("TRANS2 INCOMPLETE {:?}", _n);
                     events.push(SMBEvent::MalformedData);
                     false
                 },
-                Err(nom::Err::Error(_e)) |
-                Err(nom::Err::Failure(_e)) => {
+                Err(Err::Error(_e)) |
+                Err(Err::Failure(_e)) => {
                     SCLogDebug!("TRANS2 ERROR {:?}", _e);
                     events.push(SMBEvent::MalformedData);
                     false
index 671ac0f12f3400dc92d42fce569caea8aadcf83f..97e26337c2625b4feb012c9e9ce4b60e000e77ba 100644 (file)
  * 02110-1301, USA.
  */
 
+use crate::common::nom7::take_until_and_consume;
 use crate::smb::error::SmbError;
-use nom::IResult;
-use nom::combinator::rest;
-use nom::number::streaming::{le_u8, le_u16, le_u32, le_u64};
 use crate::smb::smb::*;
 use crate::smb::smb_records::*;
+use nom7::bytes::streaming::{tag, take};
+use nom7::combinator::{complete, cond, peek, rest};
+use nom7::multi::many1;
+use nom7::number::streaming::{le_u8, le_u16, le_u32, le_u64};
+use nom7::IResult;
 
 pub const SMB1_HEADER_SIZE: usize = 32;
 
 fn smb_get_unicode_string_with_offset(i: &[u8], offset: usize) -> IResult<&[u8], Vec<u8>, SmbError>
 {
-    do_parse!(i,
-            cond!(offset % 2 == 1, take!(1))
-        >>  s: call!(smb_get_unicode_string)
-        >> ( s )
-    )
+    let (i, _) = cond(offset % 2 == 1, take(1_usize))(i)?;
+    smb_get_unicode_string(i)
 }
 
 /// take a string, unicode or ascii based on record
@@ -50,19 +50,18 @@ pub struct SmbParamBlockAndXHeader {
     pub andx_offset: u16,
 }
 
-named!(pub smb1_parse_andx_header<SmbParamBlockAndXHeader>,
-    do_parse!(
-            wct: le_u8
-        >>  andx_command: le_u8
-        >>  take!(1)    // reserved
-        >>  andx_offset: le_u16
-        >>  (SmbParamBlockAndXHeader {
-                wct: wct,
-                andx_command: andx_command,
-                andx_offset: andx_offset,
-            }))
-
-);
+pub fn smb1_parse_andx_header(i: &[u8]) -> IResult<&[u8], SmbParamBlockAndXHeader> {
+    let (i, wct) = le_u8(i)?;
+    let (i, andx_command) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, andx_offset) = le_u16(i)?;
+    let hdr = SmbParamBlockAndXHeader {
+        wct,
+        andx_command,
+        andx_offset,
+    };
+    Ok((i, hdr))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb1WriteRequestRecord<'a> {
@@ -72,71 +71,71 @@ pub struct Smb1WriteRequestRecord<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb1_write_request_record<Smb1WriteRequestRecord>,
-    do_parse!(
-            _wct: le_u8
-        >>  fid: take!(2)
-        >>  _count: le_u16
-        >>  offset: le_u32
-        >>  _remaining: le_u16
-        >>  _bcc: le_u16
-        >>  _buffer_format: le_u8
-        >>  data_len: le_u16
-        >>  file_data: take!(data_len)
-        >> (Smb1WriteRequestRecord {
-                offset: offset as u64,
-                len: data_len as u32,
-                fid,
-                data:file_data,
-            }))
-);
+pub fn parse_smb1_write_request_record(i: &[u8]) -> IResult<&[u8], Smb1WriteRequestRecord> {
+    let (i, _wct) = le_u8(i)?;
+    let (i, fid) = take(2_usize)(i)?;
+    let (i, _count) = le_u16(i)?;
+    let (i, offset) = le_u32(i)?;
+    let (i, _remaining) = le_u16(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    let (i, _buffer_format) = le_u8(i)?;
+    let (i, data_len) = le_u16(i)?;
+    let (i, file_data) = take(data_len)(i)?;
+    let record = Smb1WriteRequestRecord {
+        offset: offset as u64,
+        len: data_len as u32,
+        fid,
+        data:file_data,
+    };
+    Ok((i, record))
+}
 
 pub fn parse_smb1_write_andx_request_record(i : &[u8], andx_offset: usize) -> IResult<&[u8], Smb1WriteRequestRecord> {
     let ax = andx_offset as u16;
-    do_parse!(i,
-            wct: le_u8
-        >>  _andx_command: le_u8
-        >>  take!(1)    // reserved
-        >>  _andx_offset: le_u16
-        >>  fid: take!(2)
-        >>  offset: le_u32
-        >>  take!(4)    // reserved
-        >>  _write_mode: le_u16
-        >>  _remaining: le_u16
-        >>  data_len_high: le_u16
-        >>  data_len_low: le_u16
-        >>  data_offset: le_u16
-        >>  high_offset: cond!(wct==14,le_u32)
-        >>  bcc: le_u16
-        //spec [MS-CIFS].pdf says always take one byte padding
-        >>  _padding: cond!(bcc > data_len_low, take!(bcc - data_len_low)) // TODO figure out how this works with data_len_high
-        >>  _padding_evasion: cond!(data_offset > ax+4+2*(wct as u16), take!(data_offset - (ax+4+2*(wct as u16))))
-        >>  file_data: rest
-        >> (Smb1WriteRequestRecord {
-                offset: if high_offset != None { ((high_offset.unwrap() as u64) << 32)|(offset as u64) } else { 0 },
-                len: (((data_len_high as u32) << 16) as u32)|(data_len_low as u32),
-                fid,
-                data:file_data,
-            }))
-}
-
-named!(pub parse_smb1_write_and_close_request_record<Smb1WriteRequestRecord>,
-    do_parse!(
-            _wct: le_u8
-        >>  fid: take!(2)
-        >>  count: le_u16
-        >>  offset: le_u32
-        >>  _last_write: take!(4)
-        >>  bcc: le_u16
-        >>  _padding: cond!(bcc > count, take!(bcc - count))
-        >>  file_data: take!(count)
-        >> (Smb1WriteRequestRecord {
-                offset: offset as u64,
-                len: count as u32,
-                fid,
-                data:file_data,
-            }))
-);
+    let (i, wct) = le_u8(i)?;
+    let (i, _andx_command) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, _andx_offset) = le_u16(i)?;
+    let (i, fid) = take(2_usize)(i)?;
+    let (i, offset) = le_u32(i)?;
+    let (i, _) = take(4_usize)(i)?; // reserved
+    let (i, _write_mode) = le_u16(i)?;
+    let (i, _remaining) = le_u16(i)?;
+    let (i, data_len_high) = le_u16(i)?;
+    let (i, data_len_low) = le_u16(i)?;
+    let (i, data_offset) = le_u16(i)?;
+    let (i, high_offset) = cond(wct == 14, le_u32)(i)?;
+    let (i, bcc) = le_u16(i)?;
+    //spec [MS-CIFS].pdf says always take one byte padding
+    let (i, _padding) = cond(bcc > data_len_low, |b| take(bcc - data_len_low)(b))(i)?; // TODO figure out how this works with data_len_high
+    let (i, _padding_evasion) = cond(data_offset > ax+4+2*(wct as u16), |b| take(data_offset - (ax+4+2*(wct as u16)))(b))(i)?;
+    let (i, file_data) = rest(i)?;
+    let record = Smb1WriteRequestRecord {
+        offset: if high_offset != None { ((high_offset.unwrap() as u64) << 32)|(offset as u64) } else { 0 },
+        len: (((data_len_high as u32) << 16) as u32)|(data_len_low as u32),
+        fid,
+        data: file_data,
+    };
+    Ok((i, record))
+}
+
+pub fn parse_smb1_write_and_close_request_record(i: &[u8]) -> IResult<&[u8], Smb1WriteRequestRecord> {
+    let (i, _wct) = le_u8(i)?;
+    let (i, fid) = take(2_usize)(i)?;
+    let (i, count) = le_u16(i)?;
+    let (i, offset) = le_u32(i)?;
+    let (i, _last_write) = take(4_usize)(i)?;
+    let (i, bcc) = le_u16(i)?;
+    let (i, _padding) = cond(bcc > count, |b| take(bcc - count)(b))(i)?;
+    let (i, file_data) = take(count)(i)?;
+    let record = Smb1WriteRequestRecord {
+        offset: offset as u64,
+        len: count as u32,
+        fid,
+        data: file_data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb1NegotiateProtocolResponseRecord<'a> {
@@ -144,55 +143,59 @@ pub struct Smb1NegotiateProtocolResponseRecord<'a> {
     pub server_guid: &'a[u8],
 }
 
-named!(pub parse_smb1_negotiate_protocol_response_record_error<Smb1NegotiateProtocolResponseRecord>,
-    do_parse!(
-            _wct: le_u8
-         >> _bcc: le_u16
-         >> ( Smb1NegotiateProtocolResponseRecord {
-                dialect_idx: 0,
-                server_guid: &[],
-            })
-));
-
-named!(pub parse_smb1_negotiate_protocol_response_record_ok<Smb1NegotiateProtocolResponseRecord>,
-    do_parse!(
-            _wct: le_u8
-        >>  dialect_idx: le_u16
-        >>  _sec_mode: le_u8
-        >>  take!(16)
-        >>  _caps: le_u32
-        >>  _sys_time: le_u64
-        >>  _server_tz: le_u16
-        >>  _challenge_len: le_u8
-        >>  bcc: le_u16
-        >>  server_guid: cond!(bcc >= 16, take!(16))
-        >> (Smb1NegotiateProtocolResponseRecord {
-                dialect_idx,
-                server_guid: server_guid.unwrap_or(&[]),
-            }))
-);
+pub fn parse_smb1_negotiate_protocol_response_record_error(i: &[u8])
+    -> IResult<&[u8], Smb1NegotiateProtocolResponseRecord> {
+     let (i, _wct) = le_u8(i)?;
+     let (i, _bcc) = le_u16(i)?;
+     let record = Smb1NegotiateProtocolResponseRecord {
+         dialect_idx: 0,
+         server_guid: &[],
+     };
+     Ok((i, record))
+}
+
+pub fn parse_smb1_negotiate_protocol_response_record_ok(i: &[u8])
+    -> IResult<&[u8], Smb1NegotiateProtocolResponseRecord> {
+    let (i, _wct) = le_u8(i)?;
+    let (i, dialect_idx) = le_u16(i)?;
+    let (i, _sec_mode) = le_u8(i)?;
+    let (i, _) = take(16_usize)(i)?;
+    let (i, _caps) = le_u32(i)?;
+    let (i, _sys_time) = le_u64(i)?;
+    let (i, _server_tz) = le_u16(i)?;
+    let (i, _challenge_len) = le_u8(i)?;
+    let (i, bcc) = le_u16(i)?;
+    let (i, server_guid) = cond(bcc >= 16, take(16_usize))(i)?;
+    let record = Smb1NegotiateProtocolResponseRecord {
+        dialect_idx,
+        server_guid: server_guid.unwrap_or(&[]),
+    };
+    Ok((i, record))
+}
 
-named!(pub parse_smb1_negotiate_protocol_response_record<Smb1NegotiateProtocolResponseRecord>,
-    switch!(peek!(le_u8),
-        0 => call!(parse_smb1_negotiate_protocol_response_record_error) |
-        _ => call!(parse_smb1_negotiate_protocol_response_record_ok)
-    ));
+pub fn parse_smb1_negotiate_protocol_response_record(i: &[u8])
+    -> IResult<&[u8], Smb1NegotiateProtocolResponseRecord> {
+    let (i, wct) = peek(le_u8)(i)?;
+    match wct {
+        0 => parse_smb1_negotiate_protocol_response_record_error(i),
+        _ => parse_smb1_negotiate_protocol_response_record_ok(i),
+    }
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb1NegotiateProtocolRecord<'a> {
     pub dialects: Vec<&'a [u8]>,
 }
 
-named!(pub parse_smb1_negotiate_protocol_record<Smb1NegotiateProtocolRecord>,
-    do_parse!(
-           _wtc: le_u8
-        >> _bcc: le_u16
-        // dialects is a list of [1 byte buffer format][string][0 terminator]
-        >> dialects: many1!(complete!(take_until_and_consume!("\0")))
-        >> (Smb1NegotiateProtocolRecord {
-                dialects
-            }))
-);
+pub fn parse_smb1_negotiate_protocol_record(i: &[u8])
+    -> IResult<&[u8], Smb1NegotiateProtocolRecord> {
+    let (i, _wtc) = le_u8(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    // dialects is a list of [1 byte buffer format][string][0 terminator]
+    let (i, dialects) = many1(complete(take_until_and_consume(b"\0")))(i)?;
+    let record = Smb1NegotiateProtocolRecord { dialects };
+    Ok((i, record))
+}
 
 
 #[derive(Debug,PartialEq)]
@@ -201,22 +204,23 @@ pub struct Smb1ResponseRecordTreeConnectAndX<'a> {
     pub nativefs: &'a[u8],
 }
 
-named!(pub parse_smb_connect_tree_andx_response_record<Smb1ResponseRecordTreeConnectAndX>,
-    do_parse!(
-            wct: le_u8
-        >>  _andx_command: le_u8
-        >>  take!(1)    // reserved
-        >>  _andx_offset: le_u16
-        >>  cond!(wct >= 3, take!(2))   // optional support
-        >>  cond!(wct == 7, take!(8))   // access masks
-        >>  _bcc: le_u16
-        >>  service: take_until_and_consume!("\x00")
-        >>  nativefs: take_until_and_consume!("\x00")
-        >> (Smb1ResponseRecordTreeConnectAndX {
-                service,
-                nativefs
-           }))
-);
+pub fn parse_smb_connect_tree_andx_response_record(i: &[u8])
+    -> IResult<&[u8], Smb1ResponseRecordTreeConnectAndX> {
+    let (i, wct) = le_u8(i)?;
+    let (i, _andx_command) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, _andx_offset) = le_u16(i)?;
+    let (i, _) = cond(wct >= 3, take(2_usize))(i)?; // optional support
+    let (i, _) = cond(wct == 7, take(8_usize))(i)?; // access masks
+    let (i, _bcc) = le_u16(i)?;
+    let (i, service) = take_until_and_consume(b"\x00")(i)?;
+    let (i, nativefs) = take_until_and_consume(b"\x00")(i)?;
+    let record = Smb1ResponseRecordTreeConnectAndX {
+        service,
+        nativefs
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRecordTreeConnectAndX<'a> {
@@ -224,18 +228,19 @@ pub struct SmbRecordTreeConnectAndX<'a> {
     pub service: &'a[u8],
 }
 
-pub fn parse_smb_connect_tree_andx_record<'a>(i: &'a[u8], r: &SmbRecord) -> IResult<&'a[u8], SmbRecordTreeConnectAndX<'a>, SmbError> {
-    do_parse!(i,
-       _skip1: take!(7)
-       >> pwlen: le_u16
-       >> _bcc: le_u16
-       >> _pw: take!(pwlen)
-       >> path: call!(smb1_get_string, r, 11 + pwlen as usize)
-       >> service: take_until_and_consume!("\x00")
-       >> (SmbRecordTreeConnectAndX {
-                path,
-                service
-           }))
+pub fn parse_smb_connect_tree_andx_record<'a>(i: &'a[u8], r: &SmbRecord)
+   -> IResult<&'a[u8], SmbRecordTreeConnectAndX<'a>, SmbError> {
+   let (i, _skip1) = take(7_usize)(i)?;
+   let (i, pwlen) = le_u16(i)?;
+   let (i, _bcc) = le_u16(i)?;
+   let (i, _pw) = take(pwlen)(i)?;
+   let (i, path) = smb1_get_string(i, r, 11 + pwlen as usize)?;
+   let (i, service) = take_until_and_consume(b"\x00")(i)?;
+   let record = SmbRecordTreeConnectAndX {
+       path,
+       service
+   };
+   Ok((i, record))
 }
 
 #[derive(Debug,PartialEq)]
@@ -252,16 +257,16 @@ pub struct SmbPipeProtocolRecord<'a> {
     pub fid: &'a[u8],
 }
 
-named!(pub parse_smb_trans_request_record_pipe<&[u8], SmbPipeProtocolRecord, SmbError>,
-    do_parse!(
-            fun: le_u16
-        >>  fid: take!(2)
-        >> (SmbPipeProtocolRecord {
-                function: fun,
-                fid
-            })
-    )
-);
+pub fn parse_smb_trans_request_record_pipe(i: &[u8])
+    -> IResult<&[u8], SmbPipeProtocolRecord, SmbError> {
+    let (i, fun) = le_u16(i)?;
+    let (i, fid) = take(2_usize)(i)?;
+    let record = SmbPipeProtocolRecord {
+        function: fun,
+        fid
+    };
+    Ok((i, record))
+}
 
 
 #[derive(Debug,PartialEq)]
@@ -274,36 +279,37 @@ pub struct SmbRecordTransRequestParams<> {
     bcc: u16,
 }
 
-named!(pub parse_smb_trans_request_record_params<&[u8], (SmbRecordTransRequestParams, Option<SmbPipeProtocolRecord>), SmbError>,
-    do_parse!(
-          wct: le_u8
-       >> _total_param_cnt: le_u16
-       >> _total_data_count: le_u16
-       >> _max_param_cnt: le_u16
-       >> max_data_cnt: le_u16
-       >> _max_setup_cnt: le_u8
-       >> take!(1) // reserved
-       >> take!(2) // flags
-       >> _timeout: le_u32
-       >> take!(2) // reserved
-       >> param_cnt: le_u16
-       >> param_offset: le_u16
-       >> data_cnt: le_u16
-       >> data_offset: le_u16
-       >> setup_cnt: le_u8
-       >> take!(1) // reserved
-       >> pipe: cond!(wct == 16 && setup_cnt == 2 && data_cnt > 0, parse_smb_trans_request_record_pipe)
-       >> bcc: le_u16
-       >> (( SmbRecordTransRequestParams {
-                max_data_cnt,
-                param_cnt,
-                param_offset,
-                data_cnt,
-                data_offset,
-                bcc
-            },
-            pipe)))
-);
+pub fn parse_smb_trans_request_record_params(i: &[u8])
+    -> IResult<&[u8], (SmbRecordTransRequestParams, Option<SmbPipeProtocolRecord>), SmbError>
+{
+   let (i, wct) = le_u8(i)?;
+   let (i, _total_param_cnt) = le_u16(i)?;
+   let (i, _total_data_count) = le_u16(i)?;
+   let (i, _max_param_cnt) = le_u16(i)?;
+   let (i, max_data_cnt) = le_u16(i)?;
+   let (i, _max_setup_cnt) = le_u8(i)?;
+   let (i, _) = take(1_usize)(i)?; // reserved
+   let (i, _) = take(2_usize)(i)?; // flags
+   let (i, _timeout) = le_u32(i)?;
+   let (i, _) = take(2_usize)(i)?; // reserved
+   let (i, param_cnt) = le_u16(i)?;
+   let (i, param_offset) = le_u16(i)?;
+   let (i, data_cnt) = le_u16(i)?;
+   let (i, data_offset) = le_u16(i)?;
+   let (i, setup_cnt) = le_u8(i)?;
+   let (i, _) = take(1_usize)(i)?; // reserved
+   let (i, pipe) = cond(wct == 16 && setup_cnt == 2 && data_cnt > 0, parse_smb_trans_request_record_pipe)(i)?;
+   let (i, bcc) = le_u16(i)?;
+   let params = SmbRecordTransRequestParams {
+            max_data_cnt,
+            param_cnt,
+            param_offset,
+            data_cnt,
+            data_offset,
+            bcc
+        };
+   Ok((i, (params, pipe)))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRecordTransRequestData<'a> {
@@ -314,15 +320,12 @@ pub fn parse_smb_trans_request_record_data(i: &[u8],
         pad1: usize, param_cnt: u16, pad2: usize, data_len: u16)
     -> IResult<&[u8], SmbRecordTransRequestData, SmbError>
 {
-    do_parse!(i,
-            take!(pad1)
-        >>  take!(param_cnt)
-        >>  take!(pad2)
-        >>  data: take!(data_len)
-        >> (SmbRecordTransRequestData {
-                data:data,
-            })
-    )
+    let (i, _) = take(pad1)(i)?;
+    let (i, _) = take(param_cnt)(i)?;
+    let (i, _) = take(pad2)(i)?;
+    let (i, data) = take(data_len)(i)?;
+    let req = SmbRecordTransRequestData { data };
+    Ok((i, req))
 }
 
 pub fn parse_smb_trans_request_record<'a, 'b>(i: &'a[u8], r: &SmbRecord<'b>)
@@ -370,7 +373,7 @@ pub fn parse_smb_trans_request_record<'a, 'b>(i: &'a[u8], r: &SmbRecord<'b>)
     };
 
     let res = SmbRecordTransRequest {
-        params: params, pipe: pipe, txname: n, data: recdata,
+        params, pipe, txname: n, data: recdata,
     };
     Ok((rem, res))
 }
@@ -383,105 +386,108 @@ pub struct SmbRecordTransResponse<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb_trans_response_error_record<SmbRecordTransResponse>,
-    do_parse!(
-          _wct: le_u8
-       >> bcc: le_u16
-       >> (SmbRecordTransResponse {
-                data_cnt:0,
-                bcc:bcc,
-                data:&[],
-           }))
-);
-
-named!(pub parse_smb_trans_response_regular_record<SmbRecordTransResponse>,
-    do_parse!(
-          wct: le_u8
-       >> _total_param_cnt: le_u16
-       >> _total_data_count: le_u16
-       >> take!(2) // reserved
-       >> _param_cnt: le_u16
-       >> _param_offset: le_u16
-       >> _param_displacement: le_u16
-       >> data_cnt: le_u16
-       >> data_offset: le_u16
-       >> _data_displacement: le_u16
-       >> _setup_cnt: le_u8
-       >> take!(1) // reserved
-       >> bcc: le_u16
-       >> take!(1) // padding
-       >> _padding_evasion: cond!(data_offset > 36+2*(wct as u16), take!(data_offset - (36+2*(wct as u16))))
-       >> data: take!(data_cnt)
-       >> (SmbRecordTransResponse {
-                data_cnt,
-                bcc,
-                data
-           }))
-);
-
-named!(pub parse_smb_trans_response_record<SmbRecordTransResponse>,
-    switch!(peek!(le_u8), // wct
-        0 => call!(parse_smb_trans_response_error_record) |
-        _ => call!(parse_smb_trans_response_regular_record))
-);
+pub fn parse_smb_trans_response_error_record(i: &[u8]) -> IResult<&[u8], SmbRecordTransResponse> {
+   let (i, _wct) = le_u8(i)?;
+   let (i, bcc) = le_u16(i)?;
+   let resp = SmbRecordTransResponse {
+       data_cnt: 0,
+       bcc,
+       data: &[],
+   };
+   Ok((i, resp))
+}
+
+pub fn parse_smb_trans_response_regular_record(i: &[u8]) -> IResult<&[u8], SmbRecordTransResponse> {
+   let (i, wct) = le_u8(i)?;
+   let (i, _total_param_cnt) = le_u16(i)?;
+   let (i, _total_data_count) = le_u16(i)?;
+   let (i, _) = take(2_usize)(i)?; // reserved
+   let (i, _param_cnt) = le_u16(i)?;
+   let (i, _param_offset) = le_u16(i)?;
+   let (i, _param_displacement) = le_u16(i)?;
+   let (i, data_cnt) = le_u16(i)?;
+   let (i, data_offset) = le_u16(i)?;
+   let (i, _data_displacement) = le_u16(i)?;
+   let (i, _setup_cnt) = le_u8(i)?;
+   let (i, _) = take(1_usize)(i)?; // reserved
+   let (i, bcc) = le_u16(i)?;
+   let (i, _) = take(1_usize)(i)?; // padding
+   let (i, _padding_evasion) = cond(
+       data_offset > 36+2*(wct as u16),
+       |b| take(data_offset - (36+2*(wct as u16)))(b)
+    )(i)?;
+   let (i, data) = take(data_cnt)(i)?;
+   let resp = SmbRecordTransResponse {
+       data_cnt,
+       bcc,
+       data
+   };
+   Ok((i, resp))
+}
+
+pub fn parse_smb_trans_response_record(i: &[u8]) -> IResult<&[u8], SmbRecordTransResponse> {
+    let (i, wct) = peek(le_u8)(i)?;
+    match wct {
+        0 => parse_smb_trans_response_error_record(i),
+        _ => parse_smb_trans_response_regular_record(i),
+    }
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRecordSetupAndX<'a> {
     pub sec_blob: &'a[u8],
 }
 
-named!(pub parse_smb_setup_andx_record<SmbRecordSetupAndX>,
-    do_parse!(
-          _skip1: take!(15)
-       >> sec_blob_len: le_u16
-       >> _skip2: take!(8)
-       >> _bcc: le_u16
-       >> sec_blob: take!(sec_blob_len)
-       >> (SmbRecordSetupAndX {
-                sec_blob
-           }))
-);
+pub fn parse_smb_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbRecordSetupAndX> {
+    let (i, _skip1) = take(15_usize)(i)?;
+    let (i, sec_blob_len) = le_u16(i)?;
+    let (i, _skip2) = take(8_usize)(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    let (i, sec_blob) = take(sec_blob_len)(i)?;
+    let record = SmbRecordSetupAndX { sec_blob };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbResponseRecordSetupAndX<'a> {
     pub sec_blob: &'a[u8],
 }
 
-named!(response_setup_andx_record<SmbResponseRecordSetupAndX>,
-    do_parse!(
-          _skip1: take!(7)
-       >> sec_blob_len: le_u16
-       >> _bcc: le_u16
-       >> sec_blob: take!(sec_blob_len)
-       >> (SmbResponseRecordSetupAndX {
-                sec_blob
-           }))
-);
+fn response_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX> {
+   let (i, _skip1) = take(7_usize)(i)?;
+   let (i, sec_blob_len) = le_u16(i)?;
+   let (i, _bcc) = le_u16(i)?;
+   let (i, sec_blob) = take(sec_blob_len)(i)?;
+   let record = SmbResponseRecordSetupAndX { sec_blob };
+   Ok((i, record))
+}
 
-named!(response_setup_andx_wct3_record<SmbResponseRecordSetupAndX>,
-    do_parse!(
-          _skip1: take!(7)
-       >> _bcc: le_u16
-       >> (SmbResponseRecordSetupAndX {
-                sec_blob:&[],
-           }))
-);
+fn response_setup_andx_wct3_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX> {
+   let (i, _skip1) = take(7_usize)(i)?;
+   let (i, _bcc) = le_u16(i)?;
+   let record = SmbResponseRecordSetupAndX {
+        sec_blob: &[],
+   };
+   Ok((i, record))
+}
 
-named!(response_setup_andx_error_record<SmbResponseRecordSetupAndX>,
-    do_parse!(
-          _wct: le_u8
-       >> _bcc: le_u16
-       >> (SmbResponseRecordSetupAndX {
-                sec_blob: &[],
-           }))
-);
+fn response_setup_andx_error_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX> {
+   let (i, _wct) = le_u8(i)?;
+   let (i, _bcc) = le_u16(i)?;
+   let record = SmbResponseRecordSetupAndX {
+        sec_blob: &[],
+   };
+   Ok((i, record))
+}
 
-named!(pub parse_smb_response_setup_andx_record<SmbResponseRecordSetupAndX>,
-    switch!(peek!(le_u8), // wct
-        0 => call!(response_setup_andx_error_record) |
-        3 => call!(response_setup_andx_wct3_record)  |
-        _ => call!(response_setup_andx_record))
-);
+pub fn parse_smb_response_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX> {
+    let (i, wct) = peek(le_u8)(i)?;
+    match wct {
+        0 => response_setup_andx_error_record(i),
+        3 => response_setup_andx_wct3_record(i),
+        _ => response_setup_andx_record(i),
+    }
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRequestReadAndXRecord<'a> {
@@ -490,25 +496,25 @@ pub struct SmbRequestReadAndXRecord<'a> {
     pub offset: u64,
 }
 
-named!(pub parse_smb_read_andx_request_record<SmbRequestReadAndXRecord>,
-    do_parse!(
-            wct: le_u8
-        >>  _andx_command: le_u8
-        >>  take!(1)    // reserved
-        >>  _andx_offset: le_u16
-        >>  fid: take!(2)
-        >>  offset: le_u32
-        >>  max_count_low: le_u16
-        >>  take!(2)
-        >>  max_count_high: le_u32
-        >>  take!(2)
-        >>  high_offset: cond!(wct==12,le_u32) // only from wct ==12?
-        >> (SmbRequestReadAndXRecord {
-                fid,
-                size: (((max_count_high as u64) << 16)|max_count_low as u64),
-                offset: if high_offset != None { ((high_offset.unwrap() as u64) << 32)|(offset as u64) } else { 0 },
-           }))
-);
+pub fn parse_smb_read_andx_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestReadAndXRecord> {
+    let (i, wct) = le_u8(i)?;
+    let (i, _andx_command) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, _andx_offset) = le_u16(i)?;
+    let (i, fid) = take(2_usize)(i)?;
+    let (i, offset) = le_u32(i)?;
+    let (i, max_count_low) = le_u16(i)?;
+    let (i, _) = take(2_usize)(i)?;
+    let (i, max_count_high) = le_u32(i)?;
+    let (i, _) = take(2_usize)(i)?;
+    let (i, high_offset) = cond(wct == 12,le_u32)(i)?; // only from wct ==12?
+    let record = SmbRequestReadAndXRecord {
+        fid,
+        size: (((max_count_high as u64) << 16)|max_count_low as u64),
+        offset: if high_offset != None { ((high_offset.unwrap() as u64) << 32)|(offset as u64) } else { 0 },
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbResponseReadAndXRecord<'a> {
@@ -516,27 +522,33 @@ pub struct SmbResponseReadAndXRecord<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb_read_andx_response_record<SmbResponseReadAndXRecord>,
-    do_parse!(
-            wct: le_u8
-        >>  _andx_command: le_u8
-        >>  take!(1)    // reserved
-        >>  _andx_offset: le_u16
-        >>  take!(6)
-        >>  data_len_low: le_u16
-        >>  data_offset: le_u16
-        >>  data_len_high: le_u32
-        >>  take!(6)    // reserved
-        >>  bcc: le_u16
-        >>  _padding: cond!(bcc > data_len_low, take!(bcc - data_len_low)) // TODO figure out how this works with data_len_high
-        >>  _padding_evasion: cond!(data_offset > 36+2*(wct as u16), take!(data_offset - (36+2*(wct as u16))))
-        >>  file_data: rest
-
-        >> (SmbResponseReadAndXRecord {
-                len: (((data_len_high as u32) << 16)|data_len_low as u32),
-                data:file_data,
-           }))
-);
+pub fn parse_smb_read_andx_response_record(i: &[u8]) -> IResult<&[u8], SmbResponseReadAndXRecord> {
+    let (i, wct) = le_u8(i)?;
+    let (i, _andx_command) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, _andx_offset) = le_u16(i)?;
+    let (i, _) = take(6_usize)(i)?;
+    let (i, data_len_low) = le_u16(i)?;
+    let (i, data_offset) = le_u16(i)?;
+    let (i, data_len_high) = le_u32(i)?;
+    let (i, _) = take(6_usize)(i)?; // reserved
+    let (i, bcc) = le_u16(i)?;
+    let (i, _padding) = cond(
+        bcc > data_len_low,
+        |b| take(bcc - data_len_low)(b)
+    )(i)?; // TODO figure out how this works with data_len_high
+    let (i, _padding_evasion) = cond(
+        data_offset > 36+2*(wct as u16),
+        |b| take(data_offset - (36+2*(wct as u16)))(b)
+    )(i)?;
+    let (i, file_data) = rest(i)?;
+
+    let record = SmbResponseReadAndXRecord {
+        len: (((data_len_high as u32) << 16)|data_len_low as u32),
+        data: file_data,
+   };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRequestRenameRecord {
@@ -544,20 +556,20 @@ pub struct SmbRequestRenameRecord {
     pub newname: Vec<u8>,
 }
 
-named!(pub parse_smb_rename_request_record<&[u8], SmbRequestRenameRecord, SmbError>,
-    do_parse!(
-            _wct: le_u8
-        >>  _search_attr: le_u16
-        >>  _bcc: le_u16
-        >>  _oldtype: le_u8
-        >>  oldname: smb_get_unicode_string
-        >>  _newtype: le_u8
-        >>  newname: call!(smb_get_unicode_string_with_offset, 1) // HACK if we assume oldname is a series of utf16 chars offset would be 1
-        >> (SmbRequestRenameRecord {
-                oldname,
-                newname
-           }))
-);
+pub fn parse_smb_rename_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestRenameRecord, SmbError> {
+    let (i, _wct) = le_u8(i)?;
+    let (i, _search_attr) = le_u16(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    let (i, _oldtype) = le_u8(i)?;
+    let (i, oldname) = smb_get_unicode_string(i)?;
+    let (i, _newtype) = le_u8(i)?;
+    let (i, newname) = smb_get_unicode_string_with_offset(i, 1)?; // HACK if we assume oldname is a series of utf16 chars offset would be 1
+    let record = SmbRequestRenameRecord {
+        oldname,
+        newname
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRequestCreateAndXRecord<> {
@@ -569,21 +581,24 @@ pub struct SmbRequestCreateAndXRecord<> {
 pub fn parse_smb_create_andx_request_record<'a>(i: &'a[u8], r: &SmbRecord)
     -> IResult<&'a[u8], SmbRequestCreateAndXRecord<>, SmbError>
 {
-    do_parse!(i,
-          _skip1: take!(6)
-       >> file_name_len: le_u16
-       >> _skip3: take!(28)
-       >> disposition: le_u32
-       >> create_options: le_u32
-       >> _skip2: take!(5)
-       >> bcc: le_u16
-       >> file_name: cond!(bcc >= file_name_len, call!(smb1_get_string, r, (bcc - file_name_len) as usize))
-       >> _skip3: rest
-       >> (SmbRequestCreateAndXRecord {
-                disposition: disposition,
-                create_options: create_options,
-                file_name: file_name.unwrap_or_default(),
-           }))
+    let (i, _skip1) = take(6_usize)(i)?;
+    let (i, file_name_len) = le_u16(i)?;
+    let (i, _skip3) = take(28_usize)(i)?;
+    let (i, disposition) = le_u32(i)?;
+    let (i, create_options) = le_u32(i)?;
+    let (i, _skip2) = take(5_usize)(i)?;
+    let (i, bcc) = le_u16(i)?;
+    let (i, file_name) = cond(
+        bcc >= file_name_len,
+        |b| smb1_get_string(b, r, (bcc - file_name_len) as usize)
+    )(i)?;
+    let (i, _skip3) = rest(i)?;
+    let record = SmbRequestCreateAndXRecord {
+        disposition,
+        create_options,
+        file_name: file_name.unwrap_or_default(),
+    };
+    Ok((i, record))
 }
 
 #[derive(Debug,PartialEq)]
@@ -591,13 +606,14 @@ pub struct Trans2RecordParamSetFileInfoDisposition<> {
     pub delete: bool,
 }
 
-named!(pub parse_trans2_request_data_set_file_info_disposition<Trans2RecordParamSetFileInfoDisposition>,
-    do_parse!(
-            delete: le_u8
-        >> (Trans2RecordParamSetFileInfoDisposition {
-                delete: delete & 1 == 1,
-            })
-));
+pub fn parse_trans2_request_data_set_file_info_disposition(i: &[u8])
+    -> IResult<&[u8], Trans2RecordParamSetFileInfoDisposition> {
+    let (i, delete) = le_u8(i)?;
+    let record = Trans2RecordParamSetFileInfoDisposition {
+        delete: delete & 1 == 1,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Trans2RecordParamSetFileInfo<'a> {
@@ -605,15 +621,12 @@ pub struct Trans2RecordParamSetFileInfo<'a> {
     pub loi: u16,
 }
 
-named!(pub parse_trans2_request_params_set_file_info<Trans2RecordParamSetFileInfo>,
-    do_parse!(
-            fid: take!(2)
-        >>  loi: le_u16
-        >> (Trans2RecordParamSetFileInfo {
-                fid:fid,
-                loi:loi,
-            })
-));
+pub fn parse_trans2_request_params_set_file_info(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetFileInfo> {
+    let (i, fid) = take(2_usize)(i)?;
+    let (i, loi) = le_u16(i)?;
+    let record = Trans2RecordParamSetFileInfo { fid, loi };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Trans2RecordParamSetFileInfoRename<'a> {
@@ -621,18 +634,18 @@ pub struct Trans2RecordParamSetFileInfoRename<'a> {
     pub newname: &'a[u8],
 }
 
-named!(pub parse_trans2_request_data_set_file_info_rename<Trans2RecordParamSetFileInfoRename>,
-    do_parse!(
-            replace: le_u8
-        >>  _reserved: take!(3)
-        >>  _root_dir: take!(4)
-        >>  newname_len: le_u32
-        >>  newname: take!(newname_len)
-        >> (Trans2RecordParamSetFileInfoRename {
-                replace: replace==1,
-                newname: newname,
-            })
-));
+pub fn parse_trans2_request_data_set_file_info_rename(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetFileInfoRename> {
+    let (i, replace) = le_u8(i)?;
+    let (i, _reserved) = take(3_usize)(i)?;
+    let (i, _root_dir) = take(4_usize)(i)?;
+    let (i, newname_len) = le_u32(i)?;
+    let (i, newname) = take(newname_len)(i)?;
+    let record = Trans2RecordParamSetFileInfoRename {
+        replace: replace==1,
+        newname,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Trans2RecordParamSetPathInfo<> {
@@ -640,16 +653,13 @@ pub struct Trans2RecordParamSetPathInfo<> {
     pub oldname: Vec<u8>,
 }
 
-named!(pub parse_trans2_request_params_set_path_info<&[u8], Trans2RecordParamSetPathInfo, SmbError>,
-    do_parse!(
-            loi: le_u16
-        >>  _reserved: take!(4)
-        >>  oldname: call!(smb_get_unicode_string)
-        >> (Trans2RecordParamSetPathInfo {
-                loi,
-                oldname
-            })
-));
+pub fn parse_trans2_request_params_set_path_info(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetPathInfo, SmbError> {
+    let (i, loi) = le_u16(i)?;
+    let (i, _reserved) = take(4_usize)(i)?;
+    let (i, oldname) = smb_get_unicode_string(i)?;
+    let record = Trans2RecordParamSetPathInfo { loi, oldname };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Trans2RecordParamSetPathInfoRename<'a> {
@@ -657,18 +667,18 @@ pub struct Trans2RecordParamSetPathInfoRename<'a> {
     pub newname: &'a[u8],
 }
 
-named!(pub parse_trans2_request_data_set_path_info_rename<Trans2RecordParamSetPathInfoRename>,
-    do_parse!(
-            replace: le_u8
-        >>  _reserved: take!(3)
-        >>  _root_dir: take!(4)
-        >>  newname_len: le_u32
-        >>  newname: take!(newname_len)
-        >> (Trans2RecordParamSetPathInfoRename {
-                replace: replace==1,
-                newname
-            })
-));
+pub fn parse_trans2_request_data_set_path_info_rename(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetPathInfoRename> {
+    let (i, replace) = le_u8(i)?;
+    let (i, _reserved) = take(3_usize)(i)?;
+    let (i, _root_dir) = take(4_usize)(i)?;
+    let (i, newname_len) = le_u32(i)?;
+    let (i, newname) = take(newname_len)(i)?;
+    let record = Trans2RecordParamSetPathInfoRename {
+        replace: replace==1,
+        newname
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRequestTrans2Record<'a> {
@@ -677,38 +687,41 @@ pub struct SmbRequestTrans2Record<'a> {
     pub data_blob: &'a[u8],
 }
 
-named!(pub parse_smb_trans2_request_record<SmbRequestTrans2Record>,
-    do_parse!(
-            _wct: le_u8
-        >>  _total_param_cnt: le_u16
-        >>  _total_data_cnt: le_u16
-        >>  _max_param_cnt: le_u16
-        >>  _max_data_cnt: le_u16
-        >>  _max_setup_cnt: le_u8
-        >>  _reserved1: take!(1)
-        >>  _flags: le_u16
-        >>  _timeout: le_u32
-        >>  _reserved2: take!(2)
-        >>  param_cnt: le_u16
-        >>  param_offset: le_u16
-        >>  data_cnt: le_u16
-        >>  data_offset: le_u16
-        >>  _setup_cnt: le_u8
-        >>  _reserved3: take!(1)
-        >>  subcmd: le_u16
-        >>  _bcc: le_u16
-        //TODO test and use param_offset
-        >>  _padding: take!(3)
-        >>  setup_blob: take!(param_cnt)
-        >>  _padding2: cond!(data_offset > param_offset + param_cnt, take!(data_offset - param_offset - param_cnt))
-        >>  data_blob: take!(data_cnt)
-
-        >> (SmbRequestTrans2Record {
-                subcmd,
-                setup_blob,
-                data_blob
-           }))
-);
+pub fn parse_smb_trans2_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestTrans2Record> {
+    let (i, _wct) = le_u8(i)?;
+    let (i, _total_param_cnt) = le_u16(i)?;
+    let (i, _total_data_cnt) = le_u16(i)?;
+    let (i, _max_param_cnt) = le_u16(i)?;
+    let (i, _max_data_cnt) = le_u16(i)?;
+    let (i, _max_setup_cnt) = le_u8(i)?;
+    let (i, _reserved1) = take(1_usize)(i)?;
+    let (i, _flags) = le_u16(i)?;
+    let (i, _timeout) = le_u32(i)?;
+    let (i, _reserved2) = take(2_usize)(i)?;
+    let (i, param_cnt) = le_u16(i)?;
+    let (i, param_offset) = le_u16(i)?;
+    let (i, data_cnt) = le_u16(i)?;
+    let (i, data_offset) = le_u16(i)?;
+    let (i, _setup_cnt) = le_u8(i)?;
+    let (i, _reserved3) = take(1_usize)(i)?;
+    let (i, subcmd) = le_u16(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    //TODO test and use param_offset
+    let (i, _padding) = take(3_usize)(i)?;
+    let (i, setup_blob) = take(param_cnt)(i)?;
+    let (i, _padding2) = cond(
+        data_offset > param_offset + param_cnt,
+        |b| take(data_offset - param_offset - param_cnt)(b)
+    )(i)?;
+    let (i, data_blob) = take(data_cnt)(i)?;
+
+    let record = SmbRequestTrans2Record {
+        subcmd,
+        setup_blob,
+        data_blob
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbResponseCreateAndXRecord<'a> {
@@ -720,36 +733,36 @@ pub struct SmbResponseCreateAndXRecord<'a> {
     pub file_size: u64,
 }
 
-named!(pub parse_smb_create_andx_response_record<SmbResponseCreateAndXRecord>,
-    do_parse!(
-            wct: le_u8
-        >>  _andx_command: le_u8
-        >>  take!(1)    // reserved
-        >>  _andx_offset: le_u16
-        >>  _oplock_level: le_u8
-        >>  fid: take!(2)
-        >>  _create_action: le_u32
-        >>  create_ts: le_u64
-        >>  last_access_ts: le_u64
-        >>  last_write_ts: le_u64
-        >>  last_change_ts: le_u64
-        >>  take!(4)
-        >>  file_size: le_u64
-        >>  _eof: le_u64
-        >>  _file_type: le_u16
-        >>  _ipc_state: le_u16
-        >>  _is_dir: le_u8
-        >>  cond!(wct == 42, take!(32))
-        >>  _bcc: le_u16
-        >> (SmbResponseCreateAndXRecord {
-                fid:fid,
-                create_ts: SMBFiletime::new(create_ts),
-                last_access_ts: SMBFiletime::new(last_access_ts),
-                last_write_ts: SMBFiletime::new(last_write_ts),
-                last_change_ts: SMBFiletime::new(last_change_ts),
-                file_size:file_size,
-           }))
-);
+pub fn parse_smb_create_andx_response_record(i: &[u8]) -> IResult<&[u8], SmbResponseCreateAndXRecord> {
+    let (i, wct) = le_u8(i)?;
+    let (i, _andx_command) = le_u8(i)?;
+    let (i, _) = take(1_usize)(i)?; // reserved
+    let (i, _andx_offset) = le_u16(i)?;
+    let (i, _oplock_level) = le_u8(i)?;
+    let (i, fid) = take(2_usize)(i)?;
+    let (i, _create_action) = le_u32(i)?;
+    let (i, create_ts) = le_u64(i)?;
+    let (i, last_access_ts) = le_u64(i)?;
+    let (i, last_write_ts) = le_u64(i)?;
+    let (i, last_change_ts) = le_u64(i)?;
+    let (i, _) = take(4_usize)(i)?;
+    let (i, file_size) = le_u64(i)?;
+    let (i, _eof) = le_u64(i)?;
+    let (i, _file_type) = le_u16(i)?;
+    let (i, _ipc_state) = le_u16(i)?;
+    let (i, _is_dir) = le_u8(i)?;
+    let (i, _) = cond(wct == 42, take(32_usize))(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    let record = SmbResponseCreateAndXRecord {
+        fid,
+        create_ts: SMBFiletime::new(create_ts),
+        last_access_ts: SMBFiletime::new(last_access_ts),
+        last_write_ts: SMBFiletime::new(last_write_ts),
+        last_change_ts: SMBFiletime::new(last_change_ts),
+        file_size,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRequestCloseRecord<'a> {
@@ -770,14 +783,12 @@ pub struct SmbVersion<> {
     pub version: u8,
 }
 
-named!(pub parse_smb_version<SmbVersion>,
-    do_parse!(
-        version: le_u8
-        >> tag!("SMB")
-        >> (SmbVersion {
-                version:version,
-            }))
-);
+pub fn parse_smb_version(i: &[u8]) -> IResult<&[u8], SmbVersion> {
+    let (i, version) = le_u8(i)?;
+    let (i, _) = tag(b"SMB")(i)?;
+    let version = SmbVersion { version };
+    Ok((i, version))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbRecord<'a> {
@@ -806,35 +817,35 @@ impl<'a> SmbRecord<'a> {
     }
 }
 
-named!(pub parse_smb_record<SmbRecord>,
-    do_parse!(
-            tag!(b"\xffSMB")
-        >>  command:le_u8
-        >>  nt_status:le_u32
-        >>  flags:le_u8
-        >>  flags2:le_u16
-        >>  process_id_high:le_u16
-        >>  _signature:take!(8)
-        >>  _reserved:take!(2)
-        >>  tree_id:le_u16
-        >>  process_id:le_u16
-        >>  user_id:le_u16
-        >>  multiplex_id:le_u16
-        >>  data: rest
-
-        >>  (SmbRecord {
-                command:command,
-                nt_status:nt_status,
-                flags:flags,
-                flags2:flags2,
-                is_dos_error: (flags2 & 0x4000_u16 == 0),// && nt_status != 0),
-                tree_id:tree_id,
-                user_id:user_id,
-                multiplex_id:multiplex_id,
-
-                process_id: (process_id_high as u32) << 16 | process_id as u32,
-                //ssn_id: (((process_id as u32)<< 16)|(user_id as u32)),
-                ssn_id: user_id as u32,
-                data:data,
-            })
-));
+pub fn parse_smb_record(i: &[u8]) -> IResult<&[u8], SmbRecord> {
+    let (i, _) = tag(b"\xffSMB")(i)?;
+    let (i, command) = le_u8(i)?;
+    let (i, nt_status) = le_u32(i)?;
+    let (i, flags) = le_u8(i)?;
+    let (i, flags2) = le_u16(i)?;
+    let (i, process_id_high) = le_u16(i)?;
+    let (i, _signature) = take(8_usize)(i)?;
+    let (i, _reserved) = take(2_usize)(i)?;
+    let (i, tree_id) = le_u16(i)?;
+    let (i, process_id) = le_u16(i)?;
+    let (i, user_id) = le_u16(i)?;
+    let (i, multiplex_id) = le_u16(i)?;
+    let (i, data) = rest(i)?;
+
+    let record = SmbRecord {
+        command,
+        nt_status,
+        flags,
+        flags2,
+        is_dos_error: (flags2 & 0x4000_u16 == 0),// && nt_status != 0),
+        tree_id,
+        user_id,
+        multiplex_id,
+
+        process_id: (process_id_high as u32) << 16 | process_id as u32,
+        //ssn_id: (((process_id as u32)<< 16)|(user_id as u32)),
+        ssn_id: user_id as u32,
+        data,
+    };
+    Ok((i, record))
+}
index 6080075d3669cf7af61421f09f975fc9dcba6b8d..1ee2248448e8ef4de7822c283ab782859255ab12 100644 (file)
@@ -15,9 +15,9 @@
  * 02110-1301, USA.
  */
 
+use crate::common::nom7::take_until_and_consume;
 use crate::smb::error::SmbError;
-use nom;
-use nom::IResult;
+use nom7::{Err, IResult};
 
 /// parse a UTF16 string that is null terminated. Normally by 2 null
 /// bytes, but at the end of the data it can also be a single null.
@@ -42,13 +42,12 @@ pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError>
         name.push(c[0]);
         c = &c[2..];
     }
-    Err(nom::Err::Error(SmbError::BadEncoding))
+    Err(Err::Error(SmbError::BadEncoding))
 }
 
 // parse an ASCII string that is null terminated
-named!(pub smb_get_ascii_string<&[u8], Vec<u8>, SmbError>,
-    do_parse!(
-            s: take_until_and_consume!("\x00")
-        >> ( s.to_vec() )
-));
+pub fn smb_get_ascii_string(i: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError> {
+    let (i, s) = take_until_and_consume(b"\x00")(i)?;
+    Ok((i, s.to_vec()))
+}