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)
js.set_integer("last_xid", tdf.file_last_xid as u64);
return js;
}
+/*
+fn nfs_handle2hex(bytes: &Vec<u8>) -> String {
+ let strings: Vec<String> = bytes.iter()
+ .map(|b| format!("{:02x}", b))
+ .collect();
+ strings.join("")
+}
+*/
+fn nfs_handle2crc(bytes: &Vec<u8>) -> u32 {
+ let c = crc32::checksum_ieee(bytes);
+ c
+}
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;
}
// 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<u8>)
{
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);
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 {
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;
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) {
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); },
Some(h) => {
SCLogDebug!("handle {:?}", h);
self.namemap.insert(h.value.to_vec(), xidmap.file_name.to_vec());
+ resp_handle = h.value.to_vec();
},
_ => { },
}
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
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) {
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
}