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>,