]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/nfs4: Add NFSPROC4_LAYOUTRETURN op parsers
authorSam Muhammed <ghostinthehive.vx@gmail.com>
Sun, 20 Feb 2022 17:10:41 +0000 (19:10 +0200)
committerVictor Julien <vjulien@oisf.net>
Fri, 4 Mar 2022 15:50:55 +0000 (16:50 +0100)
Also add respective request unittest
test_nfs4_request_layoutreturn()

rust/src/nfs/nfs4_records.rs
rust/src/nfs/types.rs

index 0a69c48a7c26facac75d2e48cb4df0ebde7bcbe2..2efa69cb8032e0126c57731a4db835b0e99aa3a3 100644 (file)
@@ -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<Nfs4ResponseLayoutGet<'a>>),
     GetDevInfo(u32, Option<Nfs4ResponseGetDevInfo<'a>>),
+    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]
index feb7b70a2d99e841de3782a441c290f3934d44fa..fc81692dcce9541cbaef650c708b1f397025d412 100644 (file)
@@ -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;