* 02110-1301, USA.
*/
+use crate::smb::error::SmbError;
use nom;
use nom::IResult;
-use nom::error::ErrorKind;
use nom::combinator::rest;
use nom::number::Endianness;
use nom::number::complete::{be_u16, le_u8, le_u16, le_u32};
/// parse a packet type 'response' DCERPC record. Implemented
/// as function to be able to pass the fraglen in.
pub fn parse_dcerpc_response_record(i:&[u8], frag_len: u16 )
- -> IResult<&[u8], DceRpcResponseRecord>
+ -> IResult<&[u8], DceRpcResponseRecord, SmbError>
{
if frag_len < 24 {
- return Err(nom::Err::Error(error_position!(i,ErrorKind::Custom(128))));
+ return Err(nom::Err::Error(SmbError::RecordTooSmall));
}
do_parse!(i,
take!(8)
/// parse a packet type 'request' DCERPC record. Implemented
/// as function to be able to pass the fraglen in.
pub fn parse_dcerpc_request_record(i:&[u8], frag_len: u16, little: bool)
- -> IResult<&[u8], DceRpcRequestRecord>
+ -> IResult<&[u8], DceRpcRequestRecord, SmbError>
{
if frag_len < 24 {
- return Err(nom::Err::Error(error_position!(i,ErrorKind::Custom(128))));
+ return Err(nom::Err::Error(SmbError::RecordTooSmall));
}
do_parse!(i,
take!(6)
--- /dev/null
+/* Copyright (C) 2019 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.
+ */
+
+// Author: Pierre Chifflier <chifflier@wzdftpd.net>
+use nom::error::{ErrorKind, ParseError};
+
+#[derive(Debug)]
+pub enum SmbError {
+ BadEncoding,
+ RecordTooSmall,
+ NomError(ErrorKind),
+}
+
+impl<I> ParseError<I> for SmbError {
+ fn from_error_kind(_input: I, kind: ErrorKind) -> Self {
+ SmbError::NomError(kind)
+ }
+ fn append(_input: I, kind: ErrorKind, _other: Self) -> Self {
+ SmbError::NomError(kind)
+ }
+}
* 02110-1301, USA.
*/
+pub mod error;
pub mod smb_records;
pub mod smb1_records;
pub mod smb2_records;
* 02110-1301, USA.
*/
+use crate::smb::error::SmbError;
use crate::log::*;
use nom::IResult;
use nom::combinator::rest;
use crate::smb::smb::*;
use crate::smb::smb_records::*;
-fn smb_get_unicode_string_with_offset(i: &[u8], offset: usize) -> IResult<&[u8], Vec<u8>>
+fn smb_get_unicode_string_with_offset(i: &[u8], offset: usize) -> IResult<&[u8], Vec<u8>, SmbError>
{
do_parse!(i,
cond!(offset % 2 == 1, take!(1))
}
/// take a string, unicode or ascii based on record
-pub fn smb1_get_string<'a>(i: &'a[u8], r: &SmbRecord, offset: usize) -> IResult<&'a[u8], Vec<u8>> {
+pub fn smb1_get_string<'a>(i: &'a[u8], r: &SmbRecord, offset: usize) -> IResult<&'a[u8], Vec<u8>, SmbError> {
if r.has_unicode_support() {
smb_get_unicode_string_with_offset(i, offset)
} else {
pub service: &'a[u8],
}
-pub fn parse_smb_connect_tree_andx_record<'a>(i: &'a[u8], r: &SmbRecord) -> IResult<&'a[u8], SmbRecordTreeConnectAndX<'a>> {
+pub fn parse_smb_connect_tree_andx_record<'a>(i: &'a[u8], r: &SmbRecord) -> IResult<&'a[u8], SmbRecordTreeConnectAndX<'a>, SmbError> {
do_parse!(i,
_skip1: take!(7)
>> pwlen: le_u16
pub fid: &'a[u8],
}
-named!(pub parse_smb_trans_request_record_pipe<SmbPipeProtocolRecord>,
+named!(pub parse_smb_trans_request_record_pipe<&[u8], SmbPipeProtocolRecord, SmbError>,
do_parse!(
fun: le_u16
>> fid: take!(2)
bcc: u16,
}
-named!(pub parse_smb_trans_request_record_params<(SmbRecordTransRequestParams, Option<SmbPipeProtocolRecord>)>,
+named!(pub parse_smb_trans_request_record_params<&[u8], (SmbRecordTransRequestParams, Option<SmbPipeProtocolRecord>), SmbError>,
do_parse!(
wct: le_u8
>> _total_param_cnt: le_u16
pub fn parse_smb_trans_request_record_data(i: &[u8],
pad1: usize, param_cnt: u16, pad2: usize, data_len: u16)
- -> IResult<&[u8], SmbRecordTransRequestData>
+ -> IResult<&[u8], SmbRecordTransRequestData, SmbError>
{
do_parse!(i,
take!(pad1)
}
pub fn parse_smb_trans_request_record<'a, 'b>(i: &'a[u8], r: &SmbRecord<'b>)
- -> IResult<&'a[u8], SmbRecordTransRequest<'a>>
+ -> IResult<&'a[u8], SmbRecordTransRequest<'a>, SmbError>
{
let (rem, (params, pipe)) = parse_smb_trans_request_record_params(i)?;
let mut offset = 32 + (i.len() - rem.len()); // init with SMB header
pub newname: Vec<u8>,
}
-named!(pub parse_smb_rename_request_record<SmbRequestRenameRecord>,
+named!(pub parse_smb_rename_request_record<&[u8], SmbRequestRenameRecord, SmbError>,
do_parse!(
_wct: le_u8
>> _search_attr: le_u16
}
pub fn parse_smb_create_andx_request_record<'a>(i: &'a[u8], r: &SmbRecord)
- -> IResult<&'a[u8], SmbRequestCreateAndXRecord<>>
+ -> IResult<&'a[u8], SmbRequestCreateAndXRecord<>, SmbError>
{
do_parse!(i,
_skip1: take!(6)
pub oldname: Vec<u8>,
}
-named!(pub parse_trans2_request_params_set_path_info<Trans2RecordParamSetPathInfo>,
+named!(pub parse_trans2_request_params_set_path_info<&[u8], Trans2RecordParamSetPathInfo, SmbError>,
do_parse!(
loi: le_u16
>> _reserved: take!(4)
* 02110-1301, USA.
*/
+use crate::smb::error::SmbError;
use nom;
use nom::IResult;
-use nom::error::ErrorKind;
use crate::log::*;
/// parse a UTF16 string that is null terminated. Normally by 2 null
/// bytes, but at the end of the data it can also be a single null.
/// Skip every second byte.
-pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec<u8>>
+pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError>
{
SCLogDebug!("get_unicode_string: blob {} {:?}", blob.len(), blob);
let mut name : Vec<u8> = Vec::new();
name.push(c[0]);
c = &c[2..];
}
- Err(nom::Err::Error(error_position!(blob,ErrorKind::Custom(130))))
+ Err(nom::Err::Error(SmbError::BadEncoding))
}
// parse an ASCII string that is null terminated
-named!(pub smb_get_ascii_string<Vec<u8>>,
+named!(pub smb_get_ascii_string<&[u8], Vec<u8>, SmbError>,
do_parse!(
s: take_until_and_consume!("\x00")
>> ( s.to_vec() )