rust/nfs4: Add NFSPROC4_GETDEVINFO op parsers

Also add respective response/request unittests
test_nfs4_response_getdevinfo()
test_nfs4_request_getdevinfo()
pull/7112/head
Sam Muhammed 3 years ago committed by Victor Julien
parent ff54a6d9d5
commit 073244a0b8

@ -66,6 +66,7 @@ pub enum Nfs4RequestContent<'a> {
ReclaimComplete(u32),
SecInfoNoName(u32),
LayoutGet(Nfs4RequestLayoutGet<'a>),
GetDevInfo(Nfs4RequestGetDevInfo<'a>),
}
#[derive(Debug,PartialEq)]
@ -135,6 +136,29 @@ fn nfs4_parse_nfsstring(i: &[u8]) -> IResult<&[u8], &[u8]> {
Ok((i, data))
}
#[derive(Debug, PartialEq)]
pub struct Nfs4RequestGetDevInfo<'a> {
pub device_id: &'a[u8],
pub layout_type: u32,
pub maxcount: u32,
pub notify_mask: u32,
}
fn nfs4_req_getdevinfo(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
let (i, device_id) = take(16_usize)(i)?;
let (i, layout_type) = be_u32(i)?;
let (i, maxcount) = be_u32(i)?;
let (i, _) = be_u32(i)?;
let (i, notify_mask) = be_u32(i)?;
let req = Nfs4RequestContent::GetDevInfo(Nfs4RequestGetDevInfo {
device_id,
layout_type,
maxcount,
notify_mask,
});
Ok((i, req))
}
#[derive(Debug, PartialEq)]
pub struct Nfs4RequestCreateSession<'a> {
pub client_id: &'a[u8],
@ -529,6 +553,7 @@ fn parse_request_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent
NFSPROC4_RECLAIM_COMPLETE => nfs4_req_reclaim_complete(i)?,
NFSPROC4_SECINFO_NO_NAME => nfs4_req_secinfo_no_name(i)?,
NFSPROC4_LAYOUTGET => nfs4_req_layoutget(i)?,
NFSPROC4_GETDEVINFO => nfs4_req_getdevinfo(i)?,
_ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
};
Ok((i, cmd_data))
@ -581,6 +606,7 @@ pub enum Nfs4ResponseContent<'a> {
ReclaimComplete(u32),
SecInfoNoName(u32),
LayoutGet(u32, Option<Nfs4ResponseLayoutGet<'a>>),
GetDevInfo(u32, Option<Nfs4ResponseGetDevInfo<'a>>),
}
#[derive(Debug, PartialEq)]
@ -776,6 +802,36 @@ fn nfs4_res_open(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
Ok((i, Nfs4ResponseContent::Open(status, open_data)))
}
#[derive(Debug, PartialEq)]
pub struct Nfs4ResponseGetDevInfo<'a> {
pub layout_type: u32,
pub r_netid: &'a[u8],
pub r_addr: &'a[u8],
pub notify_mask: u32,
}
fn nfs4_parse_res_getdevinfo(i: &[u8]) -> IResult<&[u8], Nfs4ResponseGetDevInfo> {
let (i, layout_type) = be_u32(i)?;
let (i, _) = be_u64(i)?;
let (i, _device_index) = be_u32(i)?;
let (i, _) = be_u64(i)?;
let (i, r_netid) = nfs4_parse_nfsstring(i)?;
let (i, r_addr) = nfs4_parse_nfsstring(i)?;
let (i, notify_mask) = be_u32(i)?;
Ok((i, Nfs4ResponseGetDevInfo {
layout_type,
r_netid,
r_addr,
notify_mask,
}))
}
fn nfs4_res_getdevinfo(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
let (i, status) = be_u32(i)?;
let (i, getdevinfo) = cond(status == 0, nfs4_parse_res_getdevinfo)(i)?;
Ok((i, Nfs4ResponseContent::GetDevInfo( status, getdevinfo )))
}
/*https://datatracker.ietf.org/doc/html/rfc5661#section-13.1*/
// in case of multiple file handles, return handles in a vector
#[derive(Debug, PartialEq)]
@ -1065,6 +1121,7 @@ fn nfs4_res_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
NFSPROC4_RECLAIM_COMPLETE => nfs4_res_reclaim_complete(i)?,
NFSPROC4_SECINFO_NO_NAME => nfs4_res_secinfo_no_name(i)?,
NFSPROC4_LAYOUTGET => nfs4_res_layoutget(i)?,
NFSPROC4_GETDEVINFO => nfs4_res_getdevinfo(i)?,
_ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
};
Ok((i, cmd_data))
@ -1433,6 +1490,28 @@ mod tests {
}
}
#[test]
fn test_nfs4_request_getdevinfo() {
let buf: &[u8] = &[
0x00, 0x00, 0x00, 0x2f, /*opcode*/
0x01, 0x01, 0x00, 0x00, 0x00, 0xf2, 0xfa, 0x80, // getdevinfo
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x3e, 0x20,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
];
let (_, request) = nfs4_req_getdevinfo(&buf[4..]).unwrap();
match request {
Nfs4RequestContent::GetDevInfo( getdevifo ) => {
assert_eq!(getdevifo.device_id, &buf[4..20]);
assert_eq!(getdevifo.layout_type, 1);
assert_eq!(getdevifo.maxcount, 81440);
assert_eq!(getdevifo.notify_mask, 6);
}
_ => { panic!("Failure"); }
}
}
#[test]
fn test_nfs4_attrs() {
#[rustfmt::skip]
@ -1843,4 +1922,35 @@ mod tests {
_ => { panic!("Failure"); }
}
}
#[test]
fn test_nfs4_response_getdevinfo() {
let buf: &[u8] = &[
0x00, 0x00, 0x00, 0x2f, /*opcode*/
0x00, 0x00, 0x00, 0x00, /*status*/
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2c, // getdevinfo
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03, 0x74, 0x63, 0x70, 0x00,
0x00, 0x00, 0x00, 0x10, 0x31, 0x39, 0x32, 0x2e,
0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x36, 0x31,
0x2e, 0x38, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00,
];
let (_, getdevinfo) = nfs4_parse_res_getdevinfo(&buf[8..]).unwrap();
assert_eq!(getdevinfo.layout_type, 1);
assert_eq!(getdevinfo.r_netid, b"tcp");
assert_eq!(getdevinfo.r_addr, b"192.168.0.61.8.1");
let (_, response) = nfs4_res_getdevinfo(&buf[4..]).unwrap();
match response {
Nfs4ResponseContent::GetDevInfo(status, getdevinfo_data) => {
assert_eq!(status, 0);
assert_eq!(getdevinfo_data, Some(getdevinfo))
}
_ => { panic!("Failure"); }
}
}
}

@ -275,6 +275,7 @@ pub const NFSPROC4_WRITE: u32 = 38;
pub const NFSPROC4_RELEASE_LOCKOWNER: u32 = 39;
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_SECINFO_NO_NAME: u32 = 52;
pub const NFSPROC4_SEQUENCE: u32 = 53;

Loading…
Cancel
Save