]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs: split record parsers into different files
authorVictor Julien <victor@inliniac.net>
Wed, 14 Jun 2017 08:22:08 +0000 (10:22 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 16 Jun 2017 11:11:36 +0000 (13:11 +0200)
rust/src/nfs/mod.rs
rust/src/nfs/nfs2_records.rs
rust/src/nfs/nfs3.rs
rust/src/nfs/nfs3_records.rs [moved from rust/src/nfs/parser.rs with 59% similarity]
rust/src/nfs/nfs_records.rs [new file with mode: 0644]
rust/src/nfs/rpc_records.rs [new file with mode: 0644]

index 0b515a7c9f5f2a5827b0ce8fe9246997c8251fc2..0a03505aec1b4f4d561485f632a9f6ea46114b73 100644 (file)
  */
 
 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;
 
index 0d8733d3464970e6cc4f26bac23277ef9df8b035..46663eb29f01ed7c0a82f32cbe80c6d6b0a02755 100644 (file)
@@ -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,
index 7dc18e29073cf5e22c4083cc67147b176471061a..edfc719d49f98d97840622fde4705cee3d2dc036 100644 (file)
@@ -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);
 
similarity index 59%
rename from rust/src/nfs/parser.rs
rename to rust/src/nfs/nfs3_records.rs
index 5a8714c32991e9860767f3353de5f6397cbef114..41e88679fc9fcf48ec561b923e0b2810845edc2b 100644 (file)
 //! 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,
-           }
-   ))
-);
diff --git a/rust/src/nfs/nfs_records.rs b/rust/src/nfs/nfs_records.rs
new file mode 100644 (file)
index 0000000..a818788
--- /dev/null
@@ -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
+}
diff --git a/rust/src/nfs/rpc_records.rs b/rust/src/nfs/rpc_records.rs
new file mode 100644 (file)
index 0000000..361d5c0
--- /dev/null
@@ -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,
+           }
+   ))
+);