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

index 271428f3d6f13b8decd6041457ebc1c5e2447c38..e85906d8d3f95b38b958150a8e5759dac255d6a5 100644 (file)
@@ -15,7 +15,7 @@
  * 02110-1301, USA.
  */
 
-use nom;
+use nom7::Err;
 
 use crate::core::*;
 
@@ -392,13 +392,13 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
                         _ => false,
                     }
                 },
-                Err(nom::Err::Incomplete(_n)) => {
+                Err(Err::Incomplete(_n)) => {
                     SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", _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!("SMB2_COMMAND_SET_INFO: {:?}", _e);
                     events.push(SMBEvent::MalformedData);
                     false
index 01ffc5d77a264bba660705ddbee3d75cb397e158..c892faad477fcb60a1037c61f417bafbb2e1ad2c 100644 (file)
  * 02110-1301, USA.
  */
 
-use nom;
-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::nbss_records::NBSS_MSGTYPE_SESSION_MESSAGE;
+use nom7::bits::{bits, streaming::take as take_bits};
+use nom7::bytes::streaming::{tag, take};
+use nom7::combinator::{cond, map_parser, rest};
+use nom7::error::{make_error, Error, ErrorKind};
+use nom7::multi::count;
+use nom7::number::streaming::{le_u8, le_u16, le_u32, le_u64};
+use nom7::sequence::tuple;
+use nom7::{Err, IResult, Needed};
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2SecBlobRecord<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb2_sec_blob<Smb2SecBlobRecord>,
-    do_parse!(
-         data: rest
-         >> ( Smb2SecBlobRecord {
-                data: data,
-            })
-));
+pub fn parse_smb2_sec_blob(i: &[u8]) -> IResult<&[u8], Smb2SecBlobRecord> {
+    let (i, data) = rest(i)?;
+    Ok((i, Smb2SecBlobRecord { data }))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2RecordDir<> {
     pub request: bool,
 }
 
-named!(pub parse_smb2_record_direction<Smb2RecordDir>,
-    do_parse!(
-            _server_component: tag!(b"\xfeSMB")
-        >>  _skip: take!(12)
-        >>  flags: le_u8
-        >> (Smb2RecordDir {
-                request: flags & 0x01 == 0,
-           })
-));
+pub fn parse_smb2_record_direction(i: &[u8]) -> IResult<&[u8], Smb2RecordDir> {
+    let (i, _server_component) = tag(b"\xfeSMB")(i)?;
+    let (i, _skip) = take(12_usize)(i)?;
+    let (i, flags) = le_u8(i)?;
+    let record = Smb2RecordDir {
+        request: flags & 0x01 == 0,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2Record<'a> {
@@ -69,49 +70,50 @@ 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<Smb2Record>,
-    do_parse!(
-            _server_component: tag!(b"\xfeSMB")
-        >>  hlen: le_u16
-        >>  _credit_charge: le_u16
-        >>  _channel_seq: le_u16
-        >>  _reserved: take!(2)
-        >>  command: le_u16
-        >>  _credits_requested: le_u16
-        >>  flags: parse_smb2_request_flags
-        >> chain_offset: le_u32
-        >> message_id: le_u64
-        >> _process_id: le_u32
-        >> tree_id: le_u32
-        >> session_id: le_u64
-        >> _signature: take!(16)
-        // there is probably a cleaner way to do this
-        >> data_c: cond!(chain_offset > hlen as u32, take!(chain_offset - hlen as u32))
-        >> data_r: cond!(chain_offset <= hlen as u32, rest)
-        >> (Smb2Record {
-                direction: flags.7,
-                nt_status: 0,
-                command:command,
-                message_id: message_id,
-                tree_id: tree_id,
-                async_id: 0,
-                session_id: session_id,
-                data: if data_c != None { data_c.unwrap() } else { data_r.unwrap() }
-           })
-));
+    bits::<_, _, Error<(&[u8], usize)>, _, _>(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
+    )))(i)
+}
+
+pub fn parse_smb2_request_record(i: &[u8]) -> IResult<&[u8], Smb2Record> {
+    let (i, _server_component) = tag(b"\xfeSMB")(i)?;
+    let (i, hlen) = le_u16(i)?;
+    let (i, _credit_charge) = le_u16(i)?;
+    let (i, _channel_seq) = le_u16(i)?;
+    let (i, _reserved) = take(2_usize)(i)?;
+    let (i, command) = le_u16(i)?;
+    let (i, _credits_requested) = le_u16(i)?;
+    let (i, flags) = parse_smb2_request_flags(i)?;
+    let (i, chain_offset) = le_u32(i)?;
+    let (i, message_id) = le_u64(i)?;
+    let (i, _process_id) = le_u32(i)?;
+    let (i, tree_id) = le_u32(i)?;
+    let (i, session_id) = le_u64(i)?;
+    let (i, _signature) = take(16_usize)(i)?;
+    let (i, data) = if chain_offset > hlen as u32 {
+        take(chain_offset - hlen as u32)(i)?
+    } else {
+        rest(i)?
+    };
+    let record = Smb2Record {
+        direction: flags.7,
+        nt_status: 0,
+        command,
+        message_id,
+        tree_id,
+        async_id: 0,
+        session_id,
+        data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2NegotiateProtocolRequestRecord<'a> {
@@ -119,23 +121,23 @@ pub struct Smb2NegotiateProtocolRequestRecord<'a> {
     pub client_guid: &'a[u8],
 }
 
-named!(pub parse_smb2_request_negotiate_protocol<Smb2NegotiateProtocolRequestRecord>,
-    do_parse!(
-            _struct_size: take!(2)
-        >>  dialects_count: le_u16
-        >>  _sec_mode: le_u16
-        >>  _reserved1: le_u16
-        >>  _capabilities: le_u32
-        >>  client_guid: take!(16)
-        >>  _ctx_offset: le_u32
-        >>  _ctx_cnt: le_u16
-        >>  _reserved2: le_u16
-        >>  dia_vec: count!(le_u16, dialects_count as usize)
-        >>  (Smb2NegotiateProtocolRequestRecord {
-                dialects_vec: dia_vec,
-                client_guid: client_guid,
-            })
-));
+pub fn parse_smb2_request_negotiate_protocol(i: &[u8]) -> IResult<&[u8], Smb2NegotiateProtocolRequestRecord> {
+    let (i, _struct_size) = take(2_usize)(i)?;
+    let (i, dialects_count) = le_u16(i)?;
+    let (i, _sec_mode) = le_u16(i)?;
+    let (i, _reserved1) = le_u16(i)?;
+    let (i, _capabilities) = le_u32(i)?;
+    let (i, client_guid) = take(16_usize)(i)?;
+    let (i, _ctx_offset) = le_u32(i)?;
+    let (i, _ctx_cnt) = le_u16(i)?;
+    let (i, _reserved2) = le_u16(i)?;
+    let (i, dia_vec) = count(le_u16, dialects_count as usize)(i)?;
+    let record = Smb2NegotiateProtocolRequestRecord {
+        dialects_vec: dia_vec,
+        client_guid,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2NegotiateProtocolResponseRecord<'a> {
@@ -143,28 +145,28 @@ pub struct Smb2NegotiateProtocolResponseRecord<'a> {
     pub server_guid: &'a[u8],
 }
 
-named!(pub parse_smb2_response_negotiate_protocol<Smb2NegotiateProtocolResponseRecord>,
-    do_parse!(
-            _struct_size: take!(2)
-        >>  _skip1: take!(2)
-        >>  dialect: le_u16
-        >>  _ctx_cnt: le_u16
-        >>  server_guid: take!(16)
-        >>  (Smb2NegotiateProtocolResponseRecord {
-                dialect,
-                server_guid
-            })
-));
-
-named!(pub parse_smb2_response_negotiate_protocol_error<Smb2NegotiateProtocolResponseRecord>,
-    do_parse!(
-            _struct_size: take!(2)
-        >>  _skip1: take!(2)
-        >>  (Smb2NegotiateProtocolResponseRecord {
-                dialect: 0,
-                server_guid: &[],
-            })
-));
+pub fn parse_smb2_response_negotiate_protocol(i: &[u8]) -> IResult<&[u8], Smb2NegotiateProtocolResponseRecord> {
+    let (i, _struct_size) = take(2_usize)(i)?;
+    let (i, _skip1) = take(2_usize)(i)?;
+    let (i, dialect) = le_u16(i)?;
+    let (i, _ctx_cnt) = le_u16(i)?;
+    let (i, server_guid) = take(16_usize)(i)?;
+    let record = Smb2NegotiateProtocolResponseRecord {
+        dialect,
+        server_guid
+    };
+    Ok((i, record))
+}
+
+pub fn parse_smb2_response_negotiate_protocol_error(i: &[u8]) -> IResult<&[u8], Smb2NegotiateProtocolResponseRecord> {
+    let (i, _struct_size) = take(2_usize)(i)?;
+    let (i, _skip1) = take(2_usize)(i)?;
+    let record = Smb2NegotiateProtocolResponseRecord {
+        dialect: 0,
+        server_guid: &[],
+    };
+    Ok((i, record))
+}
 
 
 #[derive(Debug,PartialEq)]
@@ -172,55 +174,49 @@ pub struct Smb2SessionSetupRequestRecord<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb2_request_session_setup<Smb2SessionSetupRequestRecord>,
-    do_parse!(
-            _struct_size: take!(2)
-        >>  _flags: le_u8
-        >>  _security_mode: le_u8
-        >>  _capabilities: le_u32
-        >>  _channel: le_u32
-        >>  _sec_offset: le_u16
-        >>  _sec_len: le_u16
-        >>  _prev_ssn_id: take!(8)
-        >>  data: rest
-        >>  (Smb2SessionSetupRequestRecord {
-                data:data,
-            })
-));
-
+pub fn parse_smb2_request_session_setup(i: &[u8]) -> IResult<&[u8], Smb2SessionSetupRequestRecord> {
+    let (i, _struct_size) = take(2_usize)(i)?;
+    let (i, _flags) = le_u8(i)?;
+    let (i, _security_mode) = le_u8(i)?;
+    let (i, _capabilities) = le_u32(i)?;
+    let (i, _channel) = le_u32(i)?;
+    let (i, _sec_offset) = le_u16(i)?;
+    let (i, _sec_len) = le_u16(i)?;
+    let (i, _prev_ssn_id) = take(8_usize)(i)?;
+    let (i, data) = rest(i)?;
+    let record = Smb2SessionSetupRequestRecord { data };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2TreeConnectRequestRecord<'a> {
     pub share_name: &'a[u8],
 }
 
-named!(pub parse_smb2_request_tree_connect<Smb2TreeConnectRequestRecord>,
-    do_parse!(
-            _struct_size: take!(2)
-        >>  _offset_length: take!(4)
-        >>  data: rest
-        >>  (Smb2TreeConnectRequestRecord {
-                share_name:data,
-            })
-));
+pub fn parse_smb2_request_tree_connect(i: &[u8]) -> IResult<&[u8], Smb2TreeConnectRequestRecord> {
+    let (i, _struct_size) = take(2_usize)(i)?;
+    let (i, _offset_length) = take(4_usize)(i)?;
+    let (i, data) = rest(i)?;
+    let record = Smb2TreeConnectRequestRecord {
+        share_name:data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2TreeConnectResponseRecord<> {
     pub share_type: u8,
 }
 
-named!(pub parse_smb2_response_tree_connect<Smb2TreeConnectResponseRecord>,
-    do_parse!(
-            _struct_size: take!(2)
-        >>  share_type: le_u8
-        >>  _share_flags: le_u32
-        >>  _share_caps: le_u32
-        >>  _access_mask: le_u32
-        >>  (Smb2TreeConnectResponseRecord {
-                share_type
-            })
-));
-
+pub fn parse_smb2_response_tree_connect(i: &[u8]) -> IResult<&[u8], Smb2TreeConnectResponseRecord> {
+    let (i, _struct_size) = take(2_usize)(i)?;
+    let (i, share_type) = le_u8(i)?;
+    let (i, _share_flags) = le_u32(i)?;
+    let (i, _share_caps) = le_u32(i)?;
+    let (i, _access_mask) = le_u32(i)?;
+    let record = Smb2TreeConnectResponseRecord { share_type };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2CreateRequestRecord<'a> {
@@ -229,22 +225,22 @@ pub struct Smb2CreateRequestRecord<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb2_request_create<Smb2CreateRequestRecord>,
-    do_parse!(
-            _skip1: take!(36)
-        >>  disposition: le_u32
-        >>  create_options: le_u32
-        >>  _file_name_offset: le_u16
-        >>  file_name_length: le_u16
-        >>  _skip2: take!(8)
-        >>  data: take!(file_name_length)
-        >>  _skip3: rest
-        >>  (Smb2CreateRequestRecord {
-                disposition,
-                create_options,
-                data
-            })
-));
+pub fn parse_smb2_request_create(i: &[u8]) -> IResult<&[u8], Smb2CreateRequestRecord> {
+    let (i, _skip1) = take(36_usize)(i)?;
+    let (i, disposition) = le_u32(i)?;
+    let (i, create_options) = le_u32(i)?;
+    let (i, _file_name_offset) = le_u16(i)?;
+    let (i, file_name_length) = le_u16(i)?;
+    let (i, _skip2) = take(8_usize)(i)?;
+    let (i, data) = take(file_name_length)(i)?;
+    let (i, _skip3) = rest(i)?;
+    let record = Smb2CreateRequestRecord {
+        disposition,
+        create_options,
+        data
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2IOCtlRequestRecord<'a> {
@@ -254,26 +250,26 @@ pub struct Smb2IOCtlRequestRecord<'a> {
     pub data: &'a[u8],
 }
 
-named!(pub parse_smb2_request_ioctl<Smb2IOCtlRequestRecord>,
-    do_parse!(
-            _skip: take!(2)  // structure size
-        >>  take!(2)        // reserved
-        >>  func: le_u32
-        >>  guid: take!(16)
-        >>  _indata_offset: le_u32
-        >>  indata_len: le_u32
-        >>  take!(4)
-        >>  _outdata_offset: le_u32
-        >>  _outdata_len: le_u32
-        >>  take!(12)
-        >>  data: take!(indata_len)
-        >>  (Smb2IOCtlRequestRecord {
-                is_pipe: (func == 0x0011c017),
-                function: func,
-                guid:guid,
-                data:data,
-            })
-));
+pub fn parse_smb2_request_ioctl(i: &[u8]) -> IResult<&[u8], Smb2IOCtlRequestRecord> {
+    let (i, _skip) = take(2_usize)  (i)?;// structure size
+    let (i, _) = take(2_usize)        (i)?;// reserved
+    let (i, func) = le_u32(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let (i, _indata_offset) = le_u32(i)?;
+    let (i, indata_len) = le_u32(i)?;
+    let (i, _) = take(4_usize)(i)?;
+    let (i, _outdata_offset) = le_u32(i)?;
+    let (i, _outdata_len) = le_u32(i)?;
+    let (i, _) = take(12_usize)(i)?;
+    let (i, data) = take(indata_len)(i)?;
+    let record = Smb2IOCtlRequestRecord {
+        is_pipe: (func == 0x0011c017),
+        function: func,
+        guid,
+        data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2IOCtlResponseRecord<'a> {
@@ -286,73 +282,69 @@ pub struct Smb2IOCtlResponseRecord<'a> {
     pub outdata_offset: u32,
 }
 
-named!(pub parse_smb2_response_ioctl<Smb2IOCtlResponseRecord>,
-    do_parse!(
-            _skip: take!(2)  // structure size
-        >>  take!(2)        // reserved
-        >>  func: le_u32
-        >>  guid: take!(16)
-        >>  indata_offset: le_u32
-        >>  indata_len: le_u32
-        >>  outdata_offset: le_u32
-        >>  outdata_len: le_u32
-        >>  take!(8)
-        >>  take!(indata_len)
-        >>  data: take!(outdata_len)
-        >>  (Smb2IOCtlResponseRecord {
-                is_pipe: (func == 0x0011c017),
-                guid:guid,
-                data:data,
-                indata_len:indata_len,
-                outdata_len:outdata_len,
-                indata_offset:indata_offset,
-                outdata_offset:outdata_offset,
-            })
-));
+pub fn parse_smb2_response_ioctl(i: &[u8]) -> IResult<&[u8], Smb2IOCtlResponseRecord> {
+    let (i, _skip) = take(2_usize)(i)?; // structure size
+    let (i, _) = take(2_usize)(i)?; // reserved
+    let (i, func) = le_u32(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let (i, indata_offset) = le_u32(i)?;
+    let (i, indata_len) = le_u32(i)?;
+    let (i, outdata_offset) = le_u32(i)?;
+    let (i, outdata_len) = le_u32(i)?;
+    let (i, _) = take(8_usize)(i)?;
+    let (i, _) = take(indata_len)(i)?;
+    let (i, data) = take(outdata_len)(i)?;
+    let record = Smb2IOCtlResponseRecord {
+        is_pipe: (func == 0x0011c017),
+        guid,
+        data,
+        indata_len,
+        outdata_len,
+        indata_offset,
+        outdata_offset,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2CloseRequestRecord<'a> {
     pub guid: &'a[u8],
 }
 
-named!(pub parse_smb2_request_close<Smb2CloseRequestRecord>,
-    do_parse!(
-            _skip: take!(8)
-        >>  guid: take!(16)
-        >>  (Smb2CloseRequestRecord {
-                guid
-            })
-));
+pub fn parse_smb2_request_close(i: &[u8]) -> IResult<&[u8], Smb2CloseRequestRecord> {
+    let (i, _skip) = take(8_usize)(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let record = Smb2CloseRequestRecord { guid };
+    Ok((i, record))
+}
 
 #[derive(Debug)]
 pub struct Smb2SetInfoRequestRenameRecord<'a> {
     pub name: &'a[u8],
 }
 
-named!(pub parse_smb2_request_setinfo_rename<Smb2SetInfoRequestData>,
-    do_parse!(
-            _replace: le_u8
-        >>  _reserved: take!(7)
-        >>  _root_handle: take!(8)
-        >>  name_len: le_u32
-        >>  name: take!(name_len)
-        >> (Smb2SetInfoRequestData::RENAME(Smb2SetInfoRequestRenameRecord {
-                name
-            }))
-));
+pub fn parse_smb2_request_setinfo_rename(i: &[u8]) -> IResult<&[u8], Smb2SetInfoRequestData> {
+    let (i, _replace) = le_u8(i)?;
+    let (i, _reserved) = take(7_usize)(i)?;
+    let (i, _root_handle) = take(8_usize)(i)?;
+    let (i, name_len) = le_u32(i)?;
+    let (i, name) = take(name_len)(i)?;
+    let record = Smb2SetInfoRequestData::RENAME(Smb2SetInfoRequestRenameRecord { name });
+    Ok((i, record))
+}
 
 #[derive(Debug)]
 pub struct Smb2SetInfoRequestDispoRecord {
     pub delete: bool,
 }
 
-named!(pub parse_smb2_request_setinfo_disposition<&[u8], Smb2SetInfoRequestData>,
-    do_parse!(
-        info: le_u8 >>
-        (Smb2SetInfoRequestData::DISPOSITION(Smb2SetInfoRequestDispoRecord {
-                delete: info & 1 != 0,
-            }))
-));
+pub fn parse_smb2_request_setinfo_disposition(i: &[u8]) -> IResult<&[u8], Smb2SetInfoRequestData> {
+    let (i, info) = le_u8(i)?;
+    let record = Smb2SetInfoRequestData::DISPOSITION(Smb2SetInfoRequestDispoRecord {
+        delete: info & 1 != 0,
+    });
+    Ok((i, record))
+}
 
 #[derive(Debug)]
 pub enum Smb2SetInfoRequestData<'a> {
@@ -387,24 +379,27 @@ fn parse_smb2_request_setinfo_data(
     return Ok((i, Smb2SetInfoRequestData::UNHANDLED));
 }
 
-named!(pub parse_smb2_request_setinfo<Smb2SetInfoRequestRecord>,
-    do_parse!(
-            _struct_size: le_u16
-        >>  class: le_u8
-        >>  infolvl: le_u8
-        >>  setinfo_size: le_u32
-        >>  _setinfo_offset: le_u16
-        >>  _reserved: take!(2)
-        >>  _additional_info: le_u32
-        >>  guid: take!(16)
-        >>  data: flat_map!(take!(setinfo_size), call!(parse_smb2_request_setinfo_data, class, infolvl))
-        >> (Smb2SetInfoRequestRecord {
-                guid: guid,
-                class: class,
-                infolvl: infolvl,
-                data: data,
-            })
-));
+pub fn parse_smb2_request_setinfo(i: &[u8]) -> IResult<&[u8], Smb2SetInfoRequestRecord> {
+    let (i, _struct_size) = le_u16(i)?;
+    let (i, class) = le_u8(i)?;
+    let (i, infolvl) = le_u8(i)?;
+    let (i, setinfo_size) = le_u32(i)?;
+    let (i, _setinfo_offset) = le_u16(i)?;
+    let (i, _reserved) = take(2_usize)(i)?;
+    let (i, _additional_info) = le_u32(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let (i, data) = map_parser(
+        take(setinfo_size),
+        |b| parse_smb2_request_setinfo_data(b, class, infolvl)
+    )(i)?;
+    let record = Smb2SetInfoRequestRecord {
+        guid,
+        class,
+        infolvl,
+        data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2WriteRequestRecord<'a> {
@@ -415,24 +410,24 @@ pub struct Smb2WriteRequestRecord<'a> {
 }
 
 // can be called on incomplete records
-named!(pub parse_smb2_request_write<Smb2WriteRequestRecord>,
-    do_parse!(
-            _skip1: take!(4)
-        >>  wr_len: le_u32
-        >>  wr_offset: le_u64
-        >>  guid: take!(16)
-        >>  _channel: le_u32
-        >>  _remaining_bytes: le_u32
-        >>  _write_flags: le_u32
-        >>  _skip2: take!(4)
-        >>  data: call!(parse_smb2_data, wr_len)
-        >>  (Smb2WriteRequestRecord {
-                wr_len:wr_len,
-                wr_offset:wr_offset,
-                guid:guid,
-                data:data,
-            })
-));
+pub fn parse_smb2_request_write(i: &[u8]) -> IResult<&[u8], Smb2WriteRequestRecord> {
+    let (i, _skip1) = take(4_usize)(i)?;
+    let (i, wr_len) = le_u32(i)?;
+    let (i, wr_offset) = le_u64(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let (i, _channel) = le_u32(i)?;
+    let (i, _remaining_bytes) = le_u32(i)?;
+    let (i, _write_flags) = le_u32(i)?;
+    let (i, _skip2) = take(4_usize)(i)?;
+    let (i, data) = parse_smb2_data(i, wr_len)?;
+    let record = Smb2WriteRequestRecord {
+        wr_len,
+        wr_offset,
+        guid,
+        data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2ReadRequestRecord<'a> {
@@ -441,22 +436,22 @@ pub struct Smb2ReadRequestRecord<'a> {
     pub guid: &'a[u8],
 }
 
-named!(pub parse_smb2_request_read<Smb2ReadRequestRecord>,
-    do_parse!(
-            _skip1: take!(4)
-        >>  rd_len: le_u32
-        >>  rd_offset: le_u64
-        >>  guid: take!(16)
-        >>  _min_count: le_u32
-        >>  _channel: le_u32
-        >>  _remaining_bytes: le_u32
-        >>  _skip2: take!(4)
-        >>  (Smb2ReadRequestRecord {
-                rd_len:rd_len,
-                rd_offset:rd_offset,
-                guid:guid,
-            })
-));
+pub fn parse_smb2_request_read(i: &[u8]) -> IResult<&[u8], Smb2ReadRequestRecord> {
+    let (i, _skip1) = take(4_usize)(i)?;
+    let (i, rd_len) = le_u32(i)?;
+    let (i, rd_offset) = le_u64(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let (i, _min_count) = le_u32(i)?;
+    let (i, _channel) = le_u32(i)?;
+    let (i, _remaining_bytes) = le_u32(i)?;
+    let (i, _skip2) = take(4_usize)(i)?;
+    let record = Smb2ReadRequestRecord {
+        rd_len,
+        rd_offset,
+        guid,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2ReadResponseRecord<'a> {
@@ -473,24 +468,24 @@ fn parse_smb2_data<'a>(i: &'a[u8], len: u32)
     if len as usize > i.len() {
         rest(i)
     } else {
-        take!(i, len)
+        take(len)(i)
     }
 }
 
 // can be called on incomplete records
-named!(pub parse_smb2_response_read<Smb2ReadResponseRecord>,
-    do_parse!(
-            _struct_size: le_u16
-        >>  _data_offset: le_u16
-        >>  rd_len: le_u32
-        >>  _rd_rem: le_u32
-        >>  _padding: take!(4)
-        >>  data: call!(parse_smb2_data, rd_len)
-        >>  (Smb2ReadResponseRecord {
-                len : rd_len,
-                data : data,
-            })
-));
+pub fn parse_smb2_response_read(i: &[u8]) -> IResult<&[u8], Smb2ReadResponseRecord> {
+    let (i, _struct_size) = le_u16(i)?;
+    let (i, _data_offset) = le_u16(i)?;
+    let (i, rd_len) = le_u32(i)?;
+    let (i, _rd_rem) = le_u32(i)?;
+    let (i, _padding) = take(4_usize)(i)?;
+    let (i, data) = parse_smb2_data(i, rd_len)?;
+    let record = Smb2ReadResponseRecord {
+        len: rd_len,
+        data,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2CreateResponseRecord<'a> {
@@ -502,77 +497,77 @@ pub struct Smb2CreateResponseRecord<'a> {
     pub size: u64,
 }
 
-named!(pub parse_smb2_response_create<Smb2CreateResponseRecord>,
-    do_parse!(
-            _ssize: le_u16
-        >>  _oplock: le_u8
-        >>  _resp_flags: le_u8
-        >>  _create_action: le_u32
-        >>  create_ts: le_u64
-        >>  last_access_ts: le_u64
-        >>  last_write_ts: le_u64
-        >>  last_change_ts: le_u64
-        >>  _alloc_size: le_u64
-        >>  eof: le_u64
-        >>  _attrs: le_u32
-        >>  _padding: take!(4)
-        >>  guid: take!(16)
-        >>  _skip2: take!(8)
-        >>  (Smb2CreateResponseRecord {
-                guid : guid,
-                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),
-                size: eof,
-            })
-));
+pub fn parse_smb2_response_create(i: &[u8]) -> IResult<&[u8], Smb2CreateResponseRecord> {
+    let (i, _ssize) = le_u16(i)?;
+    let (i, _oplock) = le_u8(i)?;
+    let (i, _resp_flags) = le_u8(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, _alloc_size) = le_u64(i)?;
+    let (i, eof) = le_u64(i)?;
+    let (i, _attrs) = le_u32(i)?;
+    let (i, _padding) = take(4_usize)(i)?;
+    let (i, guid) = take(16_usize)(i)?;
+    let (i, _skip2) = take(8_usize)(i)?;
+    let record = Smb2CreateResponseRecord {
+        guid,
+        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),
+        size: eof,
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct Smb2WriteResponseRecord<> {
     pub wr_cnt: u32,
 }
 
-named!(pub parse_smb2_response_write<Smb2WriteResponseRecord>,
-    do_parse!(
-            _skip1: take!(4)
-        >>  wr_cnt: le_u32
-        >>  _skip2: take!(6)
-        >>  (Smb2WriteResponseRecord {
-                wr_cnt : wr_cnt,
-            })
-));
-
-named!(pub parse_smb2_response_record<Smb2Record>,
-    do_parse!(
-            tag!(b"\xfeSMB")
-        >>  hlen: le_u16
-        >>  _credit_charge: le_u16
-        >>  nt_status: le_u32
-        >>  command: le_u16
-        >>  _credit_granted: le_u16
-        >>  flags: parse_smb2_request_flags
-        >> chain_offset: le_u32
-        >> message_id: le_u64
-        >> _process_id: cond!(flags.6==0, le_u32)
-        >> tree_id: cond!(flags.6==0, le_u32)
-        >> async_id: cond!(flags.6==1, le_u64)
-        >> session_id: le_u64
-        >> _signature: take!(16)
-        // there is probably a cleaner way to do this
-        >> data_c: cond!(chain_offset > hlen as u32, take!(chain_offset - hlen as u32))
-        >> data_r: cond!(chain_offset <= hlen as u32, rest)
-        >> (Smb2Record {
-                direction: flags.7,
-                nt_status: nt_status,
-                message_id: message_id,
-                tree_id: tree_id.unwrap_or(0),
-                async_id: async_id.unwrap_or(0),
-                session_id: session_id,
-                command:command,
-                data: data_c.or(data_r).unwrap()
-           })
-));
+pub fn parse_smb2_response_write(i: &[u8]) -> IResult<&[u8], Smb2WriteResponseRecord> {
+    let (i, _skip1) = take(4_usize)(i)?;
+    let (i, wr_cnt) = le_u32(i)?;
+    let (i, _skip2) = take(6_usize)(i)?;
+    let record = Smb2WriteResponseRecord { wr_cnt };
+    Ok((i, record))
+}
+
+pub fn parse_smb2_response_record(i: &[u8]) -> IResult<&[u8], Smb2Record> {
+    let (i, _) = tag(b"\xfeSMB")(i)?;
+    let (i, hlen) = le_u16(i)?;
+    let (i, _credit_charge) = le_u16(i)?;
+    let (i, nt_status) = le_u32(i)?;
+    let (i, command) = le_u16(i)?;
+    let (i, _credit_granted) = le_u16(i)?;
+    let (i, flags) = parse_smb2_request_flags(i)?;
+    let (i, chain_offset) = le_u32(i)?;
+    let (i, message_id) = le_u64(i)?;
+    let (i, _process_id) = cond(flags.6 == 0, le_u32)(i)?;
+    let (i, tree_id) = cond(flags.6 == 0, le_u32)(i)?;
+    let (i, async_id) = cond(flags.6 == 1, le_u64)(i)?;
+    let (i, session_id) = le_u64(i)?;
+    let (i, _signature) = take(16_usize)(i)?;
+    let (i, data) = if chain_offset > hlen as u32 {
+        take(chain_offset - hlen as u32)(i)?
+    } else {
+        rest(i)?
+    };
+    let record = Smb2Record {
+        direction: flags.7,
+        nt_status,
+        message_id,
+        tree_id: tree_id.unwrap_or(0),
+        async_id: async_id.unwrap_or(0),
+        session_id,
+        command,
+        data,
+    };
+    Ok((i, record))
+}
 
 fn smb_basic_search(d: &[u8]) -> usize {
     let needle = b"SMB";
@@ -588,12 +583,12 @@ fn smb_basic_search(d: &[u8]) -> usize {
     return 0;
 }
 
-pub fn search_smb_record<'a>(i: &'a [u8]) -> nom::IResult<&'a [u8], &'a [u8]> {
+pub fn search_smb_record<'a>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8]> {
     let mut d = i;
     while d.len() >= 4 {
         let index = smb_basic_search(d);
         if index == 0 {
-            return Err(nom::Err::Error((d, nom::error::ErrorKind::Eof)));
+            return Err(Err::Error(make_error(d, ErrorKind::Eof)));
         }
         if d[index - 1] == 0xfe || d[index - 1] == 0xff || d[index - 1] == 0xfd {
             // if we have enough data, check nbss
@@ -603,5 +598,5 @@ pub fn search_smb_record<'a>(i: &'a [u8]) -> nom::IResult<&'a [u8], &'a [u8]> {
         }
         d = &d[index + 3..];
     }
-    Err(nom::Err::Incomplete(nom::Needed::Size(4 as usize - d.len())))
+    Err(Err::Incomplete(Needed::new(4 as usize - d.len())))
 }