rust/nfs4: Add NFSPROC4_CREATE_SESSION op parsers

Also add respective response/request unittests
test_nfs4_request_create_session()
test_nfs4_response_create_session()
pull/7112/head
Sam Muhammed 4 years ago committed by Victor Julien
parent 0a69c66153
commit 2a41b46eca

@ -17,7 +17,7 @@
//! Nom parsers for NFSv4 records
use nom7::bytes::streaming::{tag, take};
use nom7::combinator::{complete, cond, map, peek, verify};
use nom7::combinator::{complete, cond, map, peek, verify, rest};
use nom7::error::{make_error, ErrorKind};
use nom7::multi::{count, many_till};
use nom7::number::streaming::{be_u32, be_u64};
@ -60,6 +60,7 @@ pub enum Nfs4RequestContent<'a> {
SetClientIdConfirm,
ExchangeId(Nfs4RequestExchangeId<'a>),
Sequence(Nfs4RequestSequence<'a>),
CreateSession(Nfs4RequestCreateSession<'a>),
}
#[derive(Debug,PartialEq)]
@ -129,6 +130,34 @@ fn nfs4_parse_nfsstring(i: &[u8]) -> IResult<&[u8], &[u8]> {
Ok((i, data))
}
#[derive(Debug, PartialEq)]
pub struct Nfs4RequestCreateSession<'a> {
pub client_id: &'a[u8],
pub seqid: u32,
pub machine_name: &'a[u8],
}
fn nfs4_req_create_session(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
let (i, client_id) = take(8_usize)(i)?;
let (i, seqid) = be_u32(i)?;
let (i, _flags) = be_u32(i)?;
let (i, _fore_chan_attrs) = take(28_usize)(i)?;
let (i, _back_chan_attrs) = take(28_usize)(i)?;
let (i, _cb_program) = be_u32(i)?;
let (i, _) = be_u32(i)?;
let (i, _flavor) = be_u32(i)?;
let (i, _stamp) = be_u32(i)?;
let (i, machine_name) = nfs4_parse_nfsstring(i)?;
let (i, _) = rest(i)?;
let req = Nfs4RequestContent::CreateSession(Nfs4RequestCreateSession {
client_id,
seqid,
machine_name,
});
Ok((i, req))
}
fn nfs4_req_putfh(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
map(nfs4_parse_handle, Nfs4RequestContent::PutFH)(i)
}
@ -458,6 +487,7 @@ fn parse_request_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent
NFSPROC4_SETCLIENTID_CONFIRM => nfs4_req_setclientid_confirm(i)?,
NFSPROC4_SEQUENCE => nfs4_req_sequence(i)?,
NFSPROC4_EXCHANGE_ID => nfs4_req_exchangeid(i)?,
NFSPROC4_CREATE_SESSION => nfs4_req_create_session(i)?,
_ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
};
Ok((i, cmd_data))
@ -506,6 +536,31 @@ pub enum Nfs4ResponseContent<'a> {
Commit(u32),
ExchangeId(u32, Option<Nfs4ResponseExchangeId<'a>>),
Sequence(u32, Option<Nfs4ResponseSequence<'a>>),
CreateSession(u32, Option<Nfs4ResponseCreateSession<'a>>),
}
#[derive(Debug, PartialEq)]
pub struct Nfs4ResponseCreateSession<'a> {
pub ssn_id: &'a[u8],
pub seq_id: u32,
}
fn nfs4_parse_res_create_session(i: &[u8]) -> IResult<&[u8], Nfs4ResponseCreateSession> {
let (i, ssn_id) = take(16_usize)(i)?;
let (i, seq_id) = be_u32(i)?;
let (i, _flags) = be_u32(i)?;
let (i, _fore_chan_attrs) = take(28_usize)(i)?;
let (i, _back_chan_attrs) = take(28_usize)(i)?;
Ok((i, Nfs4ResponseCreateSession {
ssn_id,
seq_id
}))
}
fn nfs4_res_create_session(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
let (i, status) = be_u32(i)?;
let (i, create_ssn_data) = cond(status == 0, nfs4_parse_res_create_session)(i)?;
Ok((i, Nfs4ResponseContent::CreateSession( status, create_ssn_data )))
}
#[derive(Debug, PartialEq)]
@ -890,6 +945,7 @@ fn nfs4_res_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
NFSPROC4_EXCHANGE_ID => nfs4_res_exchangeid(i)?,
NFSPROC4_SEQUENCE => nfs4_res_sequence(i)?,
NFSPROC4_RENEW => nfs4_res_renew(i)?,
NFSPROC4_CREATE_SESSION => nfs4_res_create_session(i)?,
_ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
};
Ok((i, cmd_data))
@ -1199,6 +1255,38 @@ mod tests {
}
}
#[test]
fn test_nfs4_request_create_session() {
let buf: &[u8] = &[
0x00, 0x00, 0x00, 0x2b, /*opcode*/
0xe0, 0x14, 0x82, 0x00, 0x00, 0x00, 0x02, 0xd2, // create_session
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x14,
0x00, 0x10, 0x03, 0x88, 0x00, 0x00, 0x0d, 0x64,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x0c, 0x09, 0x5e, 0x92,
0x00, 0x00, 0x00, 0x09, 0x6e, 0x65, 0x74, 0x61,
0x70, 0x70, 0x2d, 0x32, 0x36, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let (_, request) = nfs4_req_create_session(&buf[4..]).unwrap();
match request {
Nfs4RequestContent::CreateSession( create_ssn ) => {
assert_eq!(create_ssn.client_id, &buf[4..12]);
assert_eq!(create_ssn.seqid, 1);
assert_eq!(create_ssn.machine_name, b"netapp-26");
}
_ => { panic!("Failure"); }
}
}
#[test]
fn test_nfs4_attrs() {
#[rustfmt::skip]
@ -1537,5 +1625,34 @@ mod tests {
}
}
#[test]
fn test_nfs4_response_create_session() {
let buf: &[u8] = &[
0x00, 0x00, 0x00, 0x2b, /*opcode*/
0x00, 0x00, 0x00, 0x00, /*status*/
// create_session
0x00, 0x00, 0x02, 0xd2, 0xe0, 0x14, 0x82, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x00,
0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x02, 0x80,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
];
let (_, create_ssn) = nfs4_parse_res_create_session(&buf[8..]).unwrap();
let (_, response) = nfs4_res_create_session(&buf[4..]).unwrap();
match response {
Nfs4ResponseContent::CreateSession( status, create_ssn_data) => {
assert_eq!(status, 0);
assert_eq!(create_ssn_data, Some(create_ssn));
}
_ => { panic!("Failure"); }
}
}
}

@ -273,6 +273,7 @@ pub const NFSPROC4_SETCLIENTID_CONFIRM: u32 = 36;
pub const NFSPROC4_VERIFY: u32 = 37;
pub const NFSPROC4_WRITE: u32 = 38;
pub const NFSPROC4_RELEASE_LOCKOWNER: u32 = 39;
pub const NFSPROC4_CREATE_SESSION: u32 = 43;
pub const NFSPROC4_SEQUENCE: u32 = 53;

Loading…
Cancel
Save