nfs: split record parsers into different files

pull/2787/head
Victor Julien 8 years ago
parent 25edac7666
commit 9edbb6f235

@ -16,9 +16,10 @@
*/
pub mod types;
#[macro_use]
pub mod parser;
pub mod rpc_records;
pub mod nfs_records;
pub mod nfs2_records;
pub mod nfs3_records;
pub mod nfs3;
pub mod log;

@ -17,7 +17,7 @@
//! Nom parsers for NFSv2 records
use nom::{be_u32, rest};
use nfs::parser::*;
use nfs::nfs_records::*;
#[derive(Debug,PartialEq)]
pub struct Nfs2Handle<'a> {
@ -73,14 +73,14 @@ named!(pub parse_nfs2_request_read<Nfs2RequestRead>,
))
);
named!(pub parse_nfs2_reply_read<Nfs3ReplyRead>,
named!(pub parse_nfs2_reply_read<NfsReplyRead>,
do_parse!(
status: be_u32
>> attr_blob: take!(68)
>> data_len: be_u32
>> data_contents: rest
>> (
Nfs3ReplyRead {
NfsReplyRead {
status:status,
attr_follows:1,
attr_blob:attr_blob,

@ -35,8 +35,10 @@ use filecontainer::*;
//use storage::*;
use nfs::types::*;
use nfs::parser::*;
use nfs::rpc_records::*;
use nfs::nfs_records::*;
use nfs::nfs2_records::*;
use nfs::nfs3_records::*;
/// nom bug leads to this wrappers being necessary
/// TODO for some reason putting these in parser.rs and making them public
@ -1038,7 +1040,7 @@ impl NFS3State {
/// xidmapr is an Option as it's already removed from the map if we
/// have a complete record. Otherwise we do a lookup ourselves.
fn process_read_record<'b>(&mut self, r: &RpcReplyPacket<'b>,
reply: &Nfs3ReplyRead<'b>, xidmapr: Option<&NFS3RequestXidMap>) -> u32
reply: &NfsReplyRead<'b>, xidmapr: Option<&NFS3RequestXidMap>) -> u32
{
let file_name;
let file_handle;
@ -1141,7 +1143,7 @@ impl NFS3State {
0
}
fn process_partial_read_reply_record<'b>(&mut self, r: &RpcReplyPacket<'b>, reply: &Nfs3ReplyRead<'b>) -> u32 {
fn process_partial_read_reply_record<'b>(&mut self, r: &RpcReplyPacket<'b>, reply: &NfsReplyRead<'b>) -> u32 {
SCLogDebug!("REPLY {} to procedure READ blob size {} / {}",
r.hdr.xid, r.prog_data.len(), reply.count);

@ -18,42 +18,7 @@
//! Nom parsers for RPC & NFSv3
use nom::{be_u32, be_u64, rest};
#[derive(Debug,PartialEq)]
pub struct RpcRequestCredsUnix<'a> {
pub stamp: u32,
pub machine_name_len: u32,
pub machine_name_buf: &'a[u8],
pub uid: u32,
pub gid: u32,
pub aux_gids: Option<Vec<u32>>,
// list of gids
}
//named!(parse_rpc_creds_unix_aux_gids<Vec<u32>>,
// many0!(be_u32)
//);
named!(pub parse_rfc_request_creds_unix<RpcRequestCredsUnix>,
do_parse!(
stamp: be_u32
>> machine_name_len: be_u32
>> machine_name_buf: take!(machine_name_len)
>> uid: be_u32
>> gid: be_u32
//>> aux_gids: parse_rpc_creds_unix_aux_gids
>> (
RpcRequestCredsUnix {
stamp:stamp,
machine_name_len:machine_name_len,
machine_name_buf:machine_name_buf,
uid:uid,
gid:gid,
aux_gids:None,
}
))
);
use nfs::nfs_records::*;
#[derive(Debug,PartialEq)]
pub struct Nfs3Handle<'a> {
@ -439,7 +404,7 @@ named!(pub parse_nfs3_request_write<Nfs3RequestWrite>,
}
))
);
/*
#[derive(Debug,PartialEq)]
pub struct Nfs3ReplyRead<'a> {
pub status: u32,
@ -450,8 +415,8 @@ pub struct Nfs3ReplyRead<'a> {
pub data_len: u32,
pub data: &'a[u8], // likely partial
}
named!(pub parse_nfs3_reply_read<Nfs3ReplyRead>,
*/
named!(pub parse_nfs3_reply_read<NfsReplyRead>,
do_parse!(
status: be_u32
>> attr_follows: be_u32
@ -461,7 +426,7 @@ named!(pub parse_nfs3_reply_read<Nfs3ReplyRead>,
>> data_len: be_u32
>> data_contents: rest
>> (
Nfs3ReplyRead {
NfsReplyRead {
status:status,
attr_follows:attr_follows,
attr_blob:attr_blob,
@ -472,274 +437,3 @@ named!(pub parse_nfs3_reply_read<Nfs3ReplyRead>,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcPacketHeader<> {
pub frag_is_last: bool,
pub frag_len: u32,
pub xid: u32,
pub msgtype: u32,
}
named!(pub parse_rpc_packet_header<RpcPacketHeader>,
do_parse!(
fraghdr: bits!(tuple!(
take_bits!(u8, 1), // is_last
take_bits!(u32, 31))) // len
>> xid: be_u32
>> msgtype: be_u32
>> (
RpcPacketHeader {
frag_is_last:fraghdr.0 == 1,
frag_len:fraghdr.1,
xid:xid,
msgtype:msgtype,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcReplyPacket<'a> {
pub hdr: RpcPacketHeader<>,
pub verifier_flavor: u32,
pub verifier_len: u32,
pub verifier: Option<&'a[u8]>,
pub reply_state: u32,
pub accept_state: u32,
pub prog_data: &'a[u8],
}
// top of request packet, just to get to procedure
#[derive(Debug)]
pub struct RpcRequestPacketPartial {
pub hdr: RpcPacketHeader,
pub rpcver: u32,
pub program: u32,
pub progver: u32,
pub procedure: u32,
}
named!(pub parse_rpc_request_partial<RpcRequestPacketPartial>,
do_parse!(
hdr: parse_rpc_packet_header
>> rpcver: be_u32
>> program: be_u32
>> progver: be_u32
>> procedure: be_u32
>> (
RpcRequestPacketPartial {
hdr:hdr,
rpcver:rpcver,
program:program,
progver:progver,
procedure:procedure,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcPacket<'a> {
pub hdr: RpcPacketHeader<>,
pub rpcver: u32,
pub program: u32,
pub progver: u32,
pub procedure: u32,
pub creds_flavor: u32,
pub creds_len: u32,
pub creds: Option<&'a[u8]>,
pub creds_unix:Option<RpcRequestCredsUnix<'a>>,
pub verifier_flavor: u32,
pub verifier_len: u32,
pub verifier: Option<&'a[u8]>,
pub prog_data: &'a[u8],
}
named!(pub parse_rpc<RpcPacket>,
do_parse!(
hdr: parse_rpc_packet_header
>> rpcver: be_u32
>> program: be_u32
>> progver: be_u32
>> procedure: be_u32
>> creds_flavor: be_u32
>> creds_len: be_u32
>> creds: cond!(creds_flavor != 1 && creds_len > 0, take!(creds_len as usize))
>> creds_unix: cond!(creds_len > 0 && creds_flavor == 1, flat_map!(take!((creds_len) as usize),parse_rfc_request_creds_unix))
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> pl: rest
>> (
RpcPacket {
hdr:hdr,
rpcver:rpcver,
program:program,
progver:progver,
procedure:procedure,
creds_flavor:creds_flavor,
creds_len:creds_len,
creds:creds,
creds_unix:creds_unix,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
prog_data:pl,
}
))
);
// to be called with data <= hdr.frag_len + 4. Sending more data is undefined.
named!(pub parse_rpc_reply<RpcReplyPacket>,
do_parse!(
hdr: parse_rpc_packet_header
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> reply_state: be_u32
>> accept_state: be_u32
>> pl: rest
>> (
RpcReplyPacket {
hdr:hdr,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
reply_state:reply_state,
accept_state:accept_state,
prog_data:pl,
}
))
);
named!(pub parse_rpc_udp_packet_header<RpcPacketHeader>,
do_parse!(
xid: be_u32
>> msgtype: be_u32
>> (
RpcPacketHeader {
frag_is_last:false,
frag_len:0,
xid:xid,
msgtype:msgtype,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcUdpRequestPacket<'a> {
pub hdr: RpcPacketHeader<>,
pub rpcver: u32,
pub program: u32,
pub progver: u32,
pub procedure: u32,
pub creds_flavor: u32,
pub creds_len: u32,
pub creds: Option<&'a[u8]>,
pub creds_unix:Option<RpcRequestCredsUnix<'a>>,
pub verifier_flavor: u32,
pub verifier_len: u32,
pub verifier: Option<&'a[u8]>,
pub prog_data: &'a[u8],
}
named!(pub parse_rpc_udp_request<RpcPacket>,
do_parse!(
hdr: parse_rpc_udp_packet_header
>> rpcver: be_u32
>> program: be_u32
>> progver: be_u32
>> procedure: be_u32
>> creds_flavor: be_u32
>> creds_len: be_u32
>> creds: cond!(creds_flavor != 1 && creds_len > 0, take!(creds_len as usize))
>> creds_unix: cond!(creds_len > 0 && creds_flavor == 1, flat_map!(take!((creds_len) as usize),parse_rfc_request_creds_unix))
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> pl: rest
>> (
RpcPacket {
hdr:hdr,
rpcver:rpcver,
program:program,
progver:progver,
procedure:procedure,
creds_flavor:creds_flavor,
creds_len:creds_len,
creds:creds,
creds_unix:creds_unix,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
prog_data:pl,
}
))
);
named!(pub parse_rpc_udp_reply<RpcReplyPacket>,
do_parse!(
hdr: parse_rpc_udp_packet_header
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> reply_state: be_u32
>> accept_state: be_u32
>> pl: rest
>> (
RpcReplyPacket {
hdr:hdr,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
reply_state:reply_state,
accept_state:accept_state,
prog_data:pl,
}
))
);

@ -0,0 +1,29 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
//! Nom parsers for NFS
#[derive(Debug,PartialEq)]
pub struct NfsReplyRead<'a> {
pub status: u32,
pub attr_follows: u32,
pub attr_blob: &'a[u8],
pub count: u32,
pub eof: bool,
pub data_len: u32,
pub data: &'a[u8], // likely partial
}

@ -0,0 +1,327 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
//! Nom parsers for RPC & NFSv3
use nom::{be_u32, be_u64, rest};
#[derive(Debug,PartialEq)]
pub struct RpcRequestCredsUnix<'a> {
pub stamp: u32,
pub machine_name_len: u32,
pub machine_name_buf: &'a[u8],
pub uid: u32,
pub gid: u32,
pub aux_gids: Option<Vec<u32>>,
// list of gids
}
//named!(parse_rpc_creds_unix_aux_gids<Vec<u32>>,
// many0!(be_u32)
//);
named!(pub parse_rfc_request_creds_unix<RpcRequestCredsUnix>,
do_parse!(
stamp: be_u32
>> machine_name_len: be_u32
>> machine_name_buf: take!(machine_name_len)
>> uid: be_u32
>> gid: be_u32
//>> aux_gids: parse_rpc_creds_unix_aux_gids
>> (
RpcRequestCredsUnix {
stamp:stamp,
machine_name_len:machine_name_len,
machine_name_buf:machine_name_buf,
uid:uid,
gid:gid,
aux_gids:None,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcPacketHeader<> {
pub frag_is_last: bool,
pub frag_len: u32,
pub xid: u32,
pub msgtype: u32,
}
named!(pub parse_rpc_packet_header<RpcPacketHeader>,
do_parse!(
fraghdr: bits!(tuple!(
take_bits!(u8, 1), // is_last
take_bits!(u32, 31))) // len
>> xid: be_u32
>> msgtype: be_u32
>> (
RpcPacketHeader {
frag_is_last:fraghdr.0 == 1,
frag_len:fraghdr.1,
xid:xid,
msgtype:msgtype,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcReplyPacket<'a> {
pub hdr: RpcPacketHeader<>,
pub verifier_flavor: u32,
pub verifier_len: u32,
pub verifier: Option<&'a[u8]>,
pub reply_state: u32,
pub accept_state: u32,
pub prog_data: &'a[u8],
}
// top of request packet, just to get to procedure
#[derive(Debug)]
pub struct RpcRequestPacketPartial {
pub hdr: RpcPacketHeader,
pub rpcver: u32,
pub program: u32,
pub progver: u32,
pub procedure: u32,
}
named!(pub parse_rpc_request_partial<RpcRequestPacketPartial>,
do_parse!(
hdr: parse_rpc_packet_header
>> rpcver: be_u32
>> program: be_u32
>> progver: be_u32
>> procedure: be_u32
>> (
RpcRequestPacketPartial {
hdr:hdr,
rpcver:rpcver,
program:program,
progver:progver,
procedure:procedure,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcPacket<'a> {
pub hdr: RpcPacketHeader<>,
pub rpcver: u32,
pub program: u32,
pub progver: u32,
pub procedure: u32,
pub creds_flavor: u32,
pub creds_len: u32,
pub creds: Option<&'a[u8]>,
pub creds_unix:Option<RpcRequestCredsUnix<'a>>,
pub verifier_flavor: u32,
pub verifier_len: u32,
pub verifier: Option<&'a[u8]>,
pub prog_data: &'a[u8],
}
named!(pub parse_rpc<RpcPacket>,
do_parse!(
hdr: parse_rpc_packet_header
>> rpcver: be_u32
>> program: be_u32
>> progver: be_u32
>> procedure: be_u32
>> creds_flavor: be_u32
>> creds_len: be_u32
>> creds: cond!(creds_flavor != 1 && creds_len > 0, take!(creds_len as usize))
>> creds_unix: cond!(creds_len > 0 && creds_flavor == 1, flat_map!(take!((creds_len) as usize),parse_rfc_request_creds_unix))
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> pl: rest
>> (
RpcPacket {
hdr:hdr,
rpcver:rpcver,
program:program,
progver:progver,
procedure:procedure,
creds_flavor:creds_flavor,
creds_len:creds_len,
creds:creds,
creds_unix:creds_unix,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
prog_data:pl,
}
))
);
// to be called with data <= hdr.frag_len + 4. Sending more data is undefined.
named!(pub parse_rpc_reply<RpcReplyPacket>,
do_parse!(
hdr: parse_rpc_packet_header
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> reply_state: be_u32
>> accept_state: be_u32
>> pl: rest
>> (
RpcReplyPacket {
hdr:hdr,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
reply_state:reply_state,
accept_state:accept_state,
prog_data:pl,
}
))
);
named!(pub parse_rpc_udp_packet_header<RpcPacketHeader>,
do_parse!(
xid: be_u32
>> msgtype: be_u32
>> (
RpcPacketHeader {
frag_is_last:false,
frag_len:0,
xid:xid,
msgtype:msgtype,
}
))
);
#[derive(Debug,PartialEq)]
pub struct RpcUdpRequestPacket<'a> {
pub hdr: RpcPacketHeader<>,
pub rpcver: u32,
pub program: u32,
pub progver: u32,
pub procedure: u32,
pub creds_flavor: u32,
pub creds_len: u32,
pub creds: Option<&'a[u8]>,
pub creds_unix:Option<RpcRequestCredsUnix<'a>>,
pub verifier_flavor: u32,
pub verifier_len: u32,
pub verifier: Option<&'a[u8]>,
pub prog_data: &'a[u8],
}
named!(pub parse_rpc_udp_request<RpcPacket>,
do_parse!(
hdr: parse_rpc_udp_packet_header
>> rpcver: be_u32
>> program: be_u32
>> progver: be_u32
>> procedure: be_u32
>> creds_flavor: be_u32
>> creds_len: be_u32
>> creds: cond!(creds_flavor != 1 && creds_len > 0, take!(creds_len as usize))
>> creds_unix: cond!(creds_len > 0 && creds_flavor == 1, flat_map!(take!((creds_len) as usize),parse_rfc_request_creds_unix))
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> pl: rest
>> (
RpcPacket {
hdr:hdr,
rpcver:rpcver,
program:program,
progver:progver,
procedure:procedure,
creds_flavor:creds_flavor,
creds_len:creds_len,
creds:creds,
creds_unix:creds_unix,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
prog_data:pl,
}
))
);
named!(pub parse_rpc_udp_reply<RpcReplyPacket>,
do_parse!(
hdr: parse_rpc_udp_packet_header
>> verifier_flavor: be_u32
>> verifier_len: be_u32
>> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
>> reply_state: be_u32
>> accept_state: be_u32
>> pl: rest
>> (
RpcReplyPacket {
hdr:hdr,
verifier_flavor:verifier_flavor,
verifier_len:verifier_len,
verifier:verifier,
reply_state:reply_state,
accept_state:accept_state,
prog_data:pl,
}
))
);
Loading…
Cancel
Save