]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs4: implement COMMIT parsing and handling
authorVictor Julien <victor@inliniac.net>
Tue, 20 Mar 2018 08:43:17 +0000 (09:43 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 5 Apr 2018 13:21:48 +0000 (15:21 +0200)
rust/src/nfs/nfs4.rs
rust/src/nfs/nfs4_records.rs

index 521ed34d383e4b779e150fbc53d8e73aa6c21e16..0d385ef305a84642f5de63cd9f41d08883da28a0 100644 (file)
@@ -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);
                 }
index be265084466789973a8441efad6523c964335991..0f77215e72624741832d895a5abd2c26fb1ecaad 100644 (file)
@@ -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<Nfs4RequestContent>,
     )
 );
 
+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],
@@ -446,6 +455,7 @@ named!(parse_request_compound_command<Nfs4RequestContent>,
             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>,
         >> ( 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,
@@ -805,6 +823,7 @@ named!(nfs4_res_compound_command<Nfs4ResponseContent>,
             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)              |