use nom::number::streaming::{be_u32, be_u64};
use crate::nfs::types::*;
#[derive(Debug,PartialEq)]
pub enum Nfs4RequestContent<'a> {
PutFH(Nfs4Handle<'a>),
GetFH,
SaveFH,
PutRootFH,
ReadDir,
Commit,
Open(Nfs4RequestOpen<'a>),
Lookup(Nfs4RequestLookup<'a>),
Read(Nfs4RequestRead<'a>),
Write(Nfs4RequestWrite<'a>),
Close(Nfs4StateId<'a>),
Rename(Nfs4RequestRename<'a>),
Create(Nfs4RequestCreate<'a>),
OpenConfirm(Nfs4RequestOpenConfirm<'a>),
Access(u32),
GetAttr(Nfs4Attr),
SetAttr(Nfs4RequestSetAttr<'a>),
Renew(u64),
Remove(&'a[u8]),
DelegReturn(Nfs4StateId<'a>),
SetClientId(Nfs4RequestSetClientId<'a>),
SetClientIdConfirm,
ExchangeId(Nfs4RequestExchangeId<'a>),
Sequence(Nfs4RequestSequence<'a>),
}
#[derive(Debug,PartialEq)]
pub struct Nfs4Attr {
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,
} )
));
#[derive(Debug,PartialEq)]
pub struct Nfs4StateId<'a> {
pub seqid: u32,
pub data: &'a[u8],
}
named!(nfs4_parse_stateid<Nfs4StateId>,
do_parse!(
seqid: be_u32
>> data: take!(12)
>> ( Nfs4StateId {
seqid: seqid,
data: data,
})
)
);
#[derive(Debug,PartialEq)]
pub struct Nfs4Handle<'a> {
pub len: u32,
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) )
));
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestSetClientId<'a> {
pub client_id: &'a[u8],
pub r_netid: &'a[u8],
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)
));
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestCreate<'a> {
pub ftype4: u32,
pub filename: &'a[u8],
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(&[]),
})
))
);
#[derive(Debug,PartialEq)]
pub enum Nfs4OpenRequestContent<'a> {
Exclusive4(&'a[u8]),
Unchecked4(Nfs4Attr),
Guarded4(Nfs4Attr),
}
named!(nfs4_req_open_unchecked4<Nfs4OpenRequestContent>,
do_parse!(
attrs: nfs4_parse_attrs
>> ( Nfs4OpenRequestContent::Unchecked4(attrs) )
));
named!(nfs4_req_open_guarded4<Nfs4OpenRequestContent>,
do_parse!(
attrs: nfs4_parse_attrs
>> ( Nfs4OpenRequestContent::Guarded4(attrs) )
));
named!(nfs4_req_open_exclusive4<Nfs4OpenRequestContent>,
do_parse!(
ver: take!(8)
>> ( Nfs4OpenRequestContent::Exclusive4(ver) )
));
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 )
));
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestOpen<'a> {
pub open_type: u32,
pub filename: &'a[u8],
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 )
)
);
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestRename<'a> {
pub oldname: &'a[u8],
pub newname: &'a[u8],
}
named!(nfs4_req_rename<Nfs4RequestContent>,
do_parse!(
oldname: nfs4_parse_nfsstring
>> newname: nfs4_parse_nfsstring
>> ( Nfs4RequestContent::Rename(Nfs4RequestRename {
oldname,
newname
})
))
);
#[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
})
))
);
named!(nfs4_req_remove<Nfs4RequestContent>,
do_parse!(
filename: nfs4_parse_nfsstring
>> ( Nfs4RequestContent::Remove(filename) )
));
#[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
}))
));
named!(nfs4_req_getattr<Nfs4RequestContent>,
do_parse!(
attrs: nfs4_parse_attrbits
>> ( Nfs4RequestContent::GetAttr(attrs) )
)
);
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestWrite<'a> {
pub stateid: Nfs4StateId<'a>,
pub offset: u64,
pub stable: u32,
pub write_len: u32,
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,
}))
));
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestRead<'a> {
pub stateid: Nfs4StateId<'a>,
pub offset: u64,
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) )
));
#[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 )
)
);
#[derive(Debug,PartialEq)]
pub struct Nfs4RequestExchangeId<'a> {
pub client_string: &'a[u8],
pub nii_domain: &'a[u8],
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
}
))
));
#[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 )
));
#[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
})
));
#[derive(Debug,PartialEq)]
pub enum Nfs4ResponseContent<'a> {
PutFH(u32),
PutRootFH(u32),
GetFH(u32, Option<Nfs4Handle<'a>>),
Lookup(u32),
SaveFH(u32),
Rename(u32),
Write(u32, Option<Nfs4ResponseWrite>),
Read(u32, Option<Nfs4ResponseRead<'a>>),
Renew(u32),
Open(u32, Option<Nfs4ResponseOpen<'a>>),
OpenConfirm(u32, Option<Nfs4StateId<'a>>),
Close(u32, Option<Nfs4StateId<'a>>),
GetAttr(u32, Option<Nfs4Attr>),
SetAttr(u32),
Access(u32, Option<Nfs4ResponseAccess>),
ReadDir(u32, Option<Nfs4ResponseReaddir<'a>>),
Remove(u32),
DelegReturn(u32),
SetClientId(u32),
SetClientIdConfirm(u32),
Create(u32),
Commit(u32),
Sequence(u32, Option<Nfs4ResponseSequence<'a>>),
}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseWrite {
pub count: u32,
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) )
));
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseRead<'a> {
pub eof: bool,
pub count: u32,
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) )
));
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseOpen<'a> {
pub stateid: Nfs4StateId<'a>,
pub result_flags: u32,
pub delegation_type: u32,
pub delegate_read: Option<Nfs4ResponseOpenDelegateRead<'a>>,
}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseOpenDelegateRead<'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) )
));
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseReaddirEntry<'a> {
pub name: &'a[u8],
}
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseReaddir<'a> {
pub eof: bool,
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
>> listing: many_till!(complete!(call!(nfs4_res_readdir_entry)), peek!(tag!(b"\x00\x00\x00\x00")))
>> _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)) >> ( 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))
));
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseAccess {
pub supported_types: u32,
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, ))
));
#[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)
));
#[derive(Debug,PartialEq)]
pub struct Nfs4ResponseCompoundRecord<'a> {
pub status: u32,
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,
})
));