return 0;
}
+fn nfs3_rename_object(tx: &NFS3Transaction) -> Json
+{
+ let js = Json::object();
+ let from_str = String::from_utf8_lossy(&tx.file_name);
+ js.set_string("from", &from_str);
+
+ let to_vec = match tx.type_data {
+ Some(NFS3TransactionTypeData::RENAME(ref x)) => { x.to_vec() },
+ _ => { Vec::new() }
+ };
+
+ let to_str = String::from_utf8_lossy(&to_vec);
+ js.set_string("to", &to_str);
+ return js;
+}
+
fn nfs3_creds_object(tx: &NFS3Transaction) -> Json
{
let js = Json::object();
if tx.procedure == NFSPROC3_READ {
let read_js = nfs3_read_object(tx);
js.set("read", read_js);
- }
- if tx.procedure == NFSPROC3_WRITE {
+ } else if tx.procedure == NFSPROC3_WRITE {
let write_js = nfs3_write_object(tx);
js.set("write", write_js);
+ } else if tx.procedure == NFSPROC3_RENAME {
+ let rename_js = nfs3_rename_object(tx);
+ js.set("rename", rename_js);
}
return js.unwrap();
* Transaction lookup.
*/
+#[derive(Debug)]
+pub enum NFS3TransactionTypeData {
+ RENAME(Vec<u8>),
+}
#[derive(Debug)]
pub struct NFS3Transaction {
pub id: u64, /// internal id
pub xid: u32, /// nfs3 req/reply pair id
pub procedure: u32,
+ /// file name of the object we're dealing with. In case of RENAME
+ /// this is the 'from' or original name.
pub file_name: Vec<u8>,
pub request_machine_name: Vec<u8>,
pub file_tx_direction: u8, // STREAM_TOCLIENT or STREAM_TOSERVER
pub file_handle: Vec<u8>,
+ pub type_data: Option<NFS3TransactionTypeData>,
+
/// additional procedures part of a single file transfer. Currently
/// only COMMIT on WRITEs.
pub file_additional_procs: Vec<u32>,
is_file_tx: false,
file_tx_direction: 0,
file_handle:Vec::new(),
+ type_data: None,
file_additional_procs:Vec::new(),
file_last_xid: 0,
file_tracker: None,
};
}
+ fn xidmap_handle2name(&mut self, xidmap: &mut NFS3RequestXidMap) {
+ match self.namemap.get(&xidmap.file_handle) {
+ Some(n) => {
+ SCLogDebug!("xidmap_handle2name: name {:?}", n);
+ xidmap.file_name = n.to_vec();
+ },
+ _ => {
+ SCLogDebug!("xidmap_handle2name: object {:?} not found",
+ xidmap.file_handle);
+ },
+ }
+ }
+
/// complete request record
fn process_request_record<'b>(&mut self, r: &RpcPacket<'b>) -> u32 {
SCLogDebug!("REQUEST {} procedure {} ({}) blob size {}",
r.hdr.xid, r.procedure, self.requestmap.len(), r.prog_data.len());
let mut xidmap = NFS3RequestXidMap::new(r.procedure, 0);
+ let mut aux_file_name = Vec::new();
if r.procedure == NFSPROC3_LOOKUP {
self.process_request_record_lookup(r, &mut xidmap);
+ } else if r.procedure == NFSPROC3_ACCESS {
+ match parse_nfs3_request_access(r.prog_data) {
+ IResult::Done(_, ar) => {
+ xidmap.file_handle = ar.handle.value.to_vec();
+ self.xidmap_handle2name(&mut xidmap);
+ },
+ IResult::Incomplete(_) => { panic!("WEIRD"); },
+ IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
+ };
+ } else if r.procedure == NFSPROC3_GETATTR {
+ match parse_nfs3_request_getattr(r.prog_data) {
+ IResult::Done(_, gar) => {
+ xidmap.file_handle = gar.handle.value.to_vec();
+ self.xidmap_handle2name(&mut xidmap);
+ },
+ IResult::Incomplete(_) => { panic!("WEIRD"); },
+ IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
+ };
} else if r.procedure == NFSPROC3_READ {
match parse_nfs3_request_read(r.prog_data) {
IResult::Done(_, nfs3_read_record) => {
xidmap.chunk_offset = nfs3_read_record.offset;
xidmap.file_handle = nfs3_read_record.handle.value.to_vec();
-
- match self.namemap.get(nfs3_read_record.handle.value) {
- Some(n) => {
- SCLogDebug!("READ name {:?}", n);
- xidmap.file_name = n.to_vec();
- },
- _ => {
- SCLogDebug!("READ object {:?} not found",
- nfs3_read_record.handle.value);
- },
- }
+ self.xidmap_handle2name(&mut xidmap);
},
IResult::Incomplete(_) => { panic!("WEIRD"); },
IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
} else if r.procedure == NFSPROC3_CREATE {
match parse_nfs3_request_create(r.prog_data) {
IResult::Done(_, nfs3_create_record) => {
+ xidmap.file_handle = nfs3_create_record.handle.value.to_vec();
xidmap.file_name = nfs3_create_record.name_vec;
},
IResult::Incomplete(_) => { panic!("WEIRD"); },
IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
};
+ } else if r.procedure == NFSPROC3_REMOVE {
+ match parse_nfs3_request_remove(r.prog_data) {
+ IResult::Done(_, rr) => {
+ xidmap.file_handle = rr.handle.value.to_vec();
+ xidmap.file_name = rr.name_vec;
+ },
+ IResult::Incomplete(_) => { panic!("WEIRD"); },
+ IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
+ };
+
+ } else if r.procedure == NFSPROC3_RENAME {
+ match parse_nfs3_request_rename(r.prog_data) {
+ IResult::Done(_, rr) => {
+ xidmap.file_handle = rr.from_handle.value.to_vec();
+ xidmap.file_name = rr.from_name_vec;
+ aux_file_name = rr.to_name_vec;
+ },
+ IResult::Incomplete(_) => { panic!("WEIRD"); },
+ IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
+ };
+
} else if r.procedure == NFSPROC3_COMMIT {
SCLogDebug!("COMMIT, closing shop");
tx.file_name = xidmap.file_name.to_vec();
//self.ts_txs_updated = true;
+ if r.procedure == NFSPROC3_RENAME {
+ tx.type_data = Some(NFS3TransactionTypeData::RENAME(aux_file_name));
+ }
+
match &r.creds_unix {
&Some(ref u) => {
tx.request_machine_name = u.machine_name_buf.to_vec();
))
);
+#[derive(Debug,PartialEq)]
+pub struct Nfs3RequestRemove<'a> {
+ pub handle: Nfs3Handle<'a>,
+ pub name_len: u32,
+ pub name_vec: Vec<u8>,
+}
+
+named!(pub parse_nfs3_request_remove<Nfs3RequestRemove>,
+ do_parse!(
+ handle: parse_nfs3_handle
+ >> name_len: be_u32
+ >> name: take!(name_len)
+ >> fill_bytes: rest
+ >> (
+ Nfs3RequestRemove {
+ handle:handle,
+ name_len:name_len,
+ name_vec:name.to_vec(),
+ }
+ ))
+);
+
+#[derive(Debug,PartialEq)]
+pub struct Nfs3RequestRename<'a> {
+ pub from_handle: Nfs3Handle<'a>,
+ pub from_name_vec: Vec<u8>,
+ pub to_handle: Nfs3Handle<'a>,
+ pub to_name_vec: Vec<u8>,
+}
+
+named!(pub parse_nfs3_request_rename<Nfs3RequestRename>,
+ do_parse!(
+ from_handle: parse_nfs3_handle
+ >> from_name_len: be_u32
+ >> from_name: take!(from_name_len)
+ >> from_fill_bytes: cond!(from_name_len % 4 != 0, take!(4 - from_name_len % 4))
+ >> to_handle: parse_nfs3_handle
+ >> to_name_len: be_u32
+ >> to_name: take!(to_name_len)
+ >> to_fill_bytes: rest
+ >> (
+ Nfs3RequestRename {
+ from_handle:from_handle,
+ from_name_vec:from_name.to_vec(),
+ to_handle:to_handle,
+ to_name_vec:to_name.to_vec(),
+ }
+ ))
+);
+
+#[derive(Debug,PartialEq)]
+pub struct Nfs3RequestGetAttr<'a> {
+ pub handle: Nfs3Handle<'a>,
+}
+
+named!(pub parse_nfs3_request_getattr<Nfs3RequestGetAttr>,
+ do_parse!(
+ handle: parse_nfs3_handle
+ >> (
+ Nfs3RequestGetAttr {
+ handle:handle,
+ }
+ ))
+);
+
#[derive(Debug,PartialEq)]
pub struct Nfs3RequestAccess<'a> {
pub handle: Nfs3Handle<'a>,