From: Sam Muhammed Date: Sun, 20 Feb 2022 17:10:41 +0000 (+0200) Subject: rust/nfs4: Add NFSPROC4_LAYOUTRETURN op parsers X-Git-Tag: suricata-7.0.0-beta1~813 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff81cad4f1547d1a69292649c25e84aaef87c857;p=thirdparty%2Fsuricata.git rust/nfs4: Add NFSPROC4_LAYOUTRETURN op parsers Also add respective request unittest test_nfs4_request_layoutreturn() --- diff --git a/rust/src/nfs/nfs4_records.rs b/rust/src/nfs/nfs4_records.rs index 0a69c48a7c..2efa69cb80 100644 --- a/rust/src/nfs/nfs4_records.rs +++ b/rust/src/nfs/nfs4_records.rs @@ -67,6 +67,7 @@ pub enum Nfs4RequestContent<'a> { SecInfoNoName(u32), LayoutGet(Nfs4RequestLayoutGet<'a>), GetDevInfo(Nfs4RequestGetDevInfo<'a>), + LayoutReturn(Nfs4RequestLayoutReturn<'a>), } #[derive(Debug,PartialEq)] @@ -136,6 +137,34 @@ fn nfs4_parse_nfsstring(i: &[u8]) -> IResult<&[u8], &[u8]> { Ok((i, data)) } +#[derive(Debug, PartialEq)] +pub struct Nfs4RequestLayoutReturn<'a> { + pub layout_type: u32, + pub return_type: u32, + pub length: u64, + pub stateid: Nfs4StateId<'a>, + pub lrf_data: &'a[u8], +} + +fn nfs4_req_layoutreturn(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> { + let (i, _reclaim) = verify(be_u32, |&v| v <= 1)(i)?; + let (i, layout_type) = be_u32(i)?; + let (i, _iq_mode) = be_u32(i)?; + let (i, return_type) = be_u32(i)?; + let (i, _offset) = be_u64(i)?; + let (i, length) = be_u64(i)?; + let (i, stateid) = nfs4_parse_stateid(i)?; + let (i, lrf_data) = nfs4_parse_nfsstring(i)?; + let req = Nfs4RequestContent::LayoutReturn(Nfs4RequestLayoutReturn { + layout_type, + return_type, + length, + stateid, + lrf_data, + }); + Ok((i, req)) +} + #[derive(Debug, PartialEq)] pub struct Nfs4RequestGetDevInfo<'a> { pub device_id: &'a[u8], @@ -554,6 +583,7 @@ fn parse_request_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent NFSPROC4_SECINFO_NO_NAME => nfs4_req_secinfo_no_name(i)?, NFSPROC4_LAYOUTGET => nfs4_req_layoutget(i)?, NFSPROC4_GETDEVINFO => nfs4_req_getdevinfo(i)?, + NFSPROC4_LAYOUTRETURN => nfs4_req_layoutreturn(i)?, _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); } }; Ok((i, cmd_data)) @@ -607,6 +637,14 @@ pub enum Nfs4ResponseContent<'a> { SecInfoNoName(u32), LayoutGet(u32, Option>), GetDevInfo(u32, Option>), + LayoutReturn(u32), +} + +// might need improvment with a stateid_present = yes case +fn nfs4_res_layoutreturn(i:&[u8]) -> IResult<&[u8], Nfs4ResponseContent> { + let (i, status) = be_u32(i)?; + let (i, _stateid_present) = verify(be_u32, |&v| v <= 1)(i)?; + Ok((i, Nfs4ResponseContent::LayoutReturn(status))) } #[derive(Debug, PartialEq)] @@ -1122,6 +1160,7 @@ fn nfs4_res_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> { NFSPROC4_SECINFO_NO_NAME => nfs4_res_secinfo_no_name(i)?, NFSPROC4_LAYOUTGET => nfs4_res_layoutget(i)?, NFSPROC4_GETDEVINFO => nfs4_res_getdevinfo(i)?, + NFSPROC4_LAYOUTRETURN => nfs4_res_layoutreturn(i)?, _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); } }; Ok((i, cmd_data)) @@ -1512,6 +1551,33 @@ mod tests { } } + #[test] + fn test_nfs4_request_layoutreturn() { + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x33, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // layoutreturn + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x01, 0x03, 0x82, 0x14, 0xe0, + 0x5b, 0x00, 0x89, 0xd9, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ]; + + let (_, stateid_buf) = nfs4_parse_stateid(&buf[36..52]).unwrap(); + assert_eq!(stateid_buf.seqid, 1); + + let (_, request) = nfs4_req_layoutreturn(&buf[4..]).unwrap(); + match request { + Nfs4RequestContent::LayoutReturn( layoutreturn ) => { + assert_eq!(layoutreturn.layout_type, 1); + assert_eq!(layoutreturn.return_type, 1); + assert_eq!(layoutreturn.stateid, stateid_buf); + } + _ => { panic!("Failure"); } + } + } + #[test] fn test_nfs4_attrs() { #[rustfmt::skip] diff --git a/rust/src/nfs/types.rs b/rust/src/nfs/types.rs index feb7b70a2d..fc81692dcc 100644 --- a/rust/src/nfs/types.rs +++ b/rust/src/nfs/types.rs @@ -277,6 +277,7 @@ pub const NFSPROC4_EXCHANGE_ID: u32 = 42; pub const NFSPROC4_CREATE_SESSION: u32 = 43; pub const NFSPROC4_GETDEVINFO: u32 = 47; pub const NFSPROC4_LAYOUTGET: u32 = 50; +pub const NFSPROC4_LAYOUTRETURN: u32 = 51; pub const NFSPROC4_SECINFO_NO_NAME: u32 = 52; pub const NFSPROC4_SEQUENCE: u32 = 53; pub const NFSPROC4_RECLAIM_COMPLETE: u32 = 58;