use std;
use std::cmp;
-use std::collections::{HashMap};
+use std::collections::HashMap;
use std::ffi::{CStr, CString};
-use nom;
+use nom7::{Err, Needed};
use crate::applayer;
use crate::applayer::*;
impl NFSRequestXidMap {
pub fn new(progver: u32, procedure: u32, chunk_offset: u64) -> NFSRequestXidMap {
NFSRequestXidMap {
- progver:progver,
- procedure:procedure,
- chunk_offset:chunk_offset,
+ progver,
+ procedure,
+ chunk_offset,
file_name:Vec::new(),
file_handle:Vec::new(),
gssapi_proc: 0,
},
}
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
// we just size checked for the minimal record size above,
// so if options are used (creds/verifier), we can still
// have Incomplete data. Fall through to the buffer code
SCLogDebug!("TS data incomplete");
// fall through to the incomplete below
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
cur_i = &cur_i[rec_size..];
self.process_request_record(rpc_record);
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
// we shouldn't get incomplete as we have the full data
// bad.
self.set_event(NFSEvent::MalformedData);
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
},
}
},
- Err(nom::Err::Incomplete(needed)) => {
- if let nom::Needed::Size(n) = needed {
+ Err(Err::Incomplete(needed)) => {
+ if let Needed::Size(n) = needed {
SCLogDebug!("Not enough data for partial RPC header {:?}", needed);
// 28 is the partial RPC header size parse_rpc_request_partial
// looks for.
+ let n = usize::from(n);
let need = if n > 28 { n } else { 28 };
return AppLayerResult::incomplete((i.len() - cur_i.len()) as u32, need as u32);
}
return AppLayerResult::err();
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
self.process_partial_read_reply_record(rpc_record, nfs_reply_read);
cur_i = remaining; // progress input past parsed record
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
}
}
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
// size check was done for MINIMAL record size,
// so Incomplete is normal.
SCLogDebug!("TC data incomplete");
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
cur_i = &cur_i[rec_size..]; // progress input past parsed record
self.process_reply_record(rpc_record);
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
// we shouldn't get incomplete as we have the full data
// bad.
self.set_event(NFSEvent::MalformedData);
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
}
}
},
- Err(nom::Err::Incomplete(needed)) => {
- if let nom::Needed::Size(n) = needed {
+ Err(Err::Incomplete(needed)) => {
+ if let Needed::Size(n) = needed {
SCLogDebug!("Not enough data for partial RPC header {:?}", needed);
// 12 is the partial RPC header size parse_rpc_packet_header
// looks for.
+ let n = usize::from(n);
let need = if n > 12 { n } else { 12 };
return AppLayerResult::incomplete((i.len() - cur_i.len()) as u32, need as u32);
}
return AppLayerResult::err();
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return AppLayerResult::err();
_ => { },
}
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
SCLogDebug!("Parsing failed: {:?}", _e);
}
}
self.is_udp = true;
self.process_reply_record(rpc_record);
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
},
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ Err(Err::Error(_e)) |
+ Err(Err::Failure(_e)) => {
SCLogDebug!("Parsing failed: {:?}", _e);
}
}
unsafe { *rdir = dir as u8 };
return 1;
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
return 0;
},
Err(_) => {
return -1;
}
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
match parse_rpc_packet_header (i) {
Ok((_, ref rpc_hdr)) => {
if rpc_hdr.frag_len >= 24 && rpc_hdr.frag_len <= 35000 && rpc_hdr.xid != 0 && rpc_hdr.msgtype == 1 {
return -1;
}
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
return 0;
},
Err(_) => {
return -1;
}
},
- Err(nom::Err::Incomplete(_)) => {
+ Err(Err::Incomplete(_)) => {
return 0;
},
Err(_) => {
//! Nom parsers for RPC & NFSv3
-use nom::IResult;
-use nom::combinator::rest;
-use nom::number::streaming::{be_u32, be_u64};
use crate::nfs::nfs_records::*;
+use nom7::bytes::streaming::take;
+use nom7::combinator::{complete, cond, rest};
+use nom7::multi::{length_data, many0};
+use nom7::number::streaming::{be_u32, be_u64};
+use nom7::IResult;
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3Handle<'a> {
pub len: u32,
- pub value: &'a[u8],
+ pub value: &'a [u8],
}
-named!(pub parse_nfs3_handle<Nfs3Handle>,
- do_parse!(
- obj_len: be_u32
- >> obj: take!(obj_len)
- >> (
- Nfs3Handle {
- len:obj_len,
- value:obj,
- }
- ))
-);
+pub fn parse_nfs3_handle(i: &[u8]) -> IResult<&[u8], Nfs3Handle> {
+ let (i, len) = be_u32(i)?;
+ let (i, value) = take(len as usize)(i)?;
+ let handle = Nfs3Handle { len, value };
+ Ok((i, handle))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3ReplyCreate<'a> {
pub status: u32,
pub handle: Option<Nfs3Handle<'a>>,
}
-named!(pub parse_nfs3_response_create<Nfs3ReplyCreate>,
- do_parse!(
- status: be_u32
- >> handle_has_value: be_u32
- >> handle: cond!(handle_has_value == 1, parse_nfs3_handle)
- >> (
- Nfs3ReplyCreate {
- status:status,
- handle:handle,
- }
- ))
-);
+pub fn parse_nfs3_response_create(i: &[u8]) -> IResult<&[u8], Nfs3ReplyCreate> {
+ let (i, status) = be_u32(i)?;
+ let (i, handle_has_value) = be_u32(i)?;
+ let (i, handle) = cond(handle_has_value == 1, parse_nfs3_handle)(i)?;
+ let reply = Nfs3ReplyCreate { status, handle };
+ Ok((i, reply))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3ReplyLookup<'a> {
pub status: u32,
pub handle: Nfs3Handle<'a>,
}
-named!(pub parse_nfs3_response_lookup<Nfs3ReplyLookup>,
- do_parse!(
- status: be_u32
- >> handle: parse_nfs3_handle
- >> (
- Nfs3ReplyLookup {
- status:status,
- handle:handle,
- }
- ))
-);
+pub fn parse_nfs3_response_lookup(i: &[u8]) -> IResult<&[u8], Nfs3ReplyLookup> {
+ let (i, status) = be_u32(i)?;
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let reply = Nfs3ReplyLookup { status, handle };
+ Ok((i, reply))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestCreate<'a> {
pub handle: Nfs3Handle<'a>,
pub name_len: u32,
pub create_mode: u32,
- pub verifier: &'a[u8],
+ pub verifier: &'a [u8],
pub name_vec: Vec<u8>,
}
-named!(pub parse_nfs3_request_create<Nfs3RequestCreate>,
- do_parse!(
- handle: parse_nfs3_handle
- >> name_len: be_u32
- >> name: take!(name_len)
- >> create_mode: be_u32
- >> verifier: rest
- >> (
- Nfs3RequestCreate {
- handle:handle,
- name_len:name_len,
- create_mode:create_mode,
- verifier:verifier,
- name_vec:name.to_vec(),
- }
- ))
-);
+pub fn parse_nfs3_request_create(i: &[u8]) -> IResult<&[u8], Nfs3RequestCreate> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, name_len) = be_u32(i)?;
+ let (i, name) = take(name_len as usize)(i)?;
+ let (i, create_mode) = be_u32(i)?;
+ let (i, verifier) = rest(i)?;
+ let req = Nfs3RequestCreate {
+ handle,
+ name_len,
+ create_mode,
+ verifier,
+ name_vec: name.to_vec(),
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestRemove<'a> {
pub handle: Nfs3Handle<'a>,
pub name_len: u32,
pub name_vec: Vec<u8>,
}
-named!(pub parse_nfs3_request_remove<Nfs3RequestRemove>,
- do_parse!(
- handle: parse_nfs3_handle
- >> name_len: be_u32
- >> name: take!(name_len)
- >> _fill_bytes: rest
- >> (
- Nfs3RequestRemove {
- handle:handle,
- name_len:name_len,
- name_vec:name.to_vec(),
- }
- ))
-);
+pub fn parse_nfs3_request_remove(i: &[u8]) -> IResult<&[u8], Nfs3RequestRemove> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, name_len) = be_u32(i)?;
+ let (i, name) = take(name_len as usize)(i)?;
+ let (i, _fill_bytes) = rest(i)?;
+ let req = Nfs3RequestRemove {
+ handle,
+ name_len,
+ name_vec: name.to_vec(),
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestRmdir<'a> {
pub handle: Nfs3Handle<'a>,
pub name_vec: Vec<u8>,
}
-named!(pub parse_nfs3_request_rmdir<Nfs3RequestRmdir>,
- do_parse!(
- dir_handle: parse_nfs3_handle
- >> name_len: be_u32
- >> name: take!(name_len)
- >> _fill_bytes: cond!(name_len % 4 != 0, take!(4 - name_len % 4))
- >> (
- Nfs3RequestRmdir {
- handle:dir_handle,
- name_vec:name.to_vec(),
- }
- ))
-);
+pub fn parse_nfs3_request_rmdir(i: &[u8]) -> IResult<&[u8], Nfs3RequestRmdir> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, name_len) = be_u32(i)?;
+ let (i, name) = take(name_len as usize)(i)?;
+ let (i, _fill_bytes) = cond(name_len % 4 != 0, take(4 - (name_len % 4)))(i)?;
+ let req = Nfs3RequestRmdir {
+ handle,
+ name_vec: name.to_vec(),
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestMkdir<'a> {
pub handle: Nfs3Handle<'a>,
pub name_vec: Vec<u8>,
}
-named!(pub parse_nfs3_request_mkdir<Nfs3RequestMkdir>,
- do_parse!(
- dir_handle: parse_nfs3_handle
- >> name_len: be_u32
- >> name: take!(name_len)
- >> _fill_bytes: cond!(name_len % 4 != 0, take!(4 - name_len % 4))
- >> _attributes: rest
- >> (
- Nfs3RequestMkdir {
- handle:dir_handle,
- name_vec:name.to_vec(),
- }
- ))
-);
+pub fn parse_nfs3_request_mkdir(i: &[u8]) -> IResult<&[u8], Nfs3RequestMkdir> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, name_len) = be_u32(i)?;
+ let (i, name) = take(name_len as usize)(i)?;
+ let (i, _fill_bytes) = cond(name_len % 4 != 0, take(4 - (name_len % 4)))(i)?;
+ let (i, _attributes) = rest(i)?;
+ let req = Nfs3RequestMkdir {
+ handle,
+ name_vec: name.to_vec(),
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestRename<'a> {
pub from_handle: Nfs3Handle<'a>,
pub from_name_vec: Vec<u8>,
pub to_name_vec: Vec<u8>,
}
-named!(pub parse_nfs3_request_rename<Nfs3RequestRename>,
- do_parse!(
- from_handle: parse_nfs3_handle
- >> from_name_len: be_u32
- >> from_name: take!(from_name_len)
- >> _from_fill_bytes: cond!(from_name_len % 4 != 0, take!(4 - from_name_len % 4))
- >> to_handle: parse_nfs3_handle
- >> to_name_len: be_u32
- >> to_name: take!(to_name_len)
- >> _to_fill_bytes: rest
- >> (
- Nfs3RequestRename {
- from_handle,
- from_name_vec:from_name.to_vec(),
- to_handle,
- to_name_vec:to_name.to_vec(),
- }
- ))
-);
+pub fn parse_nfs3_request_rename(i: &[u8]) -> IResult<&[u8], Nfs3RequestRename> {
+ let (i, from_handle) = parse_nfs3_handle(i)?;
+ let (i, from_name_len) = be_u32(i)?;
+ let (i, from_name) = take(from_name_len as usize)(i)?;
+ let (i, _from_fill_bytes) = cond(from_name_len % 4 != 0, take(4 - (from_name_len % 4)))(i)?;
+
+ let (i, to_handle) = parse_nfs3_handle(i)?;
+ let (i, to_name_len) = be_u32(i)?;
+ let (i, to_name) = take(to_name_len as usize)(i)?;
+ let (i, _from_fill_bytes) = rest(i)?;
+ let req = Nfs3RequestRename {
+ from_handle,
+ from_name_vec: from_name.to_vec(),
+ to_handle,
+ to_name_vec: to_name.to_vec(),
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestGetAttr<'a> {
pub handle: Nfs3Handle<'a>,
}
-named!(pub parse_nfs3_request_getattr<Nfs3RequestGetAttr>,
- do_parse!(
- handle: parse_nfs3_handle
- >> (
- Nfs3RequestGetAttr {
- handle:handle,
- }
- ))
-);
+pub fn parse_nfs3_request_getattr(i: &[u8]) -> IResult<&[u8], Nfs3RequestGetAttr> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ Ok((i, Nfs3RequestGetAttr { handle }))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestAccess<'a> {
pub handle: Nfs3Handle<'a>,
pub check_access: u32,
}
-named!(pub parse_nfs3_request_access<Nfs3RequestAccess>,
- do_parse!(
- handle: parse_nfs3_handle
- >> check_access: be_u32
- >> (
- Nfs3RequestAccess {
- handle:handle,
- check_access:check_access,
- }
- ))
-);
+pub fn parse_nfs3_request_access(i: &[u8]) -> IResult<&[u8], Nfs3RequestAccess> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, check_access) = be_u32(i)?;
+ let req = Nfs3RequestAccess {
+ handle,
+ check_access,
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestCommit<'a> {
pub handle: Nfs3Handle<'a>,
}
-named!(pub parse_nfs3_request_commit<Nfs3RequestCommit>,
- do_parse!(
- handle: parse_nfs3_handle
- >> _offset: be_u64
- >> _count: be_u32
- >> (
- Nfs3RequestCommit {
- handle
- }
- ))
-);
+pub fn parse_nfs3_request_commit(i: &[u8]) -> IResult<&[u8], Nfs3RequestCommit> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, _offset) = be_u64(i)?;
+ let (i, _count) = be_u32(i)?;
+ Ok((i, Nfs3RequestCommit { handle }))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestRead<'a> {
pub handle: Nfs3Handle<'a>,
pub offset: u64,
}
-named!(pub parse_nfs3_request_read<Nfs3RequestRead>,
- do_parse!(
- handle: parse_nfs3_handle
- >> offset: be_u64
- >> _count: be_u32
- >> (
- Nfs3RequestRead {
- handle,
- offset
- }
- ))
-);
+pub fn parse_nfs3_request_read(i: &[u8]) -> IResult<&[u8], Nfs3RequestRead> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, offset) = be_u64(i)?;
+ let (i, _count) = be_u32(i)?;
+ Ok((i, Nfs3RequestRead { handle, offset }))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestLookup<'a> {
pub handle: Nfs3Handle<'a>,
pub name_vec: Vec<u8>,
}
-named!(pub parse_nfs3_request_lookup<Nfs3RequestLookup>,
- do_parse!(
- handle: parse_nfs3_handle
- >> name_len: be_u32
- >> name_contents: take!(name_len)
- >> _name_padding: rest
- >> (
- Nfs3RequestLookup {
- handle,
- name_vec:name_contents.to_vec(),
- }
- ))
-);
-
+pub fn parse_nfs3_request_lookup(i: &[u8]) -> IResult<&[u8], Nfs3RequestLookup> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, name_contents) = length_data(be_u32)(i)?;
+ let (i, _name_padding) = rest(i)?;
+ let req = Nfs3RequestLookup {
+ handle,
+ name_vec: name_contents.to_vec(),
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3ResponseReaddirplusEntryC<'a> {
pub name_vec: Vec<u8>,
pub handle: Option<Nfs3Handle<'a>>,
}
-named!(pub parse_nfs3_response_readdirplus_entry<Nfs3ResponseReaddirplusEntryC>,
- do_parse!(
- _file_id: be_u64
- >> name_len: be_u32
- >> name_content: take!(name_len)
- >> _fill_bytes: cond!(name_len % 4 != 0, take!(4 - name_len % 4))
- >> _cookie: take!(8)
- >> attr_value_follows: be_u32
- >> _attr: cond!(attr_value_follows==1, take!(84))
- >> handle_value_follows: be_u32
- >> handle: cond!(handle_value_follows==1, parse_nfs3_handle)
- >> (
- Nfs3ResponseReaddirplusEntryC {
- name_vec:name_content.to_vec(),
- handle,
- }
- )
- )
-);
+pub fn parse_nfs3_response_readdirplus_entry(
+ i: &[u8],
+) -> IResult<&[u8], Nfs3ResponseReaddirplusEntryC> {
+ let (i, _file_id) = be_u64(i)?;
+ let (i, name_len) = be_u32(i)?;
+ let (i, name_contents) = take(name_len as usize)(i)?;
+ let (i, _fill_bytes) = cond(name_len % 4 != 0, take(4 - (name_len % 4)))(i)?;
+ let (i, _cookie) = take(8_usize)(i)?;
+ let (i, attr_value_follows) = be_u32(i)?;
+ let (i, _attr) = cond(attr_value_follows == 1, take(84_usize))(i)?;
+ let (i, handle_value_follows) = be_u32(i)?;
+ let (i, handle) = cond(handle_value_follows == 1, parse_nfs3_handle)(i)?;
+ let resp = Nfs3ResponseReaddirplusEntryC {
+ name_vec: name_contents.to_vec(),
+ handle,
+ };
+ Ok((i, resp))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3ResponseReaddirplusEntry<'a> {
pub entry: Option<Nfs3ResponseReaddirplusEntryC<'a>>,
}
-named!(pub parse_nfs3_response_readdirplus_entry_cond<Nfs3ResponseReaddirplusEntry>,
- do_parse!(
- value_follows: be_u32
- >> entry: cond!(value_follows==1, parse_nfs3_response_readdirplus_entry)
- >> (
- Nfs3ResponseReaddirplusEntry {
- entry
- }
- ))
-);
+pub fn parse_nfs3_response_readdirplus_entry_cond(
+ i: &[u8],
+) -> IResult<&[u8], Nfs3ResponseReaddirplusEntry> {
+ let (i, value_follows) = be_u32(i)?;
+ let (i, entry) = cond(value_follows == 1, parse_nfs3_response_readdirplus_entry)(i)?;
+ Ok((i, Nfs3ResponseReaddirplusEntry { entry }))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3ResponseReaddirplus<'a> {
pub status: u32,
- pub data: &'a[u8],
+ pub data: &'a [u8],
}
-named!(pub parse_nfs3_response_readdirplus<Nfs3ResponseReaddirplus>,
- do_parse!(
- status: be_u32
- >> dir_attr_follows: be_u32
- >> _dir_attr: cond!(dir_attr_follows == 1, take!(84))
- >> _verifier: take!(8)
- >> data: rest
-
- >> ( Nfs3ResponseReaddirplus {
- status,
- data
- } ))
-);
+pub fn parse_nfs3_response_readdirplus(i: &[u8]) -> IResult<&[u8], Nfs3ResponseReaddirplus> {
+ let (i, status) = be_u32(i)?;
+ let (i, dir_attr_follows) = be_u32(i)?;
+ let (i, _dir_attr) = cond(dir_attr_follows == 1, take(84_usize))(i)?;
+ let (i, data) = rest(i)?;
+ let resp = Nfs3ResponseReaddirplus { status, data };
+ Ok((i, resp))
+}
-pub(crate) fn many0_nfs3_response_readdirplus_entries<'a>(input: &'a [u8]) -> IResult<&'a[u8], Vec<Nfs3ResponseReaddirplusEntry<'a>>> {
- many0!(input, complete!(parse_nfs3_response_readdirplus_entry_cond))
+pub(crate) fn many0_nfs3_response_readdirplus_entries<'a>(
+ input: &'a [u8],
+) -> IResult<&'a [u8], Vec<Nfs3ResponseReaddirplusEntry<'a>>> {
+ many0(complete(parse_nfs3_response_readdirplus_entry_cond))(input)
}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestReaddirplus<'a> {
pub handle: Nfs3Handle<'a>,
pub cookie: u32,
- pub verifier: &'a[u8],
+ pub verifier: &'a [u8],
pub dircount: u32,
pub maxcount: u32,
}
-named!(pub parse_nfs3_request_readdirplus<Nfs3RequestReaddirplus>,
- do_parse!(
- handle: parse_nfs3_handle
- >> cookie: be_u32
- >> verifier: take!(8)
- >> dircount: be_u32
- >> maxcount: be_u32
- >> (
- Nfs3RequestReaddirplus {
- handle:handle,
- cookie:cookie,
- verifier:verifier,
- dircount:dircount,
- maxcount:maxcount,
- }
- ))
-);
+pub fn parse_nfs3_request_readdirplus(i: &[u8]) -> IResult<&[u8], Nfs3RequestReaddirplus> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, cookie) = be_u32(i)?;
+ let (i, verifier) = take(8_usize)(i)?;
+ let (i, dircount) = be_u32(i)?;
+ let (i, maxcount) = be_u32(i)?;
+ let req = Nfs3RequestReaddirplus {
+ handle,
+ cookie,
+ verifier,
+ dircount,
+ maxcount,
+ };
+ Ok((i, req))
+}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct Nfs3RequestWrite<'a> {
pub handle: Nfs3Handle<'a>,
pub count: u32,
pub stable: u32,
pub file_len: u32,
- pub file_data: &'a[u8],
-}
-
-named!(pub parse_nfs3_request_write<Nfs3RequestWrite>,
- do_parse!(
- handle: parse_nfs3_handle
- >> offset: be_u64
- >> count: be_u32
- >> stable: be_u32
- >> file_len: be_u32
- >> file_data: rest // likely partial
- >> (
- Nfs3RequestWrite {
- handle:handle,
- offset:offset,
- count:count,
- stable:stable,
- file_len:file_len,
- file_data:file_data,
- }
- ))
-);
+ pub file_data: &'a [u8],
+}
+
+pub fn parse_nfs3_request_write(i: &[u8]) -> IResult<&[u8], Nfs3RequestWrite> {
+ let (i, handle) = parse_nfs3_handle(i)?;
+ let (i, offset) = be_u64(i)?;
+ let (i, count) = be_u32(i)?;
+ let (i, stable) = be_u32(i)?;
+ let (i, file_len) = be_u32(i)?;
+ let (i, file_data) = rest(i)?;
+ let req = Nfs3RequestWrite {
+ handle,
+ offset,
+ count,
+ stable,
+ file_len,
+ file_data,
+ };
+ Ok((i, req))
+}
/*
#[derive(Debug,PartialEq)]
pub struct Nfs3ReplyRead<'a> {
pub data: &'a[u8], // likely partial
}
*/
-named!(pub parse_nfs3_reply_read<NfsReplyRead>,
- do_parse!(
- status: be_u32
- >> attr_follows: be_u32
- >> attr_blob: take!(84) // fixed size?
- >> count: be_u32
- >> eof: be_u32
- >> data_len: be_u32
- >> data_contents: rest
- >> (
- NfsReplyRead {
- status:status,
- attr_follows:attr_follows,
- attr_blob:attr_blob,
- count:count,
- eof:eof != 0,
- data_len:data_len,
- data:data_contents,
- }
- ))
-);
+pub fn parse_nfs3_reply_read(i: &[u8]) -> IResult<&[u8], NfsReplyRead> {
+ let (i, status) = be_u32(i)?;
+ let (i, attr_follows) = be_u32(i)?;
+ let (i, attr_blob) = take(84_usize)(i)?; // fixed size?
+ let (i, count) = be_u32(i)?;
+ let (i, eof) = be_u32(i)?;
+ let (i, data_len) = be_u32(i)?;
+ let (i, data) = rest(i)?;
+ let reply = NfsReplyRead {
+ status,
+ attr_follows,
+ attr_blob,
+ count,
+ eof: eof != 0,
+ data_len,
+ data,
+ };
+ Ok((i, reply))
+}
// written by Victor Julien
-use nom;
+use nom::bytes::streaming::take;
use nom::number::streaming::be_u32;
+use nom7::Err;
use crate::core::*;
use crate::nfs::nfs::*;
-use crate::nfs::types::*;
-use crate::nfs::rpc_records::*;
-use crate::nfs::nfs_records::*;
use crate::nfs::nfs4_records::*;
+use crate::nfs::nfs_records::*;
+use crate::nfs::rpc_records::*;
+use crate::nfs::types::*;
use crate::kerberos::{parse_kerberos5_request, Kerberos5Ticket, SecBlobError};
-named!(parse_req_gssapi<&[u8], Kerberos5Ticket, SecBlobError>,
- do_parse!(
- len: be_u32
- >> ap: flat_map!(take!(len), parse_kerberos5_request)
- >> ( ap )
-));
+// use the old nom type until both SMB and NFS are migrated to nom 7
+fn parse_req_gssapi(i: &[u8]) -> nom::IResult<&[u8], Kerberos5Ticket, SecBlobError> {
+ let (i, len) = be_u32(i)?;
+ let (i, buf) = take(len as usize)(i)?;
+ let (_, ap) = parse_kerberos5_request(buf)?;
+ Ok((i, ap))
+}
impl NFSState {
/* normal write: PUTFH (file handle), WRITE (write opts/data). File handle
* is not part of the write record itself so we pass it in here. */
- fn write_v4<'b>(&mut self, r: &RpcPacket<'b>, w: &Nfs4RequestWrite<'b>, fh: &'b[u8])
- {
+ fn write_v4<'b>(&mut self, r: &RpcPacket<'b>, w: &Nfs4RequestWrite<'b>, fh: &'b [u8]) {
// for now assume that stable FILE_SYNC flags means a single chunk
let is_last = if w.stable == 2 { true } else { false };
SCLogDebug!("is_last {}", is_last);
let found = match self.get_file_tx_by_handle(&file_handle, Direction::ToServer) {
Some((tx, files, flags)) => {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
- filetracker_newchunk(&mut tdf.file_tracker, files, flags,
- &file_name, w.data, w.offset,
- w.write_len, fill_bytes as u8, is_last, &r.hdr.xid);
+ filetracker_newchunk(
+ &mut tdf.file_tracker,
+ files,
+ flags,
+ &file_name,
+ w.data,
+ w.offset,
+ w.write_len,
+ fill_bytes as u8,
+ is_last,
+ &r.hdr.xid,
+ );
tdf.chunk_count += 1;
if is_last {
tdf.file_last_xid = r.hdr.xid;
}
}
true
- },
+ }
None => false,
};
if !found {
let (tx, files, flags) = self.new_file_tx(&file_handle, &file_name, Direction::ToServer);
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
- filetracker_newchunk(&mut tdf.file_tracker, files, flags,
- &file_name, w.data, w.offset,
- w.write_len, fill_bytes as u8, is_last, &r.hdr.xid);
+ filetracker_newchunk(
+ &mut tdf.file_tracker,
+ files,
+ flags,
+ &file_name,
+ w.data,
+ w.offset,
+ w.write_len,
+ fill_bytes as u8,
+ is_last,
+ &r.hdr.xid,
+ );
tx.procedure = NFSPROC4_WRITE;
tx.xid = r.hdr.xid;
tx.is_first = true;
self.ts_chunk_left = w.write_len as u32 - file_data_len as u32;
}
- fn close_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b[u8])
- {
+ fn close_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b [u8]) {
self.commit_v4(r, fh)
}
- fn commit_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b[u8])
- {
+ fn commit_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b [u8]) {
SCLogDebug!("COMMIT, closing shop");
let file_handle = fh.to_vec();
- if let Some((tx, files, flags)) = self.get_file_tx_by_handle(&file_handle, Direction::ToServer) {
+ if let Some((tx, files, flags)) = self.get_file_tx_by_handle(&file_handle, Direction::ToServer)
+ {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
tdf.file_tracker.close(files, flags);
tdf.file_last_xid = r.hdr.xid;
}
}
- fn new_tx_v4<'b>(&mut self, r: &RpcPacket<'b>,
- xidmap: &NFSRequestXidMap, procedure: u32,
- _aux_opcodes: &Vec<u32>)
- {
+ fn new_tx_v4<'b>(
+ &mut self, r: &RpcPacket<'b>, xidmap: &NFSRequestXidMap, procedure: u32,
+ _aux_opcodes: &Vec<u32>,
+ ) {
let mut tx = self.new_tx();
tx.xid = r.hdr.xid;
tx.procedure = procedure;
tx.request_machine_name = u.machine_name_buf.to_vec();
tx.request_uid = u.uid;
tx.request_gid = u.gid;
- },
- _ => { },
+ }
+ _ => {}
}
- SCLogDebug!("NFSv4: TX created: ID {} XID {} PROCEDURE {}",
- tx.id, tx.xid, tx.procedure);
+ SCLogDebug!(
+ "NFSv4: TX created: ID {} XID {} PROCEDURE {}",
+ tx.id,
+ tx.xid,
+ tx.procedure
+ );
self.transactions.push(tx);
}
/* A normal READ request looks like: PUTFH (file handle) READ (read opts).
* We need the file handle for the READ.
*/
- fn compound_request<'b>(&mut self, r: &RpcPacket<'b>,
- cr: &Nfs4RequestCompoundRecord<'b>,
- xidmap: &mut NFSRequestXidMap)
- {
- let mut last_putfh : Option<&'b[u8]> = None;
- let mut main_opcode : u32 = 0;
- let mut aux_opcodes : Vec<u32> = Vec::new();
+ fn compound_request<'b>(
+ &mut self, r: &RpcPacket<'b>, cr: &Nfs4RequestCompoundRecord<'b>,
+ xidmap: &mut NFSRequestXidMap,
+ ) {
+ let mut last_putfh: Option<&'b [u8]> = None;
+ let mut main_opcode: u32 = 0;
+ let mut aux_opcodes: Vec<u32> = Vec::new();
for c in &cr.commands {
SCLogDebug!("c {:?}", c);
main_opcode = NFSPROC4_REMOVE;
}
&Nfs4RequestContent::SetClientId(ref _rd) => {
- SCLogDebug!("SETCLIENTIDv4: client id {} r_netid {} r_addr {}",
- String::from_utf8_lossy(&_rd.client_id),
- String::from_utf8_lossy(&_rd.r_netid),
- String::from_utf8_lossy(&_rd.r_addr));
+ SCLogDebug!(
+ "SETCLIENTIDv4: client id {} r_netid {} r_addr {}",
+ String::from_utf8_lossy(&_rd.client_id),
+ String::from_utf8_lossy(&_rd.r_netid),
+ String::from_utf8_lossy(&_rd.r_addr)
+ );
}
- &_ => { },
+ &_ => {}
}
}
/// complete request record
pub fn process_request_record_v4<'b>(&mut self, r: &RpcPacket<'b>) {
- SCLogDebug!("NFSv4 REQUEST {} procedure {} ({}) blob size {}",
- r.hdr.xid, r.procedure, self.requestmap.len(), r.prog_data.len());
+ SCLogDebug!(
+ "NFSv4 REQUEST {} procedure {} ({}) blob size {}",
+ r.hdr.xid,
+ r.procedure,
+ self.requestmap.len(),
+ r.prog_data.len()
+ );
let mut xidmap = NFSRequestXidMap::new(r.progver, r.procedure, 0);
let mut data = r.prog_data;
if let RpcRequestCreds::GssApi(ref creds) = r.creds {
- if creds.procedure == 0 && creds.service == 2 {
+ if creds.procedure == 0 && creds.service == 2 {
SCLogDebug!("GSS INTEGRITIY: {:?}", creds);
match parse_rpc_gssapi_integrity(r.prog_data) {
Ok((_rem, rec)) => {
// store proc and serv for the reply
xidmap.gssapi_proc = creds.procedure;
xidmap.gssapi_service = creds.service;
- },
- Err(nom::Err::Incomplete(_n)) => {
+ }
+ Err(Err::Incomplete(_n)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: INCOMPLETE {:?}", _n);
self.set_event(NFSEvent::MalformedData);
return;
- },
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
- SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: Parsing failed: {:?}", _e);
+ }
+ Err(Err::Error(_e)) | Err(Err::Failure(_e)) => {
+ SCLogDebug!(
+ "NFSPROC4_COMPOUND/GSS INTEGRITIY: Parsing failed: {:?}",
+ _e
+ );
self.set_event(NFSEvent::MalformedData);
return;
- },
+ }
}
}
}
Ok((_, rd)) => {
SCLogDebug!("NFSPROC4_COMPOUND: {:?}", rd);
self.compound_request(r, &rd, &mut xidmap);
- },
- Err(nom::Err::Incomplete(_n)) => {
+ }
+ Err(Err::Incomplete(_n)) => {
SCLogDebug!("NFSPROC4_COMPOUND: INCOMPLETE {:?}", _n);
self.set_event(NFSEvent::MalformedData);
- },
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ }
+ Err(Err::Error(_e)) | Err(Err::Failure(_e)) => {
SCLogDebug!("NFSPROC4_COMPOUND: Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
- },
+ }
};
}
self.requestmap.insert(r.hdr.xid, xidmap);
}
- fn compound_response<'b>(&mut self, r: &RpcReplyPacket<'b>,
- cr: &Nfs4ResponseCompoundRecord<'b>,
- xidmap: &mut NFSRequestXidMap)
- {
+ fn compound_response<'b>(
+ &mut self, r: &RpcReplyPacket<'b>, cr: &Nfs4ResponseCompoundRecord<'b>,
+ xidmap: &mut NFSRequestXidMap,
+ ) {
let mut insert_filename_with_getfh = false;
- let mut main_opcode_status : u32 = 0;
- let mut main_opcode_status_set : bool = false;
+ let mut main_opcode_status: u32 = 0;
+ let mut main_opcode_status_set: bool = false;
for c in &cr.commands {
SCLogDebug!("c {:?}", c);
SCLogDebug!("READDIRv4: dir {}", String::from_utf8_lossy(&_d.name));
}
}
-
}
}
&Nfs4ResponseContent::Remove(s) => {
SCLogDebug!("REMOVE4: status {}", s);
main_opcode_status = s;
main_opcode_status_set = true;
- },
+ }
&Nfs4ResponseContent::Create(s) => {
SCLogDebug!("CREATE4: status {}", s);
main_opcode_status = s;
main_opcode_status_set = true;
- },
+ }
&Nfs4ResponseContent::Read(s, ref rd) => {
if let &Some(ref rd) = rd {
- SCLogDebug!("READ4: xidmap {:?} status {} data {}", xidmap, s, rd.data.len());
+ SCLogDebug!(
+ "READ4: xidmap {:?} status {} data {}",
+ xidmap,
+ s,
+ rd.data.len()
+ );
// convert record to generic read reply
let reply = NfsReplyRead {
status: s,
};
self.process_read_record(r, &reply, Some(xidmap));
}
- },
+ }
&Nfs4ResponseContent::Open(_s, ref rd) => {
if let &Some(ref _rd) = rd {
SCLogDebug!("OPENv4: status {} opendata {:?}", _s, _rd);
insert_filename_with_getfh = true;
}
- },
+ }
&Nfs4ResponseContent::GetFH(_s, ref rd) => {
if let &Some(ref rd) = rd {
if insert_filename_with_getfh {
- self.namemap.insert(rd.value.to_vec(),
- xidmap.file_name.to_vec());
+ self.namemap
+ .insert(rd.value.to_vec(), xidmap.file_name.to_vec());
}
}
- },
+ }
&Nfs4ResponseContent::PutRootFH(s) => {
if s == NFS4_OK && xidmap.file_name.len() == 0 {
xidmap.file_name = b"<mount_root>".to_vec();
SCLogDebug!("filename {:?}", xidmap.file_name);
}
- },
- &_ => { },
+ }
+ &_ => {}
}
}
}
}
- pub fn process_reply_record_v4<'b>(&mut self, r: &RpcReplyPacket<'b>,
- xidmap: &mut NFSRequestXidMap) {
+ pub fn process_reply_record_v4<'b>(
+ &mut self, r: &RpcReplyPacket<'b>, xidmap: &mut NFSRequestXidMap,
+ ) {
if xidmap.procedure == NFSPROC4_COMPOUND {
let mut data = r.prog_data;
if xidmap.gssapi_proc == 0 && xidmap.gssapi_service == 2 {
-
SCLogDebug!("GSS INTEGRITIY as set by call: {:?}", xidmap);
match parse_rpc_gssapi_integrity(r.prog_data) {
Ok((_rem, rec)) => {
SCLogDebug!("GSS INTEGRITIY wrapper: {:?}", rec);
data = rec.data;
- },
- Err(nom::Err::Incomplete(_n)) => {
+ }
+ Err(Err::Incomplete(_n)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: INCOMPLETE {:?}", _n);
self.set_event(NFSEvent::MalformedData);
return;
- },
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ }
+ Err(Err::Error(_e)) | Err(Err::Failure(_e)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
return;
- },
+ }
}
}
match parse_nfs4_response_compound(data) {
Ok((_, rd)) => {
SCLogDebug!("COMPOUNDv4: {:?}", rd);
self.compound_response(r, &rd, xidmap);
- },
- Err(nom::Err::Incomplete(_)) => {
+ }
+ Err(Err::Incomplete(_)) => {
self.set_event(NFSEvent::MalformedData);
- },
- Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => {
+ }
+ Err(Err::Error(_e)) | Err(Err::Failure(_e)) => {
SCLogDebug!("Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
- },
+ }
};
}
}
*/
//! Nom parsers for NFSv4 records
-use nom::number::streaming::{be_u32, be_u64};
+use nom7::bytes::streaming::{tag, take};
+use nom7::combinator::{complete, cond, map, peek};
+use nom7::error::{make_error, ErrorKind};
+use nom7::multi::{count, many_till};
+use nom7::number::streaming::{be_u32, be_u64};
+use nom7::{Err, IResult};
use crate::nfs::types::*;
attr_mask: u64,
}
-named!(nfs4_parse_attr_fields<u32>,
- do_parse!(
- len: be_u32
- >> take!(len)
- >> (len)
-));
-
-named!(nfs4_parse_attrs<Nfs4Attr>,
- do_parse!(
- attr_cnt: be_u32
- >> attr_mask1: be_u32
- >> attr_mask2: cond!(attr_cnt >= 2, be_u32)
- >> cond!(attr_cnt == 3, be_u32)
- >> nfs4_parse_attr_fields
- >> ( Nfs4Attr {
- attr_mask: ((attr_mask1 as u64) << 32) | attr_mask2.unwrap_or(0) as u64,
- } )
-));
-
-named!(nfs4_parse_attrbits<Nfs4Attr>,
- do_parse!(
- attr_cnt: be_u32
- >> attr_mask1: be_u32
- >> attr_mask2: cond!(attr_cnt >= 2, be_u32)
- >> cond!(attr_cnt == 3, be_u32)
- >> ( Nfs4Attr {
- attr_mask: ((attr_mask1 as u64) << 32) | attr_mask2.unwrap_or(0) as u64,
- } )
-));
+fn nfs4_parse_attr_fields(i: &[u8]) -> IResult<&[u8], u32> {
+ let (i, len) = be_u32(i)?;
+ let (i, _) = take(len as usize)(i)?;
+ Ok((i, len))
+}
+
+fn nfs4_parse_attrs(i: &[u8]) -> IResult<&[u8], Nfs4Attr> {
+ let (i, attr_cnt) = be_u32(i)?;
+ let (i, attr_mask1) = be_u32(i)?;
+ let (i, attr_mask2) = cond(attr_cnt >= 2, be_u32)(i)?;
+ let (i, _) = cond(attr_cnt == 3, be_u32)(i)?;
+ let (i, _) = nfs4_parse_attr_fields(i)?;
+ let attr = Nfs4Attr {
+ attr_mask: ((attr_mask1 as u64) << 32) | attr_mask2.unwrap_or(0) as u64,
+ };
+ Ok((i, attr))
+}
+
+fn nfs4_parse_attrbits(i: &[u8]) -> IResult<&[u8], Nfs4Attr> {
+ let (i, attr_cnt) = be_u32(i)?;
+ let (i, attr_mask1) = be_u32(i)?;
+ let (i, attr_mask2) = cond(attr_cnt >= 2, be_u32)(i)?;
+ let (i, _) = cond(attr_cnt == 3, be_u32)(i)?;
+ let attr = Nfs4Attr {
+ attr_mask: ((attr_mask1 as u64) << 32) | attr_mask2.unwrap_or(0) as u64,
+ };
+ Ok((i, attr))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4StateId<'a> {
pub data: &'a[u8],
}
-named!(nfs4_parse_stateid<Nfs4StateId>,
- do_parse!(
- seqid: be_u32
- >> data: take!(12)
- >> ( Nfs4StateId {
- seqid: seqid,
- data: data,
- })
- )
-);
+fn nfs4_parse_stateid(i: &[u8]) -> IResult<&[u8], Nfs4StateId> {
+ let (i, seqid) = be_u32(i)?;
+ let (i, data) = take(12_usize)(i)?;
+ let state = Nfs4StateId { seqid, data };
+ Ok((i, state))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4Handle<'a> {
pub value: &'a[u8],
}
-named!(nfs4_parse_handle<Nfs4Handle>,
- do_parse!(
- obj_len: be_u32
- >> obj: take!(obj_len)
- >> ( Nfs4Handle {
- len: obj_len,
- value: obj,
- })
-));
-
-named!(nfs4_parse_nfsstring<&[u8]>,
- do_parse!(
- len: be_u32
- >> data: take!(len)
- >> _fill_bytes: cond!(len % 4 != 0, take!(4 - len % 4))
- >> ( data )
-));
-
-named!(nfs4_req_putfh<Nfs4RequestContent>,
- do_parse!(
- h: nfs4_parse_handle
- >> ( Nfs4RequestContent::PutFH(h) )
-));
+fn nfs4_parse_handle(i: &[u8]) -> IResult<&[u8], Nfs4Handle> {
+ let (i, len) = be_u32(i)?;
+ let (i, value) = take(len as usize)(i)?;
+ let handle = Nfs4Handle { len, value };
+ Ok((i, handle))
+}
+
+fn nfs4_parse_nfsstring(i: &[u8]) -> IResult<&[u8], &[u8]> {
+ let (i, len) = be_u32(i)?;
+ let (i, data) = take(len as usize)(i)?;
+ let (i, _fill_bytes) = cond(len % 4 != 0, take(4 - (len % 4)))(i)?;
+ Ok((i, data))
+}
+
+fn nfs4_req_putfh(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(nfs4_parse_handle, Nfs4RequestContent::PutFH)(i)
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestSetClientId<'a> {
pub r_addr: &'a[u8],
}
-named!(nfs4_req_setclientid<Nfs4RequestContent>,
- do_parse!(
- _client_verifier: take!(8)
- >> client_id: nfs4_parse_nfsstring
- >> _cb_program: be_u32
- >> r_netid: nfs4_parse_nfsstring
- >> r_addr: nfs4_parse_nfsstring
- >> _cb_id: be_u32
- >> (Nfs4RequestContent::SetClientId(Nfs4RequestSetClientId {
- client_id,
- r_netid,
- r_addr
- }))
-));
-
-named!(nfs4_req_setclientid_confirm<Nfs4RequestContent>,
- do_parse!(
- _client_id: take!(8)
- >> _verifier: take!(8)
- >> (Nfs4RequestContent::SetClientIdConfirm)
-));
+fn nfs4_req_setclientid(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _client_verifier) = take(8_usize)(i)?;
+ let (i, client_id) = nfs4_parse_nfsstring(i)?;
+ let (i, _cb_program) = be_u32(i)?;
+ let (i, r_netid) = nfs4_parse_nfsstring(i)?;
+ let (i, r_addr) = nfs4_parse_nfsstring(i)?;
+ let (i, _cb_id) = be_u32(i)?;
+ let req = Nfs4RequestContent::SetClientId(Nfs4RequestSetClientId {
+ client_id,
+ r_netid,
+ r_addr
+ });
+ Ok((i, req))
+}
+
+fn nfs4_req_setclientid_confirm(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _client_id) = take(8_usize)(i)?;
+ let (i, _verifier) = take(8_usize)(i)?;
+ Ok((i, Nfs4RequestContent::SetClientIdConfirm))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestCreate<'a> {
pub link_content: &'a[u8],
}
-named!(nfs4_req_create<Nfs4RequestContent>,
- do_parse!(
- ftype4: be_u32
- >> link_content: cond!(ftype4 == 5, nfs4_parse_nfsstring)
- >> filename: nfs4_parse_nfsstring
- >> _attrs: nfs4_parse_attrs
- >> ( Nfs4RequestContent::Create(Nfs4RequestCreate {
- ftype4: ftype4,
- filename: filename,
- link_content: link_content.unwrap_or(&[]),
- })
- ))
-);
+fn nfs4_req_create(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, ftype4) = be_u32(i)?;
+ let (i, link_content) = cond(ftype4 == 5, nfs4_parse_nfsstring)(i)?;
+ let (i, filename) = nfs4_parse_nfsstring(i)?;
+ let (i, _attrs) = nfs4_parse_attrs(i)?;
+ let req = Nfs4RequestContent::Create(Nfs4RequestCreate {
+ ftype4,
+ filename,
+ link_content: link_content.unwrap_or(&[]),
+ });
+ Ok((i, req))
+}
#[derive(Debug,PartialEq)]
pub enum Nfs4OpenRequestContent<'a> {
Guarded4(Nfs4Attr),
}
-named!(nfs4_req_open_unchecked4<Nfs4OpenRequestContent>,
- do_parse!(
- attrs: nfs4_parse_attrs
- >> ( Nfs4OpenRequestContent::Unchecked4(attrs) )
-));
+fn nfs4_req_open_unchecked4(i: &[u8]) -> IResult<&[u8], Nfs4OpenRequestContent> {
+ map(nfs4_parse_attrs, Nfs4OpenRequestContent::Unchecked4)(i)
+}
-named!(nfs4_req_open_guarded4<Nfs4OpenRequestContent>,
- do_parse!(
- attrs: nfs4_parse_attrs
- >> ( Nfs4OpenRequestContent::Guarded4(attrs) )
-));
+fn nfs4_req_open_guarded4(i: &[u8]) -> IResult<&[u8], Nfs4OpenRequestContent> {
+ map(nfs4_parse_attrs, Nfs4OpenRequestContent::Guarded4)(i)
+}
-named!(nfs4_req_open_exclusive4<Nfs4OpenRequestContent>,
- do_parse!(
- ver: take!(8)
- >> ( Nfs4OpenRequestContent::Exclusive4(ver) )
-));
+fn nfs4_req_open_exclusive4(i: &[u8]) -> IResult<&[u8], Nfs4OpenRequestContent> {
+ map(take(8_usize), Nfs4OpenRequestContent::Exclusive4)(i)
+}
-named!(nfs4_req_open_type<Nfs4OpenRequestContent>,
- do_parse!(
- mode: be_u32
- >> data: switch!(value!(mode),
- 0 => call!(nfs4_req_open_unchecked4) |
- 1 => call!(nfs4_req_open_guarded4) |
- 2 => call!(nfs4_req_open_exclusive4))
- >> ( data )
-));
+fn nfs4_req_open_type(i: &[u8]) -> IResult<&[u8], Nfs4OpenRequestContent> {
+ let (i, mode) = be_u32(i)?;
+ let (i, data) = match mode {
+ 0 => nfs4_req_open_unchecked4(i)?,
+ 1 => nfs4_req_open_guarded4(i)?,
+ 2 => nfs4_req_open_exclusive4(i)?,
+ _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
+ };
+ Ok((i, data))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestOpen<'a> {
pub open_data: Option<Nfs4OpenRequestContent<'a>>,
}
-named!(nfs4_req_open<Nfs4RequestContent>,
- do_parse!(
- _seqid: be_u32
- >> _share_access: be_u32
- >> _share_deny: be_u32
- >> _client_id: be_u64
- >> owner_len: be_u32
- >> cond!(owner_len > 0, take!(owner_len))
- >> open_type: be_u32
- >> open_data: cond!(open_type == 1, nfs4_req_open_type)
- >> _claim_type: be_u32
- >> filename: nfs4_parse_nfsstring
- >> ( Nfs4RequestContent::Open(Nfs4RequestOpen {
- open_type,
- filename,
- open_data
- })
- ))
-);
-
-named!(nfs4_req_readdir<Nfs4RequestContent>,
- do_parse!(
- _cookie: be_u64
- >> _cookie_verf: be_u64
- >> _dir_cnt: be_u32
- >> _max_cnt: be_u32
- >> _attr: nfs4_parse_attrbits
- >> ( Nfs4RequestContent::ReadDir )
- )
-);
+fn nfs4_req_open(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _seq_id) = be_u32(i)?;
+ let (i, _share_access) = be_u32(i)?;
+ let (i, _share_deny) = be_u32(i)?;
+ let (i, _client_id) = be_u64(i)?;
+ let (i, owner_len) = be_u32(i)?;
+ let (i, _) = cond(owner_len > 0, take(owner_len as usize))(i)?;
+ let (i, open_type) = be_u32(i)?;
+ let (i, open_data) = cond(open_type == 1, nfs4_req_open_type)(i)?;
+ let (i, _claim_type) = be_u32(i)?;
+ let (i, filename) = nfs4_parse_nfsstring(i)?;
+ let req = Nfs4RequestContent::Open(Nfs4RequestOpen {
+ open_type,
+ filename,
+ open_data
+ });
+ Ok((i, req))
+}
+
+fn nfs4_req_readdir(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _cookie) = be_u64(i)?;
+ let (i, _cookie_verf) = be_u64(i)?;
+ let (i, _dir_cnt) = be_u32(i)?;
+ let (i, _max_cnt) = be_u32(i)?;
+ let (i, _attr) = nfs4_parse_attrbits(i)?;
+ Ok((i, Nfs4RequestContent::ReadDir))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestRename<'a> {
pub newname: &'a[u8],
}
-named!(nfs4_req_rename<Nfs4RequestContent>,
- do_parse!(
- oldname: nfs4_parse_nfsstring
- >> newname: nfs4_parse_nfsstring
- >> ( Nfs4RequestContent::Rename(Nfs4RequestRename {
- oldname,
- newname
- })
- ))
-);
+fn nfs4_req_rename(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, oldname) = nfs4_parse_nfsstring(i)?;
+ let (i, newname) = nfs4_parse_nfsstring(i)?;
+ let req = Nfs4RequestContent::Rename(Nfs4RequestRename {
+ oldname,
+ newname
+ });
+ Ok((i, req))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestLookup<'a> {
pub filename: &'a[u8],
}
-named!(nfs4_req_lookup<Nfs4RequestContent>,
- do_parse!(
- filename: nfs4_parse_nfsstring
- >> ( Nfs4RequestContent::Lookup(Nfs4RequestLookup {
- filename
- })
- ))
-);
+fn nfs4_req_lookup(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(nfs4_parse_nfsstring, |filename| {
+ Nfs4RequestContent::Lookup(Nfs4RequestLookup { filename })
+ })(i)
+}
-named!(nfs4_req_remove<Nfs4RequestContent>,
- do_parse!(
- filename: nfs4_parse_nfsstring
- >> ( Nfs4RequestContent::Remove(filename) )
-));
+fn nfs4_req_remove(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(nfs4_parse_nfsstring, Nfs4RequestContent::Remove)(i)
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestSetAttr<'a> {
pub stateid: Nfs4StateId<'a>,
}
-named!(nfs4_req_setattr<Nfs4RequestContent>,
- do_parse!(
- stateid: nfs4_parse_stateid
- >> _attrs: nfs4_parse_attrs
- >> (Nfs4RequestContent::SetAttr(Nfs4RequestSetAttr {
- stateid
- }))
-));
+fn nfs4_req_setattr(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ let (i, _attrs) = nfs4_parse_attrs(i)?;
+ let req = Nfs4RequestContent::SetAttr(Nfs4RequestSetAttr { stateid });
+ Ok((i, req))
+}
-named!(nfs4_req_getattr<Nfs4RequestContent>,
- do_parse!(
- attrs: nfs4_parse_attrbits
- >> ( Nfs4RequestContent::GetAttr(attrs) )
- )
-);
+fn nfs4_req_getattr(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(nfs4_parse_attrbits, Nfs4RequestContent::GetAttr)(i)
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestWrite<'a> {
pub data: &'a[u8],
}
-named!(nfs4_req_write<Nfs4RequestContent>,
- do_parse!(
- stateid: nfs4_parse_stateid
- >> offset: be_u64
- >> stable: be_u32
- >> write_len: be_u32
- >> data: take!(write_len)
- >> _padding: cond!(write_len % 4 != 0, take!(4 - write_len % 4))
- >> (Nfs4RequestContent::Write(Nfs4RequestWrite {
- stateid: stateid,
- offset: offset,
- stable: stable,
- write_len: write_len,
- data: data,
- }))
-));
+fn nfs4_req_write(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ let (i, offset) = be_u64(i)?;
+ let (i, stable) = be_u32(i)?;
+ let (i, write_len) = be_u32(i)?;
+ let (i, data) = take(write_len as usize)(i)?;
+ let (i, _padding) = cond(write_len % 4 != 0, take(4 - (write_len % 4)))(i)?;
+ let req = Nfs4RequestContent::Write(Nfs4RequestWrite {
+ stateid,
+ offset,
+ stable,
+ write_len,
+ data,
+ });
+ Ok((i, req))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestRead<'a> {
pub count: u32,
}
-named!(nfs4_req_read<Nfs4RequestContent>,
- do_parse!(
- stateid: nfs4_parse_stateid
- >> offset: be_u64
- >> count: be_u32
- >> ( Nfs4RequestContent::Read(Nfs4RequestRead {
- stateid: stateid,
- offset: offset,
- count: count,
- })
- ))
-);
-
-named!(nfs4_req_close<Nfs4RequestContent>,
- do_parse!(
- _seqid: be_u32
- >> stateid: nfs4_parse_stateid
- >> ( Nfs4RequestContent::Close(stateid) )
-));
+fn nfs4_req_read(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ let (i, offset) = be_u64(i)?;
+ let (i, count) = be_u32(i)?;
+ let req = Nfs4RequestContent::Read(Nfs4RequestRead {
+ stateid,
+ offset,
+ count,
+ });
+ Ok((i, req))
+}
+
+fn nfs4_req_close(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _seq_id) = be_u32(i)?;
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ Ok((i, Nfs4RequestContent::Close(stateid)))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestOpenConfirm<'a> {
pub stateid: Nfs4StateId<'a>,
}
-named!(nfs4_req_open_confirm<Nfs4RequestContent>,
- do_parse!(
- stateid: nfs4_parse_stateid
- >> _seqid: be_u32
- >> ( Nfs4RequestContent::OpenConfirm(Nfs4RequestOpenConfirm {
- stateid
- })
- ))
-);
-
-named!(nfs4_req_delegreturn<Nfs4RequestContent>,
- do_parse!(
- a: nfs4_parse_stateid
- >> ( Nfs4RequestContent::DelegReturn(a) )
- )
-);
-
-named!(nfs4_req_renew<Nfs4RequestContent>,
- do_parse!(
- a: be_u64
- >> ( Nfs4RequestContent::Renew(a) )
- )
-);
-
-named!(nfs4_req_getfh<Nfs4RequestContent>,
- do_parse!( ( Nfs4RequestContent::GetFH ) ));
-
-named!(nfs4_req_savefh<Nfs4RequestContent>,
- do_parse!( ( Nfs4RequestContent::SaveFH ) ));
-
-named!(nfs4_req_putrootfh<Nfs4RequestContent>,
- do_parse!( ( Nfs4RequestContent::PutRootFH ) ));
-
-named!(nfs4_req_access<Nfs4RequestContent>,
- do_parse!(
- a: be_u32
- >> ( Nfs4RequestContent::Access(a) )
- )
-);
-
-named!(nfs4_req_commit<Nfs4RequestContent>,
- do_parse!(
- _offset: be_u64
- >> _count: be_u32
- >> ( Nfs4RequestContent::Commit )
- )
-);
+fn nfs4_req_open_confirm(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _seq_id) = be_u32(i)?;
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ let req = Nfs4RequestContent::OpenConfirm(Nfs4RequestOpenConfirm {
+ stateid
+ });
+ Ok((i, req))
+}
+
+fn nfs4_req_delegreturn(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(nfs4_parse_stateid, Nfs4RequestContent::DelegReturn)(i)
+}
+
+fn nfs4_req_renew(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(be_u64, Nfs4RequestContent::Renew)(i)
+}
+
+fn nfs4_req_getfh(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ Ok((i, Nfs4RequestContent::GetFH))
+}
+
+fn nfs4_req_savefh(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ Ok((i, Nfs4RequestContent::SaveFH))
+}
+
+fn nfs4_req_putrootfh(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ Ok((i, Nfs4RequestContent::PutRootFH))
+}
+
+fn nfs4_req_access(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ map(be_u32, Nfs4RequestContent::Access)(i)
+}
+
+fn nfs4_req_commit(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _offset) = be_u64(i)?;
+ let (i, _count) = be_u32(i)?;
+ Ok((i, Nfs4RequestContent::Commit))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestExchangeId<'a> {
pub nii_name: &'a[u8],
}
-named!(nfs4_req_exchangeid<Nfs4RequestContent>,
- do_parse!(
- _verifier: take!(8)
- >> eia_clientstring: nfs4_parse_nfsstring
- >> _eia_clientflags: be_u32
- >> _eia_state_protect: be_u32
- >> _eia_client_impl_id: be_u32
- >> nii_domain: nfs4_parse_nfsstring
- >> nii_name: nfs4_parse_nfsstring
- >> _nii_data_sec: be_u64
- >> _nii_data_nsec: be_u32
- >> (Nfs4RequestContent::ExchangeId(
- Nfs4RequestExchangeId {
- client_string: eia_clientstring,
- nii_domain,
- nii_name
- }
- ))
-));
+fn nfs4_req_exchangeid(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, _verifier) = take(8_usize)(i)?;
+ let (i, eia_clientstring) = nfs4_parse_nfsstring(i)?;
+ let (i, _eia_clientflags) = be_u32(i)?;
+ let (i, _eia_state_protect) = be_u32(i)?;
+ let (i, _eia_client_impl_id) = be_u32(i)?;
+ let (i, nii_domain) = nfs4_parse_nfsstring(i)?;
+ let (i, nii_name) = nfs4_parse_nfsstring(i)?;
+ let (i, _nii_data_sec) = be_u64(i)?;
+ let (i, _nii_data_nsec) = be_u32(i)?;
+ let req = Nfs4RequestContent::ExchangeId(Nfs4RequestExchangeId {
+ client_string: eia_clientstring,
+ nii_domain,
+ nii_name
+ });
+ Ok((i, req))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestSequence<'a> {
pub ssn_id: &'a[u8],
}
-named!(nfs4_req_sequence<Nfs4RequestContent>,
- do_parse!(
- ssn_id: take!(16)
- >> _seq_id: be_u32
- >> _slot_id: be_u32
- >> _high_slot_id: be_u32
- >> _cache_this: be_u32
- >> (Nfs4RequestContent::Sequence(
- Nfs4RequestSequence {
- ssn_id
- }
- ))
-));
-
-named!(parse_request_compound_command<Nfs4RequestContent>,
- do_parse!(
- cmd: be_u32
- >> cmd_data: switch!(value!(cmd),
- NFSPROC4_PUTFH => call!(nfs4_req_putfh) |
- NFSPROC4_READ => call!(nfs4_req_read) |
- NFSPROC4_WRITE => call!(nfs4_req_write) |
- NFSPROC4_GETFH => call!(nfs4_req_getfh) |
- NFSPROC4_SAVEFH => call!(nfs4_req_savefh) |
- NFSPROC4_OPEN => call!(nfs4_req_open) |
- NFSPROC4_CLOSE => call!(nfs4_req_close) |
- NFSPROC4_LOOKUP => call!(nfs4_req_lookup) |
- NFSPROC4_ACCESS => call!(nfs4_req_access) |
- NFSPROC4_COMMIT => call!(nfs4_req_commit) |
- NFSPROC4_GETATTR => call!(nfs4_req_getattr) |
- NFSPROC4_READDIR => call!(nfs4_req_readdir) |
- NFSPROC4_RENEW => call!(nfs4_req_renew) |
- NFSPROC4_OPEN_CONFIRM => call!(nfs4_req_open_confirm) |
- NFSPROC4_REMOVE => call!(nfs4_req_remove) |
- NFSPROC4_RENAME => call!(nfs4_req_rename) |
- NFSPROC4_CREATE => call!(nfs4_req_create) |
- NFSPROC4_DELEGRETURN => call!(nfs4_req_delegreturn) |
- NFSPROC4_SETATTR => call!(nfs4_req_setattr) |
- NFSPROC4_PUTROOTFH => call!(nfs4_req_putrootfh) |
- NFSPROC4_SETCLIENTID => call!(nfs4_req_setclientid) |
- NFSPROC4_SETCLIENTID_CONFIRM => call!(nfs4_req_setclientid_confirm) |
- NFSPROC4_SEQUENCE => call!(nfs4_req_sequence) |
- NFSPROC4_EXCHANGE_ID => call!(nfs4_req_exchangeid)
- )
- >> ( cmd_data )
-));
+fn nfs4_req_sequence(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, ssn_id) = take(16_usize)(i)?;
+ let (i, _seq_id) = be_u32(i)?;
+ let (i, _slot_id) = be_u32(i)?;
+ let (i, _high_slot_id) = be_u32(i)?;
+ let (i, _cache_this) = be_u32(i)?;
+ let req = Nfs4RequestContent::Sequence(Nfs4RequestSequence {
+ ssn_id
+ });
+ Ok((i, req))
+}
+
+fn parse_request_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+ let (i, cmd) = be_u32(i)?;
+ let (i, cmd_data) = match cmd {
+ NFSPROC4_PUTFH => nfs4_req_putfh(i)?,
+ NFSPROC4_READ => nfs4_req_read(i)?,
+ NFSPROC4_WRITE => nfs4_req_write(i)?,
+ NFSPROC4_GETFH => nfs4_req_getfh(i)?,
+ NFSPROC4_SAVEFH => nfs4_req_savefh(i)?,
+ NFSPROC4_OPEN => nfs4_req_open(i)?,
+ NFSPROC4_CLOSE => nfs4_req_close(i)?,
+ NFSPROC4_LOOKUP => nfs4_req_lookup(i)?,
+ NFSPROC4_ACCESS => nfs4_req_access(i)?,
+ NFSPROC4_COMMIT => nfs4_req_commit(i)?,
+ NFSPROC4_GETATTR => nfs4_req_getattr(i)?,
+ NFSPROC4_READDIR => nfs4_req_readdir(i)?,
+ NFSPROC4_RENEW => nfs4_req_renew(i)?,
+ NFSPROC4_OPEN_CONFIRM => nfs4_req_open_confirm(i)?,
+ NFSPROC4_REMOVE => nfs4_req_remove(i)?,
+ NFSPROC4_RENAME => nfs4_req_rename(i)?,
+ NFSPROC4_CREATE => nfs4_req_create(i)?,
+ NFSPROC4_DELEGRETURN => nfs4_req_delegreturn(i)?,
+ NFSPROC4_SETATTR => nfs4_req_setattr(i)?,
+ NFSPROC4_PUTROOTFH => nfs4_req_putrootfh(i)?,
+ NFSPROC4_SETCLIENTID => nfs4_req_setclientid(i)?,
+ NFSPROC4_SETCLIENTID_CONFIRM => nfs4_req_setclientid_confirm(i)?,
+ NFSPROC4_SEQUENCE => nfs4_req_sequence(i)?,
+ NFSPROC4_EXCHANGE_ID => nfs4_req_exchangeid(i)?,
+ _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
+ };
+ Ok((i, cmd_data))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestCompoundRecord<'a> {
pub commands: Vec<Nfs4RequestContent<'a>>,
}
-named!(pub parse_nfs4_request_compound<Nfs4RequestCompoundRecord>,
- do_parse!(
- tag_len: be_u32
- >> _tag: cond!(tag_len > 0, take!(tag_len))
- >> _min_ver: be_u32
- >> ops_cnt: be_u32
- >> commands: count!(parse_request_compound_command, ops_cnt as usize)
- >> (Nfs4RequestCompoundRecord {
- commands
- })
-));
+pub fn parse_nfs4_request_compound(i: &[u8]) -> IResult<&[u8], Nfs4RequestCompoundRecord> {
+ let (i, tag_len) = be_u32(i)?;
+ let (i, _tag) = cond(tag_len > 0, take(tag_len as usize))(i)?;
+ let (i, _min_ver) = be_u32(i)?;
+ let (i, ops_cnt) = be_u32(i)?;
+ let (i, commands) = count(parse_request_compound_command, ops_cnt as usize)(i)?;
+ Ok((i, Nfs4RequestCompoundRecord { commands }))
+}
#[derive(Debug,PartialEq)]
pub enum Nfs4ResponseContent<'a> {
pub committed: u32,
}
-named!(nfs4_res_write_ok<Nfs4ResponseWrite>,
- do_parse!(
- count: be_u32
- >> committed: be_u32
- >> _verifier: be_u64
- >> (Nfs4ResponseWrite {
- count,
- committed
- })
-));
-
-named!(nfs4_res_write<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> wd: cond!(status == 0, nfs4_res_write_ok)
- >> (Nfs4ResponseContent::Write(status, wd) )
-));
+fn nfs4_res_write_ok(i: &[u8]) -> IResult<&[u8], Nfs4ResponseWrite> {
+ let (i, count) = be_u32(i)?;
+ let (i, committed) = be_u32(i)?;
+ let (i, _verifier) = be_u64(i)?;
+ Ok((i, Nfs4ResponseWrite { count, committed }))
+}
+
+fn nfs4_res_write(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, wd) = cond(status == 0, nfs4_res_write_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::Write(status, wd)))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseRead<'a> {
pub data: &'a[u8],
}
-named!(nfs4_res_read_ok<Nfs4ResponseRead>,
- do_parse!(
- eof: be_u32
- >> read_len: be_u32
- >> read_data: take!(read_len)
- >> (Nfs4ResponseRead {
- eof: eof==1,
- count: read_len,
- data: read_data,
- })
-));
-
-named!(nfs4_res_read<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> rd: cond!(status == 0, nfs4_res_read_ok)
- >> (Nfs4ResponseContent::Read(status, rd) )
-));
+fn nfs4_res_read_ok(i: &[u8]) -> IResult<&[u8], Nfs4ResponseRead> {
+ let (i, eof) = be_u32(i)?;
+ let (i, read_len) = be_u32(i)?;
+ let (i, read_data) = take(read_len as usize)(i)?;
+ let resp = Nfs4ResponseRead {
+ eof: eof==1,
+ count: read_len,
+ data: read_data,
+ };
+ Ok((i, resp))
+}
+
+fn nfs4_res_read(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, rd) = cond(status == 0, nfs4_res_read_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::Read(status, rd)))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseOpen<'a> {
pub stateid: Nfs4StateId<'a>,
}
-named!(nfs4_res_open_ok_delegate_read<Nfs4ResponseOpenDelegateRead>,
- do_parse!(
- stateid: nfs4_parse_stateid
- >> _recall: be_u32
- >> _ace_type: be_u32
- >> _ace_flags: be_u32
- >> _ace_mask: be_u32
- >> who_len: be_u32
- >> _who: take!(who_len)
- >> (Nfs4ResponseOpenDelegateRead {
- stateid
- })
-));
-
-named!(nfs4_res_open_ok<Nfs4ResponseOpen>,
- do_parse!(
- stateid: nfs4_parse_stateid
- >> _change_info: take!(20)
- >> result_flags: be_u32
- >> _attrs: nfs4_parse_attrbits
- >> delegation_type: be_u32
- >> delegate_read: cond!(delegation_type == 1, nfs4_res_open_ok_delegate_read)
- >> ( Nfs4ResponseOpen {
- stateid,
- result_flags,
- delegation_type,
- delegate_read
- } )
-));
-
-named!(nfs4_res_open<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> open_data: cond!(status == 0, nfs4_res_open_ok)
- >> ( Nfs4ResponseContent::Open(status, open_data) )
-));
+fn nfs4_res_open_ok_delegate_read(i: &[u8]) -> IResult<&[u8], Nfs4ResponseOpenDelegateRead> {
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ let (i, _recall) = be_u32(i)?;
+ let (i, _ace_type) = be_u32(i)?;
+ let (i, _ace_flags) = be_u32(i)?;
+ let (i, _ace_mask) = be_u32(i)?;
+ let (i, who_len) = be_u32(i)?;
+ let (i, _who) = take(who_len as usize)(i)?;
+ Ok((i, Nfs4ResponseOpenDelegateRead { stateid }))
+}
+
+fn nfs4_res_open_ok(i: &[u8]) -> IResult<&[u8], Nfs4ResponseOpen> {
+ let (i, stateid) = nfs4_parse_stateid(i)?;
+ let (i, _change_info) = take(20_usize)(i)?;
+ let (i, result_flags) = be_u32(i)?;
+ let (i, _attrs) = nfs4_parse_attrbits(i)?;
+ let (i, delegation_type) = be_u32(i)?;
+ let (i, delegate_read) = cond(delegation_type == 1, nfs4_res_open_ok_delegate_read)(i)?;
+ let resp = Nfs4ResponseOpen {
+ stateid,
+ result_flags,
+ delegation_type,
+ delegate_read
+ };
+ Ok((i, resp))
+}
+
+fn nfs4_res_open(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, open_data) = cond(status == 0, nfs4_res_open_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::Open(status, open_data)))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseReaddirEntry<'a> {
pub listing: Vec<Option<Nfs4ResponseReaddirEntry<'a>>>,
}
-named!(nfs4_res_readdir_entry_do<Nfs4ResponseReaddirEntry>,
- do_parse!(
- _cookie: be_u64
- >> name: nfs4_parse_nfsstring
- >> _attrs: nfs4_parse_attrs
- >> ( Nfs4ResponseReaddirEntry {
- name: name,
- })
-));
-
-named!(nfs4_res_readdir_entry<Option<Nfs4ResponseReaddirEntry>>,
- do_parse!(
- value_follows: be_u32
- >> entry: cond!(value_follows == 1, nfs4_res_readdir_entry_do)
- >> (entry)
-));
-
-named!(nfs4_res_readdir_ok<Nfs4ResponseReaddir>,
- do_parse!(
- _verifier: be_u64
- // run parser until we find a 'value follows == 0'
- >> listing: many_till!(complete!(call!(nfs4_res_readdir_entry)), peek!(tag!(b"\x00\x00\x00\x00")))
- // value follows == 0 checked by line above
- >> _value_follows: be_u32
- >> eof: be_u32
- >> ( Nfs4ResponseReaddir { eof: eof==1, listing: listing.0 })
-));
-
-named!(nfs4_res_readdir<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> rd: cond!(status == 0, nfs4_res_readdir_ok)
- >> ( Nfs4ResponseContent::ReadDir(status, rd) )
-));
-
-named!(nfs4_res_create_ok<Nfs4Attr>,
- do_parse!(
- _change_info: take!(20)
- >> attrs: nfs4_parse_attrbits
- >> ( attrs )
-));
-
-named!(nfs4_res_create<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> _attrs: cond!(status == 0, nfs4_res_create_ok)
- >> ( Nfs4ResponseContent::Create(status) )
-));
-
-named!(nfs4_res_setattr_ok<Nfs4Attr>,
- do_parse!(
- attrs: nfs4_parse_attrbits
- >> ( attrs )
-));
-
-named!(nfs4_res_setattr<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> _attrs: cond!(status == 0, nfs4_res_setattr_ok)
- >> ( Nfs4ResponseContent::SetAttr(status) )
-));
-
-named!(nfs4_res_getattr_ok<Nfs4Attr>,
- do_parse!(
- attrs: nfs4_parse_attrs
- >> ( attrs )
-));
-
-named!(nfs4_res_getattr<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> attrs: cond!(status == 0, nfs4_res_getattr_ok)
- >> ( Nfs4ResponseContent::GetAttr(status, attrs) )
-));
-
-named!(nfs4_res_openconfirm<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> stateid: cond!(status == 0, nfs4_parse_stateid)
- >> ( Nfs4ResponseContent::OpenConfirm(status, stateid) )
-));
-
-named!(nfs4_res_close<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> stateid: cond!(status == 0, nfs4_parse_stateid)
- >> ( Nfs4ResponseContent::Close(status, stateid) )
-));
-
-named!(nfs4_res_remove<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> cond!(status == 0, take!(20)) // change_info
- >> ( Nfs4ResponseContent::Remove(status) )
-));
-
-named!(nfs4_res_rename<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::Rename(status) )
-));
-
-named!(nfs4_res_savefh<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::SaveFH(status) )
-));
-
-named!(nfs4_res_lookup<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::Lookup(status) )
-));
-
-named!(nfs4_res_renew<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::Renew(status) )
-));
-
-named!(nfs4_res_getfh<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> fh: cond!(status == 0, nfs4_parse_handle)
- >> ( Nfs4ResponseContent::GetFH(status, fh) )
-));
-
-named!(nfs4_res_putfh<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::PutFH(status) )
-));
-
-named!(nfs4_res_putrootfh<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::PutRootFH(status) )
-));
-
-named!(nfs4_res_delegreturn<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::DelegReturn(status) )
-));
-
-named!(nfs4_res_setclientid<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> _client_id: be_u64
- >> _verifier: be_u32
- >> ( Nfs4ResponseContent::SetClientId(status) )
-));
-
-named!(nfs4_res_setclientid_confirm<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ( Nfs4ResponseContent::SetClientIdConfirm(status) )
-));
-
-named!(nfs4_res_commit<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> _verifier: cond!(status == 0, take!(8))
- >> ( Nfs4ResponseContent::Commit(status))
-));
+fn nfs4_res_readdir_entry_do(i: &[u8]) -> IResult<&[u8], Nfs4ResponseReaddirEntry> {
+ let (i, _cookie) = be_u64(i)?;
+ let (i, name) = nfs4_parse_nfsstring(i)?;
+ let (i, _attrs) = nfs4_parse_attrs(i)?;
+ Ok((i, Nfs4ResponseReaddirEntry { name }))
+}
+
+fn nfs4_res_readdir_entry(i: &[u8]) -> IResult<&[u8], Option<Nfs4ResponseReaddirEntry>> {
+ let (i, value_follows) = be_u32(i)?;
+ let (i, entry) = cond(value_follows == 1, nfs4_res_readdir_entry_do)(i)?;
+ Ok((i, entry))
+}
+
+fn nfs4_res_readdir_ok(i: &[u8]) -> IResult<&[u8], Nfs4ResponseReaddir> {
+ let (i, _verifier) = be_u64(i)?;
+ // run parser until we find a 'value follows == 0'
+ let (i, listing) = many_till(
+ complete(nfs4_res_readdir_entry),
+ peek(tag(b"\x00\x00\x00\x00")),
+ )(i)?;
+ // value follows == 0 checked by line above
+ let (i, _value_follows) = be_u32(i)?;
+ let (i, eof) = be_u32(i)?;
+ Ok((
+ i,
+ Nfs4ResponseReaddir {
+ eof: eof == 1,
+ listing: listing.0,
+ },
+ ))
+}
+
+fn nfs4_res_readdir(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, rd) = cond(status == 0, nfs4_res_readdir_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::ReadDir(status, rd)))
+}
+
+fn nfs4_res_create_ok(i: &[u8]) -> IResult<&[u8], Nfs4Attr> {
+ let (i, _change_info) = take(20_usize)(i)?;
+ nfs4_parse_attrbits(i)
+}
+
+fn nfs4_res_create(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, _attrs) = cond(status == 0, nfs4_res_create_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::Create(status)))
+}
+
+fn nfs4_res_setattr_ok(i: &[u8]) -> IResult<&[u8], Nfs4Attr> {
+ nfs4_parse_attrbits(i)
+}
+
+fn nfs4_res_setattr(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, _attrs) = cond(status == 0, nfs4_res_setattr_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::SetAttr(status)))
+}
+
+fn nfs4_res_getattr_ok(i: &[u8]) -> IResult<&[u8], Nfs4Attr> {
+ nfs4_parse_attrs(i)
+}
+
+fn nfs4_res_getattr(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, attrs) = cond(status == 0, nfs4_res_getattr_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::GetAttr(status, attrs)))
+}
+
+fn nfs4_res_openconfirm(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, stateid) = cond(status == 0, nfs4_parse_stateid)(i)?;
+ Ok((i, Nfs4ResponseContent::OpenConfirm(status, stateid)))
+}
+
+fn nfs4_res_close(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, stateid) = cond(status == 0, nfs4_parse_stateid)(i)?;
+ Ok((i, Nfs4ResponseContent::Close(status, stateid)))
+}
+
+fn nfs4_res_remove(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, _) = cond(status == 0, take(20_usize))(i)?;
+ Ok((i, Nfs4ResponseContent::Remove(status)))
+}
+
+fn nfs4_res_rename(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::Rename)(i)
+}
+
+fn nfs4_res_savefh(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::SaveFH)(i)
+}
+
+fn nfs4_res_lookup(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::Lookup)(i)
+}
+
+fn nfs4_res_renew(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::Renew)(i)
+}
+
+fn nfs4_res_getfh(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, fh) = cond(status == 0, nfs4_parse_handle)(i)?;
+ Ok((i, Nfs4ResponseContent::GetFH(status, fh)))
+}
+
+fn nfs4_res_putfh(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::PutFH)(i)
+}
+
+fn nfs4_res_putrootfh(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::PutRootFH)(i)
+}
+
+fn nfs4_res_delegreturn(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::DelegReturn)(i)
+}
+
+fn nfs4_res_setclientid(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, _client_id) = be_u64(i)?;
+ let (i, _verifier) = be_u32(i)?;
+ Ok((i, Nfs4ResponseContent::SetClientId(status)))
+}
+
+fn nfs4_res_setclientid_confirm(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ map(be_u32, Nfs4ResponseContent::SetClientIdConfirm)(i)
+}
+
+fn nfs4_res_commit(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, _verifier) = cond(status == 0, take(8_usize))(i)?;
+ Ok((i, Nfs4ResponseContent::Commit(status)))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseAccess {
pub access_rights: u32,
}
-named!(nfs4_res_access_ok<Nfs4ResponseAccess>,
- do_parse!(
- s: be_u32
- >> a: be_u32
- >> (Nfs4ResponseAccess {
- supported_types: s,
- access_rights: a,
- })
-));
-
-named!(nfs4_res_access<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> ad: cond!(status == 0, nfs4_res_access_ok)
- >> ( Nfs4ResponseContent::Access(
- status, ad, ))
-));
+fn nfs4_res_access_ok(i: &[u8]) -> IResult<&[u8], Nfs4ResponseAccess> {
+ let (i, supported_types) = be_u32(i)?;
+ let (i, access_rights) = be_u32(i)?;
+ let resp = Nfs4ResponseAccess {
+ supported_types,
+ access_rights
+ };
+ Ok((i, resp))
+}
+fn nfs4_res_access(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, ad) = cond(status == 0, nfs4_res_access_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::Access(status, ad)))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseSequence<'a> {
pub ssn_id: &'a[u8],
}
-named!(nfs4_res_sequence_ok<Nfs4ResponseSequence>,
- do_parse!(
- ssn_id: take!(16)
- >> _slots: take!(12)
- >> _flags: be_u32
- >> ( Nfs4ResponseSequence {
- ssn_id: ssn_id,
- })
-));
-
-named!(nfs4_res_sequence<Nfs4ResponseContent>,
- do_parse!(
- status: be_u32
- >> seq: cond!(status == 0, nfs4_res_sequence_ok)
- >> ( Nfs4ResponseContent::Sequence(status, seq) )
-));
-
-named!(nfs4_res_compound_command<Nfs4ResponseContent>,
- do_parse!(
- cmd: be_u32
- >> cmd_data: switch!(value!(cmd),
- NFSPROC4_READ => call!(nfs4_res_read) |
- NFSPROC4_WRITE => call!(nfs4_res_write) |
- NFSPROC4_ACCESS => call!(nfs4_res_access) |
- NFSPROC4_COMMIT => call!(nfs4_res_commit) |
- NFSPROC4_GETFH => call!(nfs4_res_getfh) |
- NFSPROC4_PUTFH => call!(nfs4_res_putfh) |
- NFSPROC4_SAVEFH => call!(nfs4_res_savefh) |
- NFSPROC4_RENAME => call!(nfs4_res_rename) |
- NFSPROC4_READDIR => call!(nfs4_res_readdir) |
- NFSPROC4_GETATTR => call!(nfs4_res_getattr) |
- NFSPROC4_SETATTR => call!(nfs4_res_setattr) |
- NFSPROC4_LOOKUP => call!(nfs4_res_lookup) |
- NFSPROC4_OPEN => call!(nfs4_res_open) |
- NFSPROC4_OPEN_CONFIRM => call!(nfs4_res_openconfirm) |
- NFSPROC4_CLOSE => call!(nfs4_res_close) |
- NFSPROC4_REMOVE => call!(nfs4_res_remove) |
- NFSPROC4_CREATE => call!(nfs4_res_create) |
- NFSPROC4_DELEGRETURN => call!(nfs4_res_delegreturn) |
- NFSPROC4_SETCLIENTID => call!(nfs4_res_setclientid) |
- NFSPROC4_SETCLIENTID_CONFIRM => call!(nfs4_res_setclientid_confirm) |
- NFSPROC4_PUTROOTFH => call!(nfs4_res_putrootfh) |
- NFSPROC4_SEQUENCE => call!(nfs4_res_sequence) |
- NFSPROC4_RENEW => call!(nfs4_res_renew))
- >> (cmd_data)
-));
+fn nfs4_res_sequence_ok(i: &[u8]) -> IResult<&[u8], Nfs4ResponseSequence> {
+ let (i, ssn_id) = take(16_usize)(i)?;
+ let (i, _slots) = take(12_usize)(i)?;
+ let (i, _flags) = be_u32(i)?;
+ Ok((i, Nfs4ResponseSequence { ssn_id }))
+}
+
+fn nfs4_res_sequence(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, status) = be_u32(i)?;
+ let (i, seq) = cond(status == 0, nfs4_res_sequence_ok)(i)?;
+ Ok((i, Nfs4ResponseContent::Sequence(status, seq)))
+}
+
+fn nfs4_res_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+ let (i, cmd) = be_u32(i)?;
+ let (i, cmd_data) = match cmd {
+ NFSPROC4_READ => nfs4_res_read(i)?,
+ NFSPROC4_WRITE => nfs4_res_write(i)?,
+ NFSPROC4_ACCESS => nfs4_res_access(i)?,
+ NFSPROC4_COMMIT => nfs4_res_commit(i)?,
+ NFSPROC4_GETFH => nfs4_res_getfh(i)?,
+ NFSPROC4_PUTFH => nfs4_res_putfh(i)?,
+ NFSPROC4_SAVEFH => nfs4_res_savefh(i)?,
+ NFSPROC4_RENAME => nfs4_res_rename(i)?,
+ NFSPROC4_READDIR => nfs4_res_readdir(i)?,
+ NFSPROC4_GETATTR => nfs4_res_getattr(i)?,
+ NFSPROC4_SETATTR => nfs4_res_setattr(i)?,
+ NFSPROC4_LOOKUP => nfs4_res_lookup(i)?,
+ NFSPROC4_OPEN => nfs4_res_open(i)?,
+ NFSPROC4_OPEN_CONFIRM => nfs4_res_openconfirm(i)?,
+ NFSPROC4_CLOSE => nfs4_res_close(i)?,
+ NFSPROC4_REMOVE => nfs4_res_remove(i)?,
+ NFSPROC4_CREATE => nfs4_res_create(i)?,
+ NFSPROC4_DELEGRETURN => nfs4_res_delegreturn(i)?,
+ NFSPROC4_SETCLIENTID => nfs4_res_setclientid(i)?,
+ NFSPROC4_SETCLIENTID_CONFIRM => nfs4_res_setclientid_confirm(i)?,
+ NFSPROC4_PUTROOTFH => nfs4_res_putrootfh(i)?,
+ NFSPROC4_SEQUENCE => nfs4_res_sequence(i)?,
+ NFSPROC4_RENEW => nfs4_res_renew(i)?,
+ _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
+ };
+ Ok((i, cmd_data))
+}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseCompoundRecord<'a> {
pub commands: Vec<Nfs4ResponseContent<'a>>,
}
-named!(pub parse_nfs4_response_compound<Nfs4ResponseCompoundRecord>,
- do_parse!(
- status: be_u32
- >> tag_len: be_u32
- >> _tag: cond!(tag_len > 0, take!(tag_len))
- >> ops_cnt: be_u32
- >> commands: count!(nfs4_res_compound_command, ops_cnt as usize)
- >> (Nfs4ResponseCompoundRecord {
- status: status,
- commands: commands,
- })
-));
+pub fn parse_nfs4_response_compound(i: &[u8]) -> IResult<&[u8], Nfs4ResponseCompoundRecord> {
+ let (i, status) = be_u32(i)?;
+ let (i, tag_len) = be_u32(i)?;
+ let (i, _tag) = cond(tag_len > 0, take(tag_len as usize))(i)?;
+ let (i, ops_cnt) = be_u32(i)?;
+ let (i, commands) = count(nfs4_res_compound_command, ops_cnt as usize)(i)?;
+ Ok((i, Nfs4ResponseCompoundRecord { status, commands }))
+}
//! Nom parsers for RPCv2
-use nom::IResult;
-use nom::combinator::rest;
-use nom::number::streaming::be_u32;
-
-#[derive(Debug,PartialEq)]
+use nom7::bits::{bits, streaming::take as take_bits};
+use nom7::bytes::streaming::take;
+use nom7::combinator::cond;
+use nom7::error::Error;
+use nom7::multi::length_data;
+use nom7::number::streaming::be_u32;
+use nom7::sequence::tuple;
+use nom7::IResult;
+
+#[derive(Debug, PartialEq)]
pub enum RpcRequestCreds<'a> {
Unix(RpcRequestCredsUnix<'a>),
GssApi(RpcRequestCredsGssApi<'a>),
- Unknown(&'a[u8]),
+ Unknown(&'a [u8]),
}
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct RpcRequestCredsUnix<'a> {
pub stamp: u32,
pub machine_name_len: u32,
- pub machine_name_buf: &'a[u8],
+ pub machine_name_buf: &'a [u8],
pub uid: u32,
pub gid: u32,
pub aux_gids: Option<Vec<u32>>,
// many0!(be_u32)
//);
-named!(parse_rpc_request_creds_unix<RpcRequestCreds>,
- do_parse!(
- stamp: be_u32
- >> machine_name_len: be_u32
- >> machine_name_buf: take!(machine_name_len)
- >> uid: be_u32
- >> gid: be_u32
- //>>aux_gids: parse_rpc_creds_unix_aux_gids
- >> (RpcRequestCreds::Unix(RpcRequestCredsUnix {
- stamp:stamp,
- machine_name_len:machine_name_len,
- machine_name_buf:machine_name_buf,
- uid:uid,
- gid:gid,
- aux_gids:None,
- }))
-));
-
-#[derive(Debug,PartialEq)]
+fn parse_rpc_request_creds_unix(i: &[u8]) -> IResult<&[u8], RpcRequestCreds> {
+ let (i, stamp) = be_u32(i)?;
+ let (i, machine_name_len) = be_u32(i)?;
+ let (i, machine_name_buf) = take(machine_name_len as usize)(i)?;
+ let (i, uid) = be_u32(i)?;
+ let (i, gid) = be_u32(i)?;
+ // let (i, aux_gids) = parse_rpc_creds_unix_aux_gids(i)?;
+ let creds = RpcRequestCreds::Unix(RpcRequestCredsUnix {
+ stamp,
+ machine_name_len,
+ machine_name_buf,
+ uid,
+ gid,
+ aux_gids: None,
+ });
+ Ok((i, creds))
+}
+
+#[derive(Debug, PartialEq)]
pub struct RpcRequestCredsGssApi<'a> {
pub version: u32,
pub procedure: u32,
pub seq_num: u32,
pub service: u32,
- pub ctx: &'a[u8],
+ pub ctx: &'a [u8],
}
-named!(parse_rpc_request_creds_gssapi<RpcRequestCreds>,
- do_parse!(
- version: be_u32
- >> procedure: be_u32
- >> seq_num: be_u32
- >> service: be_u32
- >> ctx_len: be_u32
- >> ctx: take!(ctx_len)
- >> (RpcRequestCreds::GssApi(RpcRequestCredsGssApi {
- version: version,
- procedure: procedure,
- seq_num: seq_num,
- service: service,
- ctx: ctx,
- }))
-));
-
-named!(parse_rpc_request_creds_unknown<RpcRequestCreds>,
- do_parse!(
- blob: rest
- >> (RpcRequestCreds::Unknown(blob) )
-));
-
-#[derive(Debug,PartialEq)]
+fn parse_rpc_request_creds_gssapi(i: &[u8]) -> IResult<&[u8], RpcRequestCreds> {
+ let (i, version) = be_u32(i)?;
+ let (i, procedure) = be_u32(i)?;
+ let (i, seq_num) = be_u32(i)?;
+ let (i, service) = be_u32(i)?;
+ let (i, ctx) = length_data(be_u32)(i)?;
+ let creds = RpcRequestCreds::GssApi(RpcRequestCredsGssApi {
+ version,
+ procedure,
+ seq_num,
+ service,
+ ctx,
+ });
+ Ok((i, creds))
+}
+
+fn parse_rpc_request_creds_unknown(i: &[u8]) -> IResult<&[u8], RpcRequestCreds> {
+ Ok((&[], RpcRequestCreds::Unknown(i)))
+}
+
+#[derive(Debug, PartialEq)]
pub struct RpcGssApiIntegrity<'a> {
pub seq_num: u32,
- pub data: &'a[u8],
+ pub data: &'a [u8],
}
// Parse the GSSAPI Integrity envelope to get to the
// data we care about.
-named!(pub parse_rpc_gssapi_integrity<RpcGssApiIntegrity>,
- do_parse!(
- len: be_u32
- >> seq_num: be_u32
- >> data: take!(len)
- >> (RpcGssApiIntegrity {
- seq_num: seq_num,
- data: data,
- })
-));
-
-#[derive(Debug,PartialEq)]
-pub struct RpcPacketHeader<> {
+pub fn parse_rpc_gssapi_integrity(i: &[u8]) -> IResult<&[u8], RpcGssApiIntegrity> {
+ let (i, len) = be_u32(i)?;
+ let (i, seq_num) = be_u32(i)?;
+ let (i, data) = take(len as usize)(i)?;
+ let res = RpcGssApiIntegrity { seq_num, data };
+ Ok((i, res))
+}
+
+#[derive(Debug, PartialEq)]
+pub struct RpcPacketHeader {
pub frag_is_last: bool,
pub frag_len: u32,
pub xid: u32,
pub msgtype: u32,
}
-fn parse_bits(i:&[u8]) -> IResult<&[u8],(u8,u32)> {
- bits!(i,
- tuple!(
- take_bits!(1u8), // is_last
- take_bits!(31u32))) // len
+fn parse_bits(i: &[u8]) -> IResult<&[u8], (u8, u32)> {
+ bits::<_, _, Error<(&[u8], usize)>, _, _>(tuple((
+ take_bits(1u8), // is_last
+ take_bits(31u32), // len
+ )))(i)
+}
+
+pub fn parse_rpc_packet_header(i: &[u8]) -> IResult<&[u8], RpcPacketHeader> {
+ let (i, fraghdr) = parse_bits(i)?;
+ let (i, xid) = be_u32(i)?;
+ let (i, msgtype) = be_u32(i)?;
+ let hdr = RpcPacketHeader {
+ frag_is_last: fraghdr.0 == 1,
+ frag_len: fraghdr.1,
+ xid,
+ msgtype,
+ };
+ Ok((i, hdr))
}
-named!(pub parse_rpc_packet_header<RpcPacketHeader>,
- do_parse!(
- fraghdr: parse_bits
- >> xid: be_u32
- >> msgtype: be_u32
- >> (
- RpcPacketHeader {
- frag_is_last:fraghdr.0 == 1,
- frag_len:fraghdr.1,
- xid:xid,
- msgtype:msgtype,
- }
- ))
-);
-
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct RpcReplyPacket<'a> {
- pub hdr: RpcPacketHeader<>,
+ pub hdr: RpcPacketHeader,
pub verifier_flavor: u32,
pub verifier_len: u32,
- pub verifier: Option<&'a[u8]>,
+ pub verifier: Option<&'a [u8]>,
pub reply_state: u32,
pub accept_state: u32,
- pub prog_data: &'a[u8],
+ pub prog_data: &'a [u8],
}
// top of request packet, just to get to procedure
-#[derive(Debug,PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct RpcRequestPacketPartial {
pub hdr: RpcPacketHeader,
pub procedure: u32,
}
-named!(pub parse_rpc_request_partial<RpcRequestPacketPartial>,
- do_parse!(
- hdr: parse_rpc_packet_header
- >> rpcver: be_u32
- >> program: be_u32
- >> progver: be_u32
- >> procedure: be_u32
- >> (
- RpcRequestPacketPartial {
- hdr:hdr,
- rpcver:rpcver,
- program:program,
- progver:progver,
- procedure:procedure,
- }
- ))
-);
-
-#[derive(Debug,PartialEq)]
+pub fn parse_rpc_request_partial(i: &[u8]) -> IResult<&[u8], RpcRequestPacketPartial> {
+ let (i, hdr) = parse_rpc_packet_header(i)?;
+ let (i, rpcver) = be_u32(i)?;
+ let (i, program) = be_u32(i)?;
+ let (i, progver) = be_u32(i)?;
+ let (i, procedure) = be_u32(i)?;
+ let req = RpcRequestPacketPartial {
+ hdr,
+ rpcver,
+ program,
+ progver,
+ procedure,
+ };
+ Ok((i, req))
+}
+
+#[derive(Debug, PartialEq)]
pub struct RpcPacket<'a> {
- pub hdr: RpcPacketHeader<>,
+ pub hdr: RpcPacketHeader,
pub rpcver: u32,
pub program: u32,
pub verifier_flavor: u32,
pub verifier_len: u32,
- pub verifier: &'a[u8],
+ pub verifier: &'a [u8],
- pub prog_data: &'a[u8],
+ pub prog_data: &'a [u8],
}
-named!(pub parse_rpc<RpcPacket>,
- do_parse!(
- hdr: parse_rpc_packet_header
-
- >> rpcver: be_u32
- >> program: be_u32
- >> progver: be_u32
- >> procedure: be_u32
-
- >> creds_flavor: be_u32
- >> creds_len: be_u32
- >> creds: flat_map!(take!(creds_len), switch!(value!(creds_flavor),
- 1 => call!(parse_rpc_request_creds_unix) |
- 6 => call!(parse_rpc_request_creds_gssapi) |
- _ => call!(parse_rpc_request_creds_unknown) ))
-
- >> verifier_flavor: be_u32
- >> verifier_len: be_u32
- >> verifier: take!(verifier_len as usize)
-
- >> pl: rest
-
- >> (
- RpcPacket {
- hdr:hdr,
-
- rpcver:rpcver,
- program:program,
- progver:progver,
- procedure:procedure,
-
- creds_flavor:creds_flavor,
- creds:creds,
-
- verifier_flavor:verifier_flavor,
- verifier_len:verifier_len,
- verifier:verifier,
-
- prog_data:pl,
- }
- ))
-);
+pub fn parse_rpc(i: &[u8]) -> IResult<&[u8], RpcPacket> {
+ let (i, hdr) = parse_rpc_packet_header(i)?;
+
+ let (i, rpcver) = be_u32(i)?;
+ let (i, program) = be_u32(i)?;
+ let (i, progver) = be_u32(i)?;
+ let (i, procedure) = be_u32(i)?;
+
+ let (i, creds_flavor) = be_u32(i)?;
+ let (i, creds_len) = be_u32(i)?;
+ let (i, creds_buf) = take(creds_len as usize)(i)?;
+ let (_, creds) = match creds_flavor {
+ 1 => parse_rpc_request_creds_unix(creds_buf)?,
+ 6 => parse_rpc_request_creds_gssapi(creds_buf)?,
+ _ => parse_rpc_request_creds_unknown(creds_buf)?,
+ };
+
+ let (i, verifier_flavor) = be_u32(i)?;
+ let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier) = take(verifier_len as usize)(i)?;
+
+ let (i, prog_data) = (&[], i);
+ let packet = RpcPacket {
+ hdr,
+
+ rpcver,
+ program,
+ progver,
+ procedure,
+
+ creds_flavor,
+ creds,
+
+ verifier_flavor,
+ verifier_len,
+ verifier,
+
+ prog_data,
+ };
+ Ok((i, packet))
+}
// to be called with data <= hdr.frag_len + 4. Sending more data is undefined.
-named!(pub parse_rpc_reply<RpcReplyPacket>,
- do_parse!(
- hdr: parse_rpc_packet_header
-
- >> reply_state: be_u32
-
- >> verifier_flavor: be_u32
- >> verifier_len: be_u32
- >> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
-
- >> accept_state: be_u32
-
- >> pl: rest
-
- >> (
- RpcReplyPacket {
- hdr:hdr,
-
- verifier_flavor:verifier_flavor,
- verifier_len:verifier_len,
- verifier:verifier,
-
- reply_state:reply_state,
- accept_state:accept_state,
-
- prog_data:pl,
- }
- ))
-);
+pub fn parse_rpc_reply(i: &[u8]) -> IResult<&[u8], RpcReplyPacket> {
+ let (i, hdr) = parse_rpc_packet_header(i)?;
-named!(pub parse_rpc_udp_packet_header<RpcPacketHeader>,
- do_parse!(
- xid: be_u32
- >> msgtype: be_u32
- >> (
- RpcPacketHeader {
- frag_is_last:false,
- frag_len:0,
+ let (i, reply_state) = be_u32(i)?;
- xid:xid,
- msgtype:msgtype,
- }
- ))
-);
+ let (i, verifier_flavor) = be_u32(i)?;
+ let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier) = cond(verifier_len > 0, take(verifier_len as usize))(i)?;
-named!(pub parse_rpc_udp_request<RpcPacket>,
- do_parse!(
- hdr: parse_rpc_udp_packet_header
+ let (i, accept_state) = be_u32(i)?;
+ let (i, prog_data) = (&[], i);
+ let packet = RpcReplyPacket {
+ hdr,
- >> rpcver: be_u32
- >> program: be_u32
- >> progver: be_u32
- >> procedure: be_u32
+ verifier_flavor,
+ verifier_len,
+ verifier,
- >> creds_flavor: be_u32
- >> creds_len: be_u32
- >> creds: flat_map!(take!(creds_len), switch!(value!(creds_flavor),
- 1 => call!(parse_rpc_request_creds_unix) |
- 6 => call!(parse_rpc_request_creds_gssapi) |
- _ => call!(parse_rpc_request_creds_unknown) ))
+ reply_state,
+ accept_state,
- >> verifier_flavor: be_u32
- >> verifier_len: be_u32
- >> verifier: take!(verifier_len as usize)
-
- >> pl: rest
-
- >> (
- RpcPacket {
- hdr:hdr,
-
- rpcver:rpcver,
- program:program,
- progver:progver,
- procedure:procedure,
-
- creds_flavor:creds_flavor,
- creds:creds,
-
- verifier_flavor:verifier_flavor,
- verifier_len:verifier_len,
- verifier:verifier,
-
- prog_data:pl,
- }
- ))
-);
+ prog_data,
+ };
+ Ok((i, packet))
+}
-named!(pub parse_rpc_udp_reply<RpcReplyPacket>,
- do_parse!(
- hdr: parse_rpc_udp_packet_header
+pub fn parse_rpc_udp_packet_header(i: &[u8]) -> IResult<&[u8], RpcPacketHeader> {
+ let (i, xid) = be_u32(i)?;
+ let (i, msgtype) = be_u32(i)?;
+ let hdr = RpcPacketHeader {
+ frag_is_last: false,
+ frag_len: 0,
+
+ xid,
+ msgtype,
+ };
+ Ok((i, hdr))
+}
- >> verifier_flavor: be_u32
- >> verifier_len: be_u32
- >> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
+pub fn parse_rpc_udp_request(i: &[u8]) -> IResult<&[u8], RpcPacket> {
+ let (i, hdr) = parse_rpc_udp_packet_header(i)?;
+
+ let (i, rpcver) = be_u32(i)?;
+ let (i, program) = be_u32(i)?;
+ let (i, progver) = be_u32(i)?;
+ let (i, procedure) = be_u32(i)?;
+
+ let (i, creds_flavor) = be_u32(i)?;
+ let (i, creds_len) = be_u32(i)?;
+ let (i, creds_buf) = take(creds_len as usize)(i)?;
+ let (_, creds) = match creds_flavor {
+ 1 => parse_rpc_request_creds_unix(creds_buf)?,
+ 6 => parse_rpc_request_creds_gssapi(creds_buf)?,
+ _ => parse_rpc_request_creds_unknown(creds_buf)?,
+ };
+
+ let (i, verifier_flavor) = be_u32(i)?;
+ let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier) = take(verifier_len as usize)(i)?;
+
+ let (i, prog_data) = (&[], i);
+ let packet = RpcPacket {
+ hdr,
+
+ rpcver,
+ program,
+ progver,
+ procedure,
+
+ creds_flavor,
+ creds,
+
+ verifier_flavor,
+ verifier_len,
+ verifier,
+
+ prog_data,
+ };
+ Ok((i, packet))
+}
- >> reply_state: be_u32
- >> accept_state: be_u32
+pub fn parse_rpc_udp_reply(i: &[u8]) -> IResult<&[u8], RpcReplyPacket> {
+ let (i, hdr) = parse_rpc_udp_packet_header(i)?;
- >> pl: rest
+ let (i, verifier_flavor) = be_u32(i)?;
+ let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier) = cond(verifier_len > 0, take(verifier_len as usize))(i)?;
- >> (
- RpcReplyPacket {
- hdr:hdr,
+ let (i, reply_state) = be_u32(i)?;
+ let (i, accept_state) = be_u32(i)?;
+ let (i, prog_data) = (&[], i);
+ let packet = RpcReplyPacket {
+ hdr,
- verifier_flavor:verifier_flavor,
- verifier_len:verifier_len,
- verifier:verifier,
+ verifier_flavor,
+ verifier_len,
+ verifier,
- reply_state:reply_state,
- accept_state:accept_state,
+ reply_state,
+ accept_state,
- prog_data:pl,
- }
- ))
-);
+ prog_data,
+ };
+ Ok((i, packet))
+}
#[cfg(test)]
mod tests {
use crate::nfs::rpc_records::*;
- use nom::Err::Incomplete;
- use nom::Needed::Size;
+ use nom7::Err::Incomplete;
+ use nom7::Needed;
#[test]
fn test_partial_input_too_short() {
let r = parse_rpc_request_partial(buf);
match r {
- Err(Incomplete(s)) => { assert_eq!(s, Size(4)); },
+ Err(Incomplete(s)) => { assert_eq!(s, Needed::new(4)); },
_ => { panic!("failed {:?}",r); }
}
}