From: Victor Julien Date: Fri, 16 Jun 2017 14:09:18 +0000 (+0200) Subject: rust/nfs: add (file)handle to log as crc32 X-Git-Tag: suricata-4.0.0-rc1~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db2d9281517f86b4283d714db81b0fd198999cf9;p=thirdparty%2Fsuricata.git rust/nfs: add (file)handle to log as crc32 --- diff --git a/rust/Cargo.toml.in b/rust/Cargo.toml.in index 45e1fb5c0b..a04b0b0d6a 100644 --- a/rust/Cargo.toml.in +++ b/rust/Cargo.toml.in @@ -14,3 +14,4 @@ lua = [] [dependencies] nom = "~3.0" libc = "~0.2.0" +crc = "~1.4.0" diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 701df8655e..8e086bae6d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -20,6 +20,8 @@ extern crate libc; #[macro_use] extern crate nom; +extern crate crc; + #[macro_use] pub mod log; diff --git a/rust/src/nfs/log.rs b/rust/src/nfs/log.rs index 5d2cb0ebc2..8405bb94c3 100644 --- a/rust/src/nfs/log.rs +++ b/rust/src/nfs/log.rs @@ -21,6 +21,7 @@ use std::string::String; use json::*; use nfs::types::*; use nfs::nfs::*; +use crc::crc32; #[no_mangle] pub extern "C" fn rs_nfs_tx_logging_is_filtered(tx: &mut NFSTransaction) @@ -75,6 +76,18 @@ fn nfs_file_object(tx: &NFSTransaction) -> Json js.set_integer("last_xid", tdf.file_last_xid as u64); return js; } +/* +fn nfs_handle2hex(bytes: &Vec) -> String { + let strings: Vec = bytes.iter() + .map(|b| format!("{:02x}", b)) + .collect(); + strings.join("") +} +*/ +fn nfs_handle2crc(bytes: &Vec) -> u32 { + let c = crc32::checksum_ieee(bytes); + c +} fn nfs_common_header(state: &NFSState, tx: &NFSTransaction) -> Json { @@ -83,6 +96,13 @@ fn nfs_common_header(state: &NFSState, tx: &NFSTransaction) -> Json js.set_string("procedure", &nfs3_procedure_string(tx.procedure)); let file_name = String::from_utf8_lossy(&tx.file_name); js.set_string("filename", &file_name); + + if tx.file_handle.len() > 0 { + //js.set_string("handle", &nfs_handle2hex(&tx.file_handle)); + let c = nfs_handle2crc(&tx.file_handle); + let s = format!("{:x}", c); + js.set_string("hhash", &s); + } js.set_integer("id", tx.id as u64); js.set_boolean("file_tx", tx.is_file_tx); return js; diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 03c4d730a2..0be7acdcdb 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -405,13 +405,16 @@ impl NFSState { } // TODO maybe not enough users to justify a func - fn mark_response_tx_done(&mut self, xid: u32, rpc_status: u32, nfs_status: u32) + fn mark_response_tx_done(&mut self, xid: u32, rpc_status: u32, nfs_status: u32, resp_handle: &Vec) { match self.get_tx_by_xid(xid) { Some(mut mytx) => { mytx.response_done = true; mytx.rpc_response_status = rpc_status; mytx.nfs_response_status = nfs_status; + if mytx.file_handle.len() == 0 && resp_handle.len() > 0 { + mytx.file_handle = resp_handle.to_vec(); + } SCLogDebug!("process_reply_record: tx ID {} XID {} REQUEST {} RESPONSE {}", mytx.id, mytx.xid, mytx.request_done, mytx.response_done); @@ -592,6 +595,7 @@ impl NFSState { 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(); //self.ts_txs_updated = true; if r.procedure == NFSPROC3_RENAME { @@ -678,6 +682,7 @@ impl NFSState { tx.procedure = r.procedure; tx.request_done = true; tx.file_name = xidmap.file_name.to_vec(); + tx.file_handle = xidmap.file_handle.to_vec(); tx.nfs_version = r.progver as u16; //self.ts_txs_updated = true; @@ -829,6 +834,7 @@ impl NFSState { fn process_reply_record_v3<'b>(&mut self, r: &RpcReplyPacket<'b>, xidmap: &mut NFSRequestXidMap) -> u32 { let nfs_status; + let mut resp_handle = Vec::new(); if xidmap.procedure == NFSPROC3_LOOKUP { match parse_nfs3_response_lookup(r.prog_data) { @@ -840,6 +846,7 @@ impl NFSState { SCLogDebug!("LOOKUP handle {:?}", lookup.handle); self.namemap.insert(lookup.handle.value.to_vec(), xidmap.file_name.to_vec()); + resp_handle = lookup.handle.value.to_vec(); }, IResult::Incomplete(_) => { panic!("WEIRD"); }, IResult::Error(e) => { panic!("Parsing failed: {:?}",e); }, @@ -856,6 +863,7 @@ impl NFSState { Some(h) => { SCLogDebug!("handle {:?}", h); self.namemap.insert(h.value.to_vec(), xidmap.file_name.to_vec()); + resp_handle = h.value.to_vec(); }, _ => { }, } @@ -927,7 +935,7 @@ impl NFSState { r.hdr.xid, xidmap.procedure, r.prog_data.len()); if xidmap.procedure != NFSPROC3_READ { - self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status); + self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status, &resp_handle); } 0 @@ -935,6 +943,7 @@ impl NFSState { fn process_reply_record_v2<'b>(&mut self, r: &RpcReplyPacket<'b>, xidmap: &NFSRequestXidMap) -> u32 { let nfs_status; + let resp_handle = Vec::new(); if xidmap.procedure == NFSPROC3_READ { match parse_nfs2_reply_read(r.prog_data) { @@ -958,7 +967,7 @@ impl NFSState { SCLogDebug!("REPLY {} to procedure {} blob size {}", r.hdr.xid, xidmap.procedure, r.prog_data.len()); - self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status); + self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status, &resp_handle); 0 }