//! 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};
SetClientIdConfirm,
ExchangeId(Nfs4RequestExchangeId<'a>),
Sequence(Nfs4RequestSequence<'a>),
+ CreateSession(Nfs4RequestCreateSession<'a>),
}
#[derive(Debug,PartialEq)]
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)
}
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))
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)]
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))
}
}
+ #[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]
}
}
+ #[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"); }
+ }
+ }
}