From 39489bc5fdc9e71b9b013f999c7dbd67812ed9c4 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 20 Mar 2018 09:43:17 +0100 Subject: [PATCH] nfs4: implement COMMIT parsing and handling --- rust/src/nfs/nfs4.rs | 24 ++++++++++++++++++++++++ rust/src/nfs/nfs4_records.rs | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/rust/src/nfs/nfs4.rs b/rust/src/nfs/nfs4.rs index 521ed34d38..0d385ef305 100644 --- a/rust/src/nfs/nfs4.rs +++ b/rust/src/nfs/nfs4.rs @@ -105,6 +105,24 @@ impl NFSState { self.ts_chunk_left = w.write_len as u32 - file_data_len as u32; } + fn commit_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b[u8]) + { + SCLogDebug!("COMMIT, closing shop"); + + let file_handle = fh.to_vec(); + match self.get_file_tx_by_handle(&file_handle, STREAM_TOSERVER) { + Some((tx, files, flags)) => { + if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data { + tdf.file_tracker.close(files, flags); + tdf.file_last_xid = r.hdr.xid; + tx.is_last = true; + tx.request_done = true; + } + } + None => {}, + } + } + /* A normal READ request looks like: PUTFH (file handle) READ (read opts). * We need the file handle for the READ. */ @@ -142,6 +160,12 @@ impl NFSState { self.write_v4(r, rd, fh); } } + &Nfs4RequestContent::Commit => { + SCLogDebug!("COMMITv4"); + if let Some(fh) = last_putfh { + self.commit_v4(r, fh); + } + } &Nfs4RequestContent::Close(ref rd) => { SCLogDebug!("CLOSEv4: {:?}", rd); } diff --git a/rust/src/nfs/nfs4_records.rs b/rust/src/nfs/nfs4_records.rs index be26508446..0f77215e72 100644 --- a/rust/src/nfs/nfs4_records.rs +++ b/rust/src/nfs/nfs4_records.rs @@ -27,6 +27,7 @@ pub enum Nfs4RequestContent<'a> { SaveFH, PutRootFH, ReadDir, + Commit, Open(Nfs4RequestOpen<'a>), Lookup(Nfs4RequestLookup<'a>), Read(Nfs4RequestRead<'a>), @@ -406,6 +407,14 @@ named!(nfs4_req_access, ) ); +named!(nfs4_req_commit, + do_parse!( + offset: be_u64 + >> count: be_u32 + >> ( Nfs4RequestContent::Commit ) + ) +); + #[derive(Debug,PartialEq)] pub struct Nfs4RequestExchangeId<'a> { pub client_string: &'a[u8], @@ -446,6 +455,7 @@ named!(parse_request_compound_command, 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) | @@ -503,6 +513,7 @@ pub enum Nfs4ResponseContent<'a> { SetClientId(u32), SetClientIdConfirm(u32), Create(u32), + Commit(u32), } #[derive(Debug,PartialEq)] @@ -774,6 +785,13 @@ named!(nfs4_res_setclientid_confirm, >> ( Nfs4ResponseContent::SetClientIdConfirm(status) ) )); +named!(nfs4_res_commit, + do_parse!( + status: be_u32 + >> verifier: cond!(status == 0, take!(8)) + >> ( Nfs4ResponseContent::Commit(status)) +)); + #[derive(Debug,PartialEq)] pub struct Nfs4ResponseAccess { pub supported_types: u32, @@ -805,6 +823,7 @@ named!(nfs4_res_compound_command, 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) | -- 2.47.2