From cb3abba1e0f69d523f4d3ad35c795d9c408d3641 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 21 Jul 2018 18:13:32 +0200 Subject: [PATCH] nfs4: log remove procedure + add multi-proc support Add TX creation for NFS4 transactions. Start with the 'REMOVE' procedure. Start on logging all procs. In NFS4 COMPOUND records there are multiple procedures. One of them can be considered the 'main' procedure, with others as supporting utility. This patch adds the first step in supporting to track those in the TX for logging and inspection. --- rust/src/nfs/nfs4.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/rust/src/nfs/nfs4.rs b/rust/src/nfs/nfs4.rs index f3a9a75212..14b1f8a3bd 100644 --- a/rust/src/nfs/nfs4.rs +++ b/rust/src/nfs/nfs4.rs @@ -123,6 +123,32 @@ impl NFSState { } } + fn new_tx_v4<'b>(&mut self, r: &RpcPacket<'b>, + xidmap: &NFSRequestXidMap, procedure: u32, + _aux_opcodes: &Vec) + { + let mut tx = self.new_tx(); + tx.xid = r.hdr.xid; + tx.procedure = procedure; + tx.request_done = true; + tx.file_name = xidmap.file_name.to_vec(); + tx.nfs_version = r.progver as u16; + tx.file_handle = xidmap.file_handle.to_vec(); + + tx.auth_type = r.creds_flavor; + match r.creds { + RpcRequestCreds::Unix(ref u) => { + 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); + self.transactions.push(tx); + } + /* A normal READ request looks like: PUTFH (file handle) READ (read opts). * We need the file handle for the READ. */ @@ -131,12 +157,15 @@ impl NFSState { xidmap: &mut NFSRequestXidMap) { let mut last_putfh : Option<&'b[u8]> = None; + let mut main_opcode : u32 = 0; + let mut aux_opcodes : Vec = Vec::new(); for c in &cr.commands { SCLogDebug!("c {:?}", c); match c { &Nfs4RequestContent::PutFH(ref rd) => { last_putfh = Some(rd.value); + aux_opcodes.push(NFSPROC4_PUTFH); } &Nfs4RequestContent::Read(ref rd) => { SCLogDebug!("READv4: {:?}", rd); @@ -169,6 +198,11 @@ impl NFSState { &Nfs4RequestContent::Close(ref rd) => { SCLogDebug!("CLOSEv4: {:?}", rd); } + &Nfs4RequestContent::Remove(ref rd) => { + SCLogDebug!("REMOVEv4: {:?}", rd); + xidmap.file_name = rd.to_vec(); + main_opcode = NFSPROC4_REMOVE; + } &Nfs4RequestContent::SetClientId(ref rd) => { SCLogDebug!("SETCLIENTIDv4: client id {} r_netid {} r_addr {}", String::from_utf8_lossy(&rd.client_id), @@ -178,6 +212,10 @@ impl NFSState { &_ => { }, } } + + if main_opcode != 0 { + self.new_tx_v4(r, &xidmap, main_opcode, &aux_opcodes); + } } /// complete request record @@ -247,6 +285,8 @@ impl NFSState { 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; for c in &cr.commands { SCLogDebug!("c {:?}", c); @@ -265,6 +305,8 @@ impl NFSState { } &Nfs4ResponseContent::Remove(s) => { SCLogDebug!("REMOVE4: status {}", s); + main_opcode_status = s; + main_opcode_status_set = true; }, &Nfs4ResponseContent::Read(s, ref rd) => { if let &Some(ref rd) = rd { @@ -305,6 +347,11 @@ impl NFSState { &_ => { }, } } + + if main_opcode_status_set { + let resp_handle = Vec::new(); + self.mark_response_tx_done(r.hdr.xid, r.reply_state, main_opcode_status, &resp_handle); + } } pub fn process_reply_record_v4<'b>(&mut self, r: &RpcReplyPacket<'b>,