rust: Add types annotation when required

Unfortunately, the transition to nom 5 (and functions instead of macros)
has side-effects, one of them being requiring lots of types annotations
when using a parsing, for ex in a match instruction.
pull/4624/head
Pierre Chifflier 7 years ago committed by Victor Julien
parent 62e31396ae
commit f3ddd7127c

@ -25,6 +25,7 @@ use crate::applayer::LoggerFlags;
use crate::core;
use crate::dns::parser;
use nom::IResult;
use nom::number::complete::be_u16;
/// DNS record types.
@ -445,8 +446,8 @@ impl DNSState {
let mut count = 0;
while self.request_buffer.len() > 0 {
let size = match be_u16(&self.request_buffer) {
Ok((_, len)) => len,
let size = match be_u16(&self.request_buffer) as IResult<&[u8],_> {
Ok((_, len)) => i32::from(len),
_ => 0
} as usize;
SCLogDebug!("Have {} bytes, need {} to parse",
@ -486,8 +487,8 @@ impl DNSState {
let mut count = 0;
while self.response_buffer.len() > 0 {
let size = match be_u16(&self.response_buffer) {
Ok((_, len)) => len,
let size = match be_u16(&self.response_buffer) as IResult<&[u8],_> {
Ok((_, len)) => i32::from(len),
_ => 0
} as usize;
if size > 0 && self.response_buffer.len() >= size + 2 {
@ -535,7 +536,7 @@ fn probe(input: &[u8]) -> (bool, bool) {
/// Probe TCP input to see if it looks like DNS.
pub fn probe_tcp(input: &[u8]) -> (bool, bool) {
match be_u16(input) {
match be_u16(input) as IResult<&[u8],_> {
Ok((rem, _)) => {
return probe(rem);
},

@ -19,6 +19,7 @@
use nom::IResult;
use nom::error::ErrorKind;
use nom::multi::length_data;
use nom::number::complete::{be_u8, be_u16, be_u32};
use nom;
use crate::dns::dns::*;
@ -69,7 +70,7 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
pos = &pos[1..];
break;
} else if len & 0b1100_0000 == 0 {
match length_data!(pos, be_u8) {
match length_data(be_u8)(pos) as IResult<&[u8],_> {
Ok((rem, label)) => {
if name.len() > 0 {
name.push('.' as u8);
@ -83,14 +84,14 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
}
}
} else if len & 0b1100_0000 == 0b1100_0000 {
match be_u16(pos) {
match be_u16(pos) as IResult<&[u8],_> {
Ok((rem, leader)) => {
let offset = leader & 0x3fff;
if offset as usize > message.len() {
let offset = usize::from(leader) & 0x3fff;
if offset > message.len() {
return Err(nom::Err::Error(
error_position!(pos, ErrorKind::OctDigit)));
}
pos = &message[offset as usize..];
pos = &message[offset..];
if pivot == start {
pivot = rem;
}

@ -31,7 +31,7 @@ use crate::log::*;
named!(getu16<u16>,
map_res!(
map_res!(
sep!(digit1, multispace0),
delimited!(multispace0, digit1, multispace0),
str::from_utf8
),
FromStr::from_str
@ -46,7 +46,7 @@ named!(parse_u16<u16>,
named!(pub ftp_active_port<u16>,
do_parse!(
tag!("PORT") >>
sep!(digit1, multispace0) >> tag!(",") >> digit1 >> tag!(",") >>
delimited!(multispace0, digit1, multispace0) >> tag!(",") >> digit1 >> tag!(",") >>
digit1 >> tag!(",") >> digit1 >> tag!(",") >>
part1: verify!(parse_u16, |&v| v <= std::u8::MAX as u16) >>
tag!(",") >>

@ -20,6 +20,7 @@
use std;
use std::ffi::{CStr,CString};
use nom;
use nom::IResult;
use nom::number::complete::be_u32;
use der_parser::der::der_read_element_header;
use kerberos_parser::krb5_parser;
@ -477,7 +478,7 @@ pub extern "C" fn rs_krb5_probing_parser_tcp(_flow: *const Flow,
{
let slice = build_slice!(input,input_len as usize);
if slice.len() <= 14 { return unsafe{ALPROTO_FAILED}; }
match be_u32(slice) {
match be_u32(slice) as IResult<&[u8],u32> {
Ok((rem, record_mark)) => {
// protocol implementations forbid very large requests
if record_mark > 16384 { return unsafe{ALPROTO_FAILED}; }
@ -550,7 +551,7 @@ pub extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
let mut cur_i = tcp_buffer;
while cur_i.len() > 0 {
if state.record_ts == 0 {
match be_u32(cur_i) {
match be_u32(cur_i) as IResult<&[u8],u32> {
Ok((rem,record)) => {
state.record_ts = record as usize;
cur_i = rem;
@ -608,7 +609,7 @@ pub extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow,
let mut cur_i = tcp_buffer;
while cur_i.len() > 0 {
if state.record_tc == 0 {
match be_u32(cur_i) {
match be_u32(cur_i) as IResult<&[u8],_> {
Ok((rem,record)) => {
state.record_tc = record as usize;
cur_i = rem;

@ -24,6 +24,7 @@ use crate::nfs::types::*;
use crate::nfs::rpc_records::*;
use crate::nfs::nfs2_records::*;
use nom::IResult;
use nom::number::complete::be_u32;
impl NFSState {
@ -109,7 +110,7 @@ impl NFSState {
},
}
} else {
let stat = match be_u32(&r.prog_data) {
let stat = match be_u32(&r.prog_data) as IResult<&[u8],_> {
Ok((_, stat)) => {
stat as u32
}

@ -25,6 +25,7 @@ use crate::nfs::types::*;
use crate::nfs::rpc_records::*;
use crate::nfs::nfs3_records::*;
use nom::IResult;
use nom::number::complete::be_u32;
impl NFSState {
@ -327,7 +328,7 @@ impl NFSState {
}
// for all other record types only parse the status
else {
let stat = match be_u32(&r.prog_data) {
let stat = match be_u32(&r.prog_data) as IResult<&[u8],_> {
Ok((_, stat)) => {
stat as u32
}

@ -17,6 +17,7 @@
//! Nom parsers for RPCv2
use nom::IResult;
use nom::combinator::rest;
use nom::number::complete::be_u32;
@ -120,12 +121,16 @@ pub struct RpcPacketHeader<> {
pub msgtype: u32,
}
fn parse_bits(i:&[u8]) -> IResult<&[u8],(u8,u32)> {
bits!(i,
tuple!(
take_bits!(1u8), // is_last
take_bits!(31u32))) // len
}
named!(pub parse_rpc_packet_header<RpcPacketHeader>,
do_parse!(
fraghdr: bits!(tuple!(
take_bits!(1u8), // is_last
take_bits!(31u32))) // len
fraghdr: parse_bits
>> xid: be_u32
>> msgtype: be_u32
>> (

@ -27,7 +27,8 @@
//! * x.691-spec: <https://www.itu.int/rec/T-REC-X.691/en>
use nom::IResult;
use nom::error::{make_error, ErrorKind};
use nom::bytes::complete::take;
use nom::combinator::{opt, map_opt, map_res};
use nom::number::complete::{be_u16, be_u8, le_u16, le_u32, le_u8};
use crate::rdp::error::RdpError;
use crate::rdp::util::{
@ -480,19 +481,19 @@ pub fn parse_t123_tpkt(input: &[u8]) -> IResult<&[u8], T123Tpkt, RdpError> {
return Ok((i4, T123Tpkt { child }));
}
fn take_4_4_bits(input: &[u8]) -> IResult<&[u8], (u8,u8), RdpError> {
map!(input, be_u8, |b| (b >> 4, b & 0xf))
}
/// rdp-spec, section 2.2.1.1
fn parse_x224_connection_request(
input: &[u8],
) -> IResult<&[u8], X224ConnectionRequest, RdpError> {
let (i1, length) = verify!(input, be_u8, |&x| x != 0xff)?; // 0xff is reserved
let (i2, cr_cdt) = bits!(
i1,
tuple!(
verify!(take_bits!(4u8), |&x| x
== X224Type::ConnectionRequest as u8),
verify!(take_bits!(4u8), |&x| x == 0 || x == 1)
)
)?;
let (i2, cr_cdt) = take_4_4_bits(input)?;
let _ = verify!(i1, value!(cr_cdt.0), |&x| x
== X224Type::ConnectionRequest as u8)?;
let _ = verify!(i1, value!(cr_cdt.1), |&x| x == 0 || x == 1)?;
let (i3, dst_ref) = verify!(i2, be_u16, |&x| x == 0)?;
let (i4, src_ref) = try_parse!(i3, be_u16);
let (i5, class_options) = bits!(
@ -503,9 +504,7 @@ fn parse_x224_connection_request(
)
)?;
// less cr_cdt (u8), dst_ref (u16), src_ref (u16), class_options (u8)
if length < 6 {
return make_error(i5, ErrorKind::Verify)?;
}
let _ = verify!(i1, value!(length), |&x| x >= 6)?;
let i6 = i5;
let sz = length - 6;
@ -575,12 +574,8 @@ fn parse_x224_connection_request_class_0(
fn parse_rdp_cookie(input: &[u8]) -> IResult<&[u8], RdpCookie, RdpError> {
do_parse! {
input,
_key: verify!(
take!(8),
|x| x == b"Cookie: ")
>> _name: verify!(
take!(9),
|x| x == b"mstshash=")
_key: tag!(b"Cookie: ")
>> _name: tag!(b"mstshash=")
>> bytes: take_until_and_consume!("\r\n")
>> s: map_res!(value!(bytes), std::str::from_utf8)
>> (RdpCookie{ mstshash: String::from(s) })
@ -616,14 +611,10 @@ fn parse_x224_connection_confirm(
input: &[u8],
) -> IResult<&[u8], X224ConnectionConfirm, RdpError> {
let (i1, length) = verify!(input, be_u8, |&x| x != 0xff)?; // 0xff is reserved
let (i2, cr_cdt) = bits!(
i1,
tuple!(
verify!(take_bits!(4u8), |&x| x
== X224Type::ConnectionConfirm as u8),
verify!(take_bits!(4u8), |&x| x == 0 || x == 1)
)
)?;
let (i2, cr_cdt) = take_4_4_bits(input)?;
let _ = verify!(i1, value!(cr_cdt.0), |&x| x
== X224Type::ConnectionConfirm as u8)?;
let _ = verify!(i1, value!(cr_cdt.1), |&x| x == 0 || x == 1)?;
let (i3, dst_ref) = verify!(i2, be_u16, |&x| x == 0)?;
let (i4, src_ref) = try_parse!(i3, be_u16);
let (i5, class_options) = bits!(
@ -635,9 +626,7 @@ fn parse_x224_connection_confirm(
)?;
// less cr_cdt (u8), dst_ref (u16), src_ref (u16), class_options (u8)
if length < 6 {
return make_error(i5, ErrorKind::Verify)?;
}
let _ = verify!(i1, value!(length), |&x| x >= 6)?;
let i6 = i5;
let sz = length - 6;
@ -744,15 +733,18 @@ fn parse_negotiation_failure(
/// x224-spec, section 13.7
fn parse_x223_data_class_0(input: &[u8]) -> IResult<&[u8], X223Data, RdpError> {
let (i1, _length) = verify!(input, be_u8, |&x| x == 2)?;
let (i2, _dt_x_roa) = bits!(
i1,
tuple!(
verify!(take_bits!(4u8), |&x| x == 0xf),
verify!(take_bits!(3u8), |&x| x == 0),
verify!(take_bits!(1u8), |&x| x == 0)
fn parser(input: &[u8]) -> IResult<&[u8], (u8,u8,u8), RdpError> {
bits!(
input,
tuple!(
verify!(take_bits!(4u8), |&x| x == 0xf),
verify!(take_bits!(3u8), |&x| x == 0),
verify!(take_bits!(1u8), |&x| x == 0)
)
)
)?;
}
let (i1, _length) = verify!(input, be_u8, |&x| x == 2)?;
let (i2, _dt_x_roa) = parser(i1)?;
let (i3, _eot) = verify!(i2, be_u8, |&x| x == 0x80)?;
//
@ -889,14 +881,14 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
//
let (j13, post_beta2_color_depth) =
match opt!(j12, map_opt!(le_u16, num::FromPrimitive::from_u16)) {
match opt!(j12, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j12, None),
};
let (j14, client_product_id) = match post_beta2_color_depth {
None => (j13, None),
Some(_) => match opt!(j13, le_u16) {
Some(_) => match opt!(j13, le_u16) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j13, None),
},
@ -904,7 +896,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j15, serial_number) = match client_product_id {
None => (j14, None),
Some(_) => match opt!(j14, le_u32) {
Some(_) => match opt!(j14, le_u32) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j14, None),
},
@ -913,7 +905,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j16, high_color_depth) = match serial_number {
None => (j15, None),
Some(_) => {
match opt!(j15, map_opt!(le_u16, num::FromPrimitive::from_u16)) {
match opt!(j15, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j15, None),
}
@ -923,7 +915,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j17, supported_color_depth) = match high_color_depth {
None => (j16, None),
Some(_) => {
match opt!(j16, map_opt!(le_u16, SupportedColorDepth::from_bits)) {
match opt!(j16, map_opt!(le_u16, SupportedColorDepth::from_bits)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j16, None),
}
@ -933,7 +925,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j18, early_capability_flags) = match supported_color_depth {
None => (j17, None),
Some(_) => {
match opt!(j17, map_opt!(le_u16, EarlyCapabilityFlags::from_bits)) {
match opt!(j17, map_opt!(le_u16, EarlyCapabilityFlags::from_bits)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j17, None),
}
@ -942,7 +934,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j19, client_dig_product_id) = match early_capability_flags {
None => (j18, None),
Some(_) => match opt!(j18, map_res!(take!(64), le_slice_to_string)) {
Some(_) => match opt(map_res(take(64usize), le_slice_to_string))(j18) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j18, None),
},
@ -951,7 +943,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j20, connection_hint) = match client_dig_product_id {
None => (j19, None),
Some(_) => {
match opt!(j19, map_opt!(le_u8, num::FromPrimitive::from_u8)) {
match opt(map_opt(le_u8, num::FromPrimitive::from_u8))(j19) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j19, None),
}
@ -960,7 +952,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j21, pad) = match connection_hint {
None => (j20, None),
Some(_) => match opt!(j20, take!(1)) {
Some(_) => match opt(take(1usize))(j20) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j20, None),
},
@ -969,7 +961,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j22, server_selected_protocol) = match pad {
None => (j21, None),
Some(_) => {
match opt!(j21, map_opt!(le_u32, ProtocolFlags::from_bits)) {
match opt!(j21, map_opt!(le_u32, ProtocolFlags::from_bits)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j21, None),
}
@ -978,7 +970,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j23, desktop_physical_width) = match server_selected_protocol {
None => (j22, None),
Some(_) => match opt!(j22, map_opt!(le_u32, millimeters_to_opt)) {
Some(_) => match opt!(j22, map_opt!(le_u32, millimeters_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j22, None),
},
@ -986,7 +978,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j24, desktop_physical_height) = match desktop_physical_width {
None => (j23, None),
Some(_) => match opt!(j23, map_opt!(le_u32, millimeters_to_opt)) {
Some(_) => match opt!(j23, map_opt!(le_u32, millimeters_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j23, None),
},
@ -995,7 +987,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j25, desktop_orientation) = match desktop_physical_height {
None => (j24, None),
Some(_) => {
match opt!(j24, map_opt!(le_u16, num::FromPrimitive::from_u16)) {
match opt!(j24, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j24, None),
}
@ -1004,7 +996,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j26, desktop_scale_factor) = match desktop_orientation {
None => (j25, None),
Some(_) => match opt!(j25, map_opt!(le_u32, desktop_scale_to_opt)) {
Some(_) => match opt!(j25, map_opt!(le_u32, desktop_scale_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j25, None),
},
@ -1012,7 +1004,7 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (_j27, device_scale_factor) = match desktop_scale_factor {
None => (j26, None),
Some(_) => match opt!(j26, map_opt!(le_u32, device_scale_to_opt)) {
Some(_) => match opt!(j26, map_opt!(le_u32, device_scale_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j26, None),
},

@ -161,7 +161,7 @@ named!(pub sip_take_line<&[u8], Option<String> >,
pub fn parse_headers(mut input: &[u8]) -> IResult<&[u8], HashMap<String, String>> {
let mut headers_map: HashMap<String, String> = HashMap::new();
loop {
match crlf(input) {
match crlf(input) as IResult<&[u8],_> {
Ok((_, _)) => {
break;
}

@ -206,19 +206,29 @@ pub struct DceRpcRecord<'a> {
pub data: &'a[u8],
}
fn parse_dcerpc_flags1(i:&[u8]) -> IResult<&[u8],(u8,u8,u8)> {
bits!(i,
tuple!(
take_bits!(6u8),
take_bits!(1u8), // last (1)
take_bits!(1u8))) // first (2)
}
fn parse_dcerpc_flags2(i:&[u8]) -> IResult<&[u8],(u32,u32,u32)> {
bits!(i,
tuple!(
take_bits!(3u32),
take_bits!(1u32), // endianess
take_bits!(28u32)))
}
named!(pub parse_dcerpc_record<DceRpcRecord>,
do_parse!(
version_major: le_u8
>> version_minor: le_u8
>> packet_type: le_u8
>> packet_flags: bits!(tuple!(
take_bits!(6u8),
take_bits!(1u8), // last (1)
take_bits!(1u8))) // first (2)
>> data_rep: bits!(tuple!(
take_bits!(3u32),
take_bits!(1u32), // endianess
take_bits!(28u32)))
>> packet_flags: parse_dcerpc_flags1
>> data_rep: parse_dcerpc_flags2
>> endian: value!(if data_rep.1 == 0 { Endianness::Big } else { Endianness::Little })
>> frag_len: u16!(endian)
>> _auth: u16!(endian)

@ -15,6 +15,7 @@
* 02110-1301, USA.
*/
use nom::IResult;
use nom::combinator::rest;
use nom::number::complete::{le_u8, le_u16, le_u32};
@ -57,6 +58,10 @@ pub struct NTLMSSPAuthRecord<'a> {
pub version: Option<NTLMSSPVersion>,
}
fn parse_ntlm_auth_nego_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u32)> {
bits!(i, tuple!(take_bits!(6u8),take_bits!(1u8),take_bits!(25u32)))
}
named!(pub parse_ntlm_auth_record<NTLMSSPAuthRecord>,
do_parse!(
_lm_blob_len: le_u16
@ -83,7 +88,7 @@ named!(pub parse_ntlm_auth_record<NTLMSSPAuthRecord>,
>> _ssnkey_blob_maxlen: le_u16
>> _ssnkey_blob_offset: le_u32
>> nego_flags: bits!(tuple!(take_bits!(6u8),take_bits!(1u8),take_bits!(25u32)))
>> nego_flags: parse_ntlm_auth_nego_flags
>> version: cond!(nego_flags.1==1, parse_ntlm_auth_version)
// subtrack 12 as idenfier (8) and type (4) are cut before we are called

@ -67,6 +67,20 @@ impl<'a> Smb2Record<'a> {
}
}
fn parse_smb2_request_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u8,u32,u8,u8,u8,u8)> {
bits!(i,
tuple!(
take_bits!(2u8), // reserved / unused
take_bits!(1u8), // replay op
take_bits!(1u8), // dfs op
take_bits!(24u32), // reserved / unused
take_bits!(1u8), // signing
take_bits!(1u8), // chained
take_bits!(1u8), // async
take_bits!(1u8) // response
))
}
named!(pub parse_smb2_request_record<Smb2Record>,
do_parse!(
_server_component: tag!(b"\xfeSMB")
@ -76,16 +90,7 @@ named!(pub parse_smb2_request_record<Smb2Record>,
>> _reserved: take!(2)
>> command: le_u16
>> _credits_requested: le_u16
>> flags: bits!(tuple!(
take_bits!(2u8), // reserved / unused
take_bits!(1u8), // replay op
take_bits!(1u8), // dfs op
take_bits!(24u32), // reserved / unused
take_bits!(1u8), // signing
take_bits!(1u8), // chained
take_bits!(1u8), // async
take_bits!(1u8) // response
))
>> flags: parse_smb2_request_flags
>> chain_offset: le_u32
>> message_id: le_u64
>> _process_id: le_u32
@ -507,16 +512,7 @@ named!(pub parse_smb2_response_record<Smb2Record>,
>> nt_status: le_u32
>> command: le_u16
>> _credit_granted: le_u16
>> flags: bits!(tuple!(
take_bits!(2u8), // reserved / unused
take_bits!(1u8), // replay op
take_bits!(1u8), // dfs op
take_bits!(24u32), // reserved / unused
take_bits!(1u8), // signing
take_bits!(1u8), // chained
take_bits!(1u8), // async
take_bits!(1u8) // response
))
>> flags: parse_smb2_request_flags
>> chain_offset: le_u32
>> message_id: le_u64
>> _process_id: cond!(flags.6==0, le_u32)

Loading…
Cancel
Save