rust/http2: convert parser to nom7 functions (HTTP2 core functions)

pull/6802/head
Pierre Chifflier 4 years ago committed by Victor Julien
parent 52d8d35453
commit f8647b0ffb

@ -24,7 +24,7 @@ use crate::applayer::{self, *};
use crate::core::*; use crate::core::*;
use crate::filecontainer::*; use crate::filecontainer::*;
use crate::filetracker::*; use crate::filetracker::*;
use nom; use nom7::Err;
use std; use std;
use std::ffi::CString; use std::ffi::CString;
use std::fmt; use std::fmt;
@ -647,7 +647,7 @@ impl HTTP2State {
//we could set an event on remaining data //we could set an event on remaining data
return HTTP2FrameTypeData::SETTINGS(set); return HTTP2FrameTypeData::SETTINGS(set);
} }
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
if complete { if complete {
self.set_event(HTTP2Event::InvalidFrameData); self.set_event(HTTP2Event::InvalidFrameData);
return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled { return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@ -738,7 +738,7 @@ impl HTTP2State {
self.process_headers(&hs.blocks, dir); self.process_headers(&hs.blocks, dir);
return HTTP2FrameTypeData::PUSHPROMISE(hs); return HTTP2FrameTypeData::PUSHPROMISE(hs);
} }
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
if complete { if complete {
self.set_event(HTTP2Event::InvalidFrameData); self.set_event(HTTP2Event::InvalidFrameData);
return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled { return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@ -772,7 +772,7 @@ impl HTTP2State {
self.process_headers(&hs.blocks, dir); self.process_headers(&hs.blocks, dir);
return HTTP2FrameTypeData::CONTINUATION(hs); return HTTP2FrameTypeData::CONTINUATION(hs);
} }
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
if complete { if complete {
self.set_event(HTTP2Event::InvalidFrameData); self.set_event(HTTP2Event::InvalidFrameData);
return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled { return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@ -807,7 +807,7 @@ impl HTTP2State {
} }
return HTTP2FrameTypeData::HEADERS(hs); return HTTP2FrameTypeData::HEADERS(hs);
} }
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
if complete { if complete {
self.set_event(HTTP2Event::InvalidFrameData); self.set_event(HTTP2Event::InvalidFrameData);
return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled { return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@ -929,7 +929,7 @@ impl HTTP2State {
} }
input = &rem[hlsafe..]; input = &rem[hlsafe..];
} }
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
//we may have consumed data from previous records //we may have consumed data from previous records
return AppLayerResult::incomplete( return AppLayerResult::incomplete(
(il - input.len()) as u32, (il - input.len()) as u32,
@ -1035,7 +1035,7 @@ pub unsafe extern "C" fn rs_http2_probing_parser_tc(
} }
return ALPROTO_HTTP2; return ALPROTO_HTTP2;
} }
Err(nom::Err::Incomplete(_)) => { Err(Err::Incomplete(_)) => {
return ALPROTO_UNKNOWN; return ALPROTO_UNKNOWN;
} }
Err(_) => { Err(_) => {

@ -15,9 +15,11 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use nom::error::ErrorKind; use nom7::bits::streaming::take as take_bits;
use nom::Err; use nom7::branch::alt;
use nom::IResult; use nom7::combinator::{complete, map_opt};
use nom7::error::{make_error, ErrorKind};
use nom7::{Err, IResult};
fn http2_huffman_table_len5(n: u32) -> Option<u8> { fn http2_huffman_table_len5(n: u32) -> Option<u8> {
match n { match n {
@ -35,9 +37,9 @@ fn http2_huffman_table_len5(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len5<(&[u8], usize), u8>, fn http2_decode_huffman_len5(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(5u32), http2_huffman_table_len5) ) complete(map_opt(take_bits(5u32), http2_huffman_table_len5))(input)
); }
fn http2_huffman_table_len6(n: u32) -> Option<u8> { fn http2_huffman_table_len6(n: u32) -> Option<u8> {
match n { match n {
@ -71,9 +73,9 @@ fn http2_huffman_table_len6(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len6<(&[u8], usize), u8>, fn http2_decode_huffman_len6(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(6u32), http2_huffman_table_len6)) complete(map_opt(take_bits(6u32), http2_huffman_table_len6))(input)
); }
fn http2_huffman_table_len7(n: u32) -> Option<u8> { fn http2_huffman_table_len7(n: u32) -> Option<u8> {
match n { match n {
@ -113,9 +115,9 @@ fn http2_huffman_table_len7(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len7<(&[u8], usize), u8>, fn http2_decode_huffman_len7(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(7u32), http2_huffman_table_len7)) complete(map_opt(take_bits(7u32), http2_huffman_table_len7))(input)
); }
fn http2_huffman_table_len8(n: u32) -> Option<u8> { fn http2_huffman_table_len8(n: u32) -> Option<u8> {
match n { match n {
@ -129,9 +131,9 @@ fn http2_huffman_table_len8(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len8<(&[u8], usize), u8>, fn http2_decode_huffman_len8(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(8u32), http2_huffman_table_len8)) complete(map_opt(take_bits(8u32), http2_huffman_table_len8))(input)
); }
fn http2_huffman_table_len10(n: u32) -> Option<u8> { fn http2_huffman_table_len10(n: u32) -> Option<u8> {
match n { match n {
@ -144,9 +146,9 @@ fn http2_huffman_table_len10(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len10<(&[u8], usize), u8>, fn http2_decode_huffman_len10(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(10u32), http2_huffman_table_len10)) complete(map_opt(take_bits(10u32), http2_huffman_table_len10))(input)
); }
fn http2_huffman_table_len11(n: u32) -> Option<u8> { fn http2_huffman_table_len11(n: u32) -> Option<u8> {
match n { match n {
@ -157,9 +159,9 @@ fn http2_huffman_table_len11(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len11<(&[u8], usize), u8>, fn http2_decode_huffman_len11(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(11u32), http2_huffman_table_len11)) complete(map_opt(take_bits(11u32), http2_huffman_table_len11))(input)
); }
fn http2_huffman_table_len12(n: u32) -> Option<u8> { fn http2_huffman_table_len12(n: u32) -> Option<u8> {
match n { match n {
@ -169,9 +171,9 @@ fn http2_huffman_table_len12(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len12<(&[u8], usize), u8>, fn http2_decode_huffman_len12(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(12u32), http2_huffman_table_len12)) complete(map_opt(take_bits(12u32), http2_huffman_table_len12))(input)
); }
fn http2_huffman_table_len13(n: u32) -> Option<u8> { fn http2_huffman_table_len13(n: u32) -> Option<u8> {
match n { match n {
@ -185,9 +187,9 @@ fn http2_huffman_table_len13(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len13<(&[u8], usize), u8>, fn http2_decode_huffman_len13(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(13u32), http2_huffman_table_len13)) complete(map_opt(take_bits(13u32), http2_huffman_table_len13))(input)
); }
fn http2_huffman_table_len14(n: u32) -> Option<u8> { fn http2_huffman_table_len14(n: u32) -> Option<u8> {
match n { match n {
@ -197,9 +199,9 @@ fn http2_huffman_table_len14(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len14<(&[u8], usize), u8>, fn http2_decode_huffman_len14(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(14u32), http2_huffman_table_len14)) complete(map_opt(take_bits(14u32), http2_huffman_table_len14))(input)
); }
fn http2_huffman_table_len15(n: u32) -> Option<u8> { fn http2_huffman_table_len15(n: u32) -> Option<u8> {
match n { match n {
@ -210,9 +212,9 @@ fn http2_huffman_table_len15(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len15<(&[u8], usize), u8>, fn http2_decode_huffman_len15(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(15u32), http2_huffman_table_len15)) complete(map_opt(take_bits(15u32), http2_huffman_table_len15))(input)
); }
fn http2_huffman_table_len19(n: u32) -> Option<u8> { fn http2_huffman_table_len19(n: u32) -> Option<u8> {
match n { match n {
@ -223,9 +225,9 @@ fn http2_huffman_table_len19(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len19<(&[u8], usize), u8>, fn http2_decode_huffman_len19(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(19u32), http2_huffman_table_len19)) complete(map_opt(take_bits(19u32), http2_huffman_table_len19))(input)
); }
fn http2_huffman_table_len20(n: u32) -> Option<u8> { fn http2_huffman_table_len20(n: u32) -> Option<u8> {
match n { match n {
@ -241,9 +243,9 @@ fn http2_huffman_table_len20(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len20<(&[u8], usize), u8>, fn http2_decode_huffman_len20(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(20u32), http2_huffman_table_len20)) complete(map_opt(take_bits(20u32), http2_huffman_table_len20))(input)
); }
fn http2_huffman_table_len21(n: u32) -> Option<u8> { fn http2_huffman_table_len21(n: u32) -> Option<u8> {
match n { match n {
@ -264,9 +266,9 @@ fn http2_huffman_table_len21(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len21<(&[u8], usize), u8>, fn http2_decode_huffman_len21(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(21u32), http2_huffman_table_len21)) complete(map_opt(take_bits(21u32), http2_huffman_table_len21))(input)
); }
fn http2_huffman_table_len22(n: u32) -> Option<u8> { fn http2_huffman_table_len22(n: u32) -> Option<u8> {
match n { match n {
@ -300,9 +302,9 @@ fn http2_huffman_table_len22(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len22<(&[u8], usize), u8>, fn http2_decode_huffman_len22(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(22u32), http2_huffman_table_len22)) complete(map_opt(take_bits(22u32), http2_huffman_table_len22))(input)
); }
fn http2_huffman_table_len23(n: u32) -> Option<u8> { fn http2_huffman_table_len23(n: u32) -> Option<u8> {
match n { match n {
@ -339,9 +341,9 @@ fn http2_huffman_table_len23(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len23<(&[u8], usize), u8>, fn http2_decode_huffman_len23(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(23u32), http2_huffman_table_len23)) complete(map_opt(take_bits(23u32), http2_huffman_table_len23))(input)
); }
fn http2_huffman_table_len24(n: u32) -> Option<u8> { fn http2_huffman_table_len24(n: u32) -> Option<u8> {
match n { match n {
@ -361,9 +363,9 @@ fn http2_huffman_table_len24(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len24<(&[u8], usize), u8>, fn http2_decode_huffman_len24(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(24u32), http2_huffman_table_len24)) complete(map_opt(take_bits(24u32), http2_huffman_table_len24))(input)
); }
fn http2_huffman_table_len25(n: u32) -> Option<u8> { fn http2_huffman_table_len25(n: u32) -> Option<u8> {
match n { match n {
@ -375,9 +377,9 @@ fn http2_huffman_table_len25(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len25<(&[u8], usize), u8>, fn http2_decode_huffman_len25(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(25u32), http2_huffman_table_len25)) complete(map_opt(take_bits(25u32), http2_huffman_table_len25))(input)
); }
fn http2_huffman_table_len26(n: u32) -> Option<u8> { fn http2_huffman_table_len26(n: u32) -> Option<u8> {
match n { match n {
@ -400,9 +402,9 @@ fn http2_huffman_table_len26(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len26<(&[u8], usize), u8>, fn http2_decode_huffman_len26((i, bit_offset): (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(26u32), http2_huffman_table_len26)) complete(map_opt(take_bits(26u32), http2_huffman_table_len26))((i, bit_offset))
); }
fn http2_huffman_table_len27(n: u32) -> Option<u8> { fn http2_huffman_table_len27(n: u32) -> Option<u8> {
match n { match n {
@ -429,9 +431,9 @@ fn http2_huffman_table_len27(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len27<(&[u8], usize), u8>, fn http2_decode_huffman_len27(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(27u32), http2_huffman_table_len27)) complete(map_opt(take_bits(27u32), http2_huffman_table_len27))(input)
); }
fn http2_huffman_table_len28(n: u32) -> Option<u8> { fn http2_huffman_table_len28(n: u32) -> Option<u8> {
match n { match n {
@ -468,9 +470,9 @@ fn http2_huffman_table_len28(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len28<(&[u8], usize), u8>, fn http2_decode_huffman_len28(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(28u32), http2_huffman_table_len28)) complete(map_opt(take_bits(28u32), http2_huffman_table_len28))(input)
); }
fn http2_huffman_table_len30(n: u32) -> Option<u8> { fn http2_huffman_table_len30(n: u32) -> Option<u8> {
match n { match n {
@ -482,23 +484,44 @@ fn http2_huffman_table_len30(n: u32) -> Option<u8> {
} }
} }
named!(http2_decode_huffman_len30<(&[u8], usize), u8>, fn http2_decode_huffman_len30(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
complete!( map_opt!(take_bits!(30u32), http2_huffman_table_len30)) complete(map_opt(take_bits(30u32), http2_huffman_table_len30))(input)
); }
//hack to end many0 even if some bits are remaining //hack to end many0 even if some bits are remaining
fn http2_decode_huffman_end(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> { fn http2_decode_huffman_end(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
return Err(Err::Error((input, ErrorKind::Eof))); return Err(Err::Error(make_error(input, ErrorKind::Eof)));
} }
//we could profile and optimize performance here //we could profile and optimize performance here
named!(pub http2_decode_huffman<(&[u8], usize), u8>, pub fn http2_decode_huffman(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
alt!(http2_decode_huffman_len5 | http2_decode_huffman_len6 | http2_decode_huffman_len7 | // trait nom::branch::Alt is implemented for lists up to size 20,
http2_decode_huffman_len8 | http2_decode_huffman_len10 | http2_decode_huffman_len11 | // so use nested `alt` as a workaround (see nom documentation for `alt`)
http2_decode_huffman_len12 | http2_decode_huffman_len13 | http2_decode_huffman_len14 | alt((
http2_decode_huffman_len15 | http2_decode_huffman_len19 | http2_decode_huffman_len20 | http2_decode_huffman_len5,
http2_decode_huffman_len21 | http2_decode_huffman_len22 | http2_decode_huffman_len23 | http2_decode_huffman_len6,
http2_decode_huffman_len24 | http2_decode_huffman_len25 | http2_decode_huffman_len26 | http2_decode_huffman_len7,
http2_decode_huffman_len27 | http2_decode_huffman_len28 | http2_decode_huffman_len30 | http2_decode_huffman_len8,
http2_decode_huffman_end) http2_decode_huffman_len10,
); http2_decode_huffman_len11,
http2_decode_huffman_len12,
http2_decode_huffman_len13,
http2_decode_huffman_len14,
http2_decode_huffman_len15,
http2_decode_huffman_len19,
http2_decode_huffman_len20,
http2_decode_huffman_len21,
http2_decode_huffman_len21,
http2_decode_huffman_len22,
http2_decode_huffman_len23,
http2_decode_huffman_len24,
http2_decode_huffman_len25,
http2_decode_huffman_len26,
http2_decode_huffman_len27,
alt((
http2_decode_huffman_len28,
http2_decode_huffman_len30,
http2_decode_huffman_end,
)),
))(input)
}

@ -17,12 +17,16 @@
use super::huffman; use super::huffman;
use crate::http2::http2::{HTTP2DynTable, HTTP2_MAX_TABLESIZE}; use crate::http2::http2::{HTTP2DynTable, HTTP2_MAX_TABLESIZE};
use nom::character::complete::digit1; use nom7::bits::{bits, streaming::take as take_bits};
use nom::combinator::rest; use nom7::branch::alt;
use nom::error::ErrorKind; use nom7::bytes::streaming::{is_a, is_not, tag, take, take_while};
use nom::number::streaming::{be_u16, be_u32, be_u8}; use nom7::character::complete::digit1;
use nom::Err; use nom7::combinator::{complete, cond, map_opt, opt, rest, verify};
use nom::IResult; use nom7::error::{make_error, Error, ErrorKind};
use nom7::multi::many0;
use nom7::number::streaming::{be_u16, be_u24, be_u32, be_u8};
use nom7::sequence::tuple;
use nom7::{Err, IResult};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
@ -79,18 +83,23 @@ pub struct HTTP2FrameHeader {
pub stream_id: u32, pub stream_id: u32,
} }
named!(pub http2_parse_frame_header<HTTP2FrameHeader>, pub fn http2_parse_frame_header(i: &[u8]) -> IResult<&[u8], HTTP2FrameHeader> {
do_parse!( let (i, length) = be_u24(i)?;
length: bits!( take_bits!(24u32) ) >> let (i, ftype) = be_u8(i)?;
ftype: be_u8 >> let (i, flags) = be_u8(i)?;
flags: be_u8 >> let (i, b) = be_u32(i)?;
stream_id: bits!( tuple!( take_bits!(1u8), let (reserved, stream_id) = ((b >> 31) as u8, b & 0x7fff_ffff);
take_bits!(31u32) ) ) >> Ok((
(HTTP2FrameHeader{length, ftype, flags, i,
reserved:stream_id.0, HTTP2FrameHeader {
stream_id:stream_id.1}) length,
) ftype,
); flags,
reserved,
stream_id,
},
))
}
#[repr(u32)] #[repr(u32)]
#[derive(Clone, Copy, PartialEq, FromPrimitive, Debug)] #[derive(Clone, Copy, PartialEq, FromPrimitive, Debug)]
@ -147,24 +156,20 @@ pub struct HTTP2FrameGoAway {
pub errorcode: u32, //HTTP2ErrorCode pub errorcode: u32, //HTTP2ErrorCode
} }
named!(pub http2_parse_frame_goaway<HTTP2FrameGoAway>, pub fn http2_parse_frame_goaway(i: &[u8]) -> IResult<&[u8], HTTP2FrameGoAway> {
do_parse!( let (i, errorcode) = be_u32(i)?;
errorcode: be_u32 >> Ok((i, HTTP2FrameGoAway { errorcode }))
(HTTP2FrameGoAway{errorcode}) }
)
);
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HTTP2FrameRstStream { pub struct HTTP2FrameRstStream {
pub errorcode: u32, ////HTTP2ErrorCode pub errorcode: u32, ////HTTP2ErrorCode
} }
named!(pub http2_parse_frame_rststream<HTTP2FrameRstStream>, pub fn http2_parse_frame_rststream(i: &[u8]) -> IResult<&[u8], HTTP2FrameRstStream> {
do_parse!( let (i, errorcode) = be_u32(i)?;
errorcode: be_u32 >> Ok((i, HTTP2FrameRstStream { errorcode }))
(HTTP2FrameRstStream{errorcode}) }
)
);
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HTTP2FramePriority { pub struct HTTP2FramePriority {
@ -173,14 +178,19 @@ pub struct HTTP2FramePriority {
pub weight: u8, pub weight: u8,
} }
named!(pub http2_parse_frame_priority<HTTP2FramePriority>, pub fn http2_parse_frame_priority(i: &[u8]) -> IResult<&[u8], HTTP2FramePriority> {
do_parse!( let (i, b) = be_u32(i)?;
sid: bits!( tuple!( take_bits!(1u8), let (exclusive, dependency) = ((b >> 31) as u8, b & 0x7fff_ffff);
take_bits!(31u32) ) ) >> let (i, weight) = be_u8(i)?;
weight: be_u8 >> Ok((
(HTTP2FramePriority{exclusive:sid.0, dependency:sid.1, weight}) i,
) HTTP2FramePriority {
); exclusive,
dependency,
weight,
},
))
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HTTP2FrameWindowUpdate { pub struct HTTP2FrameWindowUpdate {
@ -188,13 +198,11 @@ pub struct HTTP2FrameWindowUpdate {
pub sizeinc: u32, pub sizeinc: u32,
} }
named!(pub http2_parse_frame_windowupdate<HTTP2FrameWindowUpdate>, pub fn http2_parse_frame_windowupdate(i: &[u8]) -> IResult<&[u8], HTTP2FrameWindowUpdate> {
do_parse!( let (i, b) = be_u32(i)?;
sizeinc: bits!( tuple!( take_bits!(1u8), let (reserved, sizeinc) = ((b >> 31) as u8, b & 0x7fff_ffff);
take_bits!(31u32) ) ) >> Ok((i, HTTP2FrameWindowUpdate { reserved, sizeinc }))
(HTTP2FrameWindowUpdate{reserved:sizeinc.0, sizeinc:sizeinc.1}) }
)
);
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HTTP2FrameHeadersPriority { pub struct HTTP2FrameHeadersPriority {
@ -203,14 +211,19 @@ pub struct HTTP2FrameHeadersPriority {
pub weight: u8, pub weight: u8,
} }
named!(pub http2_parse_headers_priority<HTTP2FrameHeadersPriority>, pub fn http2_parse_headers_priority(i: &[u8]) -> IResult<&[u8], HTTP2FrameHeadersPriority> {
do_parse!( let (i, b) = be_u32(i)?;
sid: bits!( tuple!( take_bits!(1u8), let (exclusive, dependency) = ((b >> 31) as u8, b & 0x7fff_ffff);
take_bits!(31u32) ) ) >> let (i, weight) = be_u8(i)?;
weight: be_u8 >> Ok((
(HTTP2FrameHeadersPriority{exclusive:sid.0, dependency:sid.1, weight}) i,
) HTTP2FrameHeadersPriority {
); exclusive,
dependency,
weight,
},
))
}
pub const HTTP2_STATIC_HEADERS_NUMBER: usize = 61; pub const HTTP2_STATIC_HEADERS_NUMBER: usize = 61;
@ -344,39 +357,38 @@ fn http2_parse_headers_block_indexed<'a>(
input: &'a [u8], dyn_headers: &HTTP2DynTable, input: &'a [u8], dyn_headers: &HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> { ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits!( bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
input, verify(take_bits(1u8), |&x| x == 1),
complete!(tuple!( take_bits(7u8),
verify!(take_bits!(1u8), |&x| x == 1), ))))(input)
take_bits!(7u8)
))
)
} }
let (i2, indexed) = parser(input)?; let (i2, indexed) = parser(input)?;
let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0x7F)?; let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0x7F)?;
if indexreal == 0 && indexed.1 == 0x7F { if indexreal == 0 && indexed.1 == 0x7F {
return Err(Err::Error((i3, ErrorKind::LengthValue))); return Err(Err::Error(make_error(i3, ErrorKind::LengthValue)));
} }
match http2_frame_header_static(indexreal, dyn_headers) { match http2_frame_header_static(indexreal, dyn_headers) {
Some(h) => Ok((i3, h)), Some(h) => Ok((i3, h)),
_ => Err(Err::Error((i3, ErrorKind::MapOpt))), _ => Err(Err::Error(make_error(i3, ErrorKind::MapOpt))),
} }
} }
fn http2_parse_headers_block_string(input: &[u8]) -> IResult<&[u8], Vec<u8>> { fn http2_parse_headers_block_string(input: &[u8]) -> IResult<&[u8], Vec<u8>> {
fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits!(input, tuple!(take_bits!(1u8), take_bits!(7u8))) let (i, b) = be_u8(input)?;
Ok((i, (b >> 7, b & 0x7f)))
} }
let (i1, huffslen) = parser(input)?; let (i1, huffslen) = parser(input)?;
let (i2, stringlen) = http2_parse_var_uint(i1, huffslen.1 as u64, 0x7F)?; let (i2, stringlen) = http2_parse_var_uint(i1, huffslen.1 as u64, 0x7F)?;
if stringlen == 0 && huffslen.1 == 0x7F { if stringlen == 0 && huffslen.1 == 0x7F {
return Err(Err::Error((i2, ErrorKind::LengthValue))); return Err(Err::Error(make_error(i2, ErrorKind::LengthValue)));
} }
let (i3, data) = take!(i2, stringlen as usize)?; let (i3, data) = take(stringlen as usize)(i2)?;
if huffslen.0 == 0 { if huffslen.0 == 0 {
return Ok((i3, data.to_vec())); return Ok((i3, data.to_vec()));
} else { } else {
let (_, val) = bits!(data, many0!(huffman::http2_decode_huffman))?; let (_, val) =
bits::<_, _, Error<(&[u8], usize)>, _, _>(many0(huffman::http2_decode_huffman))(data)?;
return Ok((i3, val)); return Ok((i3, val));
} }
} }
@ -419,18 +431,15 @@ fn http2_parse_headers_block_literal_incindex<'a>(
input: &'a [u8], dyn_headers: &mut HTTP2DynTable, input: &'a [u8], dyn_headers: &mut HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> { ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits!( bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
input, verify(take_bits(2u8), |&x| x == 1),
complete!(tuple!( take_bits(6u8),
verify!(take_bits!(2u8), |&x| x == 1), ))))(input)
take_bits!(6u8)
))
)
} }
let (i2, indexed) = parser(input)?; let (i2, indexed) = parser(input)?;
let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0x3F)?; let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0x3F)?;
if indexreal == 0 && indexed.1 == 0x3F { if indexreal == 0 && indexed.1 == 0x3F {
return Err(Err::Error((i3, ErrorKind::LengthValue))); return Err(Err::Error(make_error(i3, ErrorKind::LengthValue)));
} }
let r = http2_parse_headers_block_literal_common(i3, indexreal, dyn_headers); let r = http2_parse_headers_block_literal_common(i3, indexreal, dyn_headers);
match r { match r {
@ -476,18 +485,15 @@ fn http2_parse_headers_block_literal_noindex<'a>(
input: &'a [u8], dyn_headers: &HTTP2DynTable, input: &'a [u8], dyn_headers: &HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> { ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits!( bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
input, verify(take_bits(4u8), |&x| x == 0),
complete!(tuple!( take_bits(4u8),
verify!(take_bits!(4u8), |&x| x == 0), ))))(input)
take_bits!(4u8)
))
)
} }
let (i2, indexed) = parser(input)?; let (i2, indexed) = parser(input)?;
let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0xF)?; let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0xF)?;
if indexreal == 0 && indexed.1 == 0xF { if indexreal == 0 && indexed.1 == 0xF {
return Err(Err::Error((i3, ErrorKind::LengthValue))); return Err(Err::Error(make_error(i3, ErrorKind::LengthValue)));
} }
let r = http2_parse_headers_block_literal_common(i3, indexreal, dyn_headers); let r = http2_parse_headers_block_literal_common(i3, indexreal, dyn_headers);
return r; return r;
@ -497,18 +503,15 @@ fn http2_parse_headers_block_literal_neverindex<'a>(
input: &'a [u8], dyn_headers: &HTTP2DynTable, input: &'a [u8], dyn_headers: &HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> { ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits!( bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
input, verify(take_bits(4u8), |&x| x == 1),
complete!(tuple!( take_bits(4u8),
verify!(take_bits!(4u8), |&x| x == 1), ))))(input)
take_bits!(4u8)
))
)
} }
let (i2, indexed) = parser(input)?; let (i2, indexed) = parser(input)?;
let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0xF)?; let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 0xF)?;
if indexreal == 0 && indexed.1 == 0xF { if indexreal == 0 && indexed.1 == 0xF {
return Err(Err::Error((i3, ErrorKind::LengthValue))); return Err(Err::Error(make_error(i3, ErrorKind::LengthValue)));
} }
let r = http2_parse_headers_block_literal_common(i3, indexreal, dyn_headers); let r = http2_parse_headers_block_literal_common(i3, indexreal, dyn_headers);
return r; return r;
@ -518,7 +521,7 @@ fn http2_parse_var_uint(input: &[u8], value: u64, max: u64) -> IResult<&[u8], u6
if value < max { if value < max {
return Ok((input, value)); return Ok((input, value));
} }
let (i2, varia) = take_while!(input, |ch| (ch & 0x80) != 0)?; let (i2, varia) = take_while(|ch| (ch & 0x80) != 0)(input)?;
let (i3, finalv) = be_u8(i2)?; let (i3, finalv) = be_u8(i2)?;
if varia.len() > 9 || (varia.len() == 9 && finalv > 1) { if varia.len() > 9 || (varia.len() == 9 && finalv > 1) {
// this will overflow u64 // this will overflow u64
@ -540,13 +543,10 @@ fn http2_parse_headers_block_dynamic_size<'a>(
input: &'a [u8], dyn_headers: &mut HTTP2DynTable, input: &'a [u8], dyn_headers: &mut HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> { ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits!( bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
input, verify(take_bits(3u8), |&x| x == 1),
complete!(tuple!( take_bits(5u8),
verify!(take_bits!(3u8), |&x| x == 1), ))))(input)
take_bits!(5u8)
))
)
} }
let (i2, maxsize) = parser(input)?; let (i2, maxsize) = parser(input)?;
let (i3, maxsize2) = http2_parse_var_uint(i2, maxsize.1 as u64, 0x1F)?; let (i3, maxsize2) = http2_parse_var_uint(i2, maxsize.1 as u64, 0x1F)?;
@ -616,12 +616,11 @@ const HTTP2_FLAG_HEADER_PRIORITY: u8 = 0x20;
pub fn http2_parse_frame_headers<'a>( pub fn http2_parse_frame_headers<'a>(
input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable, input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameHeaders> { ) -> IResult<&'a [u8], HTTP2FrameHeaders> {
let (i2, padlength) = cond!(input, flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)?; let (i2, padlength) = cond(flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)(input)?;
let (mut i3, priority) = cond!( let (mut i3, priority) = cond(
i2,
flags & HTTP2_FLAG_HEADER_PRIORITY != 0, flags & HTTP2_FLAG_HEADER_PRIORITY != 0,
http2_parse_headers_priority http2_parse_headers_priority,
)?; )(i2)?;
let mut blocks = Vec::new(); let mut blocks = Vec::new();
while i3.len() > 0 { while i3.len() > 0 {
match http2_parse_headers_block(i3, dyn_headers) { match http2_parse_headers_block(i3, dyn_headers) {
@ -630,7 +629,7 @@ pub fn http2_parse_frame_headers<'a>(
debug_validate_bug_on!(i3.len() == rem.len()); debug_validate_bug_on!(i3.len() == rem.len());
if i3.len() == rem.len() { if i3.len() == rem.len() {
//infinite loop //infinite loop
return Err(Err::Error((input, ErrorKind::Eof))); return Err(Err::Error(make_error(input, ErrorKind::Eof)));
} }
i3 = rem; i3 = rem;
} }
@ -660,8 +659,9 @@ pub struct HTTP2FramePushPromise {
pub fn http2_parse_frame_push_promise<'a>( pub fn http2_parse_frame_push_promise<'a>(
input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable, input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FramePushPromise> { ) -> IResult<&'a [u8], HTTP2FramePushPromise> {
let (i2, padlength) = cond!(input, flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)?; let (i2, padlength) = cond(flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)(input)?;
let (mut i3, stream_id) = bits!(i2, tuple!(take_bits!(1u8), take_bits!(31u32)))?; let (mut i3, stream_id) =
bits::<_, _, Error<(&[u8], usize)>, _, _>(tuple((take_bits(1u8), take_bits(31u32))))(i2)?;
let mut blocks = Vec::new(); let mut blocks = Vec::new();
while i3.len() > 0 { while i3.len() > 0 {
match http2_parse_headers_block(i3, dyn_headers) { match http2_parse_headers_block(i3, dyn_headers) {
@ -670,7 +670,7 @@ pub fn http2_parse_frame_push_promise<'a>(
debug_validate_bug_on!(i3.len() == rem.len()); debug_validate_bug_on!(i3.len() == rem.len());
if i3.len() == rem.len() { if i3.len() == rem.len() {
//infinite loop //infinite loop
return Err(Err::Error((input, ErrorKind::Eof))); return Err(Err::Error(make_error(input, ErrorKind::Eof)));
} }
i3 = rem; i3 = rem;
} }
@ -707,7 +707,7 @@ pub fn http2_parse_frame_continuation<'a>(
debug_validate_bug_on!(i3.len() == rem.len()); debug_validate_bug_on!(i3.len() == rem.len());
if i3.len() == rem.len() { if i3.len() == rem.len() {
//infinite loop //infinite loop
return Err(Err::Error((input, ErrorKind::Eof))); return Err(Err::Error(make_error(input, ErrorKind::Eof)));
} }
i3 = rem; i3 = rem;
} }
@ -774,69 +774,86 @@ pub struct DetectHTTP2settingsSigCtx {
pub value: Option<DetectU32Data>, //optional value pub value: Option<DetectU32Data>, //optional value
} }
named!(detect_parse_u32_start_equal<&str,DetectU32Data>, fn detect_parse_u32_start_equal(i: &str) -> IResult<&str, DetectU32Data> {
do_parse!( let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, _) = opt(tag("="))(i)?;
opt! (tag!("=") ) >> let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >> Ok((
(DetectU32Data{value, valrange:0, mode:DetectUintMode::DetectUintModeEqual}) i,
) DetectU32Data {
); value,
valrange: 0,
named!(detect_parse_u32_start_interval<&str,DetectU32Data>, mode: DetectUintMode::DetectUintModeEqual,
do_parse!( },
opt!( is_a!( " " ) ) >> ))
value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >> }
opt!( is_a!( " " ) ) >>
tag!("-") >> fn detect_parse_u32_start_interval(i: &str) -> IResult<&str, DetectU32Data> {
opt!( is_a!( " " ) ) >> let (i, _) = opt(is_a(" "))(i)?;
valrange : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >> let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
(DetectU32Data{value, valrange, mode:DetectUintMode::DetectUintModeRange}) let (i, _) = opt(is_a(" "))(i)?;
) let (i, _) = tag("-")(i)?;
); let (i, _) = opt(is_a(" "))(i)?;
let (i, valrange) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
named!(detect_parse_u32_start_lesser<&str,DetectU32Data>, Ok((
do_parse!( i,
opt!( is_a!( " " ) ) >> DetectU32Data {
tag!("<") >> value,
opt!( is_a!( " " ) ) >> valrange,
value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >> mode: DetectUintMode::DetectUintModeRange,
(DetectU32Data{value, valrange:0, mode:DetectUintMode::DetectUintModeLt}) },
) ))
); }
named!(detect_parse_u32_start_greater<&str,DetectU32Data>, fn detect_parse_u32_start_lesser(i: &str) -> IResult<&str, DetectU32Data> {
do_parse!( let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, _) = tag("<")(i)?;
tag!(">") >> let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >> Ok((
(DetectU32Data{value, valrange:0, mode:DetectUintMode::DetectUintModeGt}) i,
) DetectU32Data {
); value,
valrange: 0,
named!(detect_parse_u32<&str,DetectU32Data>, mode: DetectUintMode::DetectUintModeLt,
do_parse!( },
u32 : alt! ( ))
detect_parse_u32_start_lesser | }
detect_parse_u32_start_greater |
complete!( detect_parse_u32_start_interval ) | fn detect_parse_u32_start_greater(i: &str) -> IResult<&str, DetectU32Data> {
detect_parse_u32_start_equal let (i, _) = opt(is_a(" "))(i)?;
) >> let (i, _) = tag(">")(i)?;
(u32) let (i, _) = opt(is_a(" "))(i)?;
) let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
); Ok((
i,
named!(pub http2_parse_settingsctx<&str,DetectHTTP2settingsSigCtx>, DetectU32Data {
do_parse!( value,
opt!( is_a!( " " ) ) >> valrange: 0,
id: map_opt!( alt! ( complete!( is_not!( " <>=" ) ) | rest ), mode: DetectUintMode::DetectUintModeGt,
|s: &str| HTTP2SettingsId::from_str(s).ok() ) >> },
value: opt!( complete!( detect_parse_u32 ) ) >> ))
(DetectHTTP2settingsSigCtx{id, value}) }
)
); fn detect_parse_u32(i: &str) -> IResult<&str, DetectU32Data> {
let (i, u32) = alt((
detect_parse_u32_start_lesser,
detect_parse_u32_start_greater,
complete(detect_parse_u32_start_interval),
detect_parse_u32_start_equal,
))(i)?;
Ok((i, u32))
}
pub fn http2_parse_settingsctx(i: &str) -> IResult<&str, DetectHTTP2settingsSigCtx> {
let (i, _) = opt(is_a(" "))(i)?;
let (i, id) = map_opt(alt((complete(is_not(" <>=")), rest)), |s: &str| {
HTTP2SettingsId::from_str(s).ok()
})(i)?;
let (i, value) = opt(complete(detect_parse_u32))(i)?;
Ok((i, DetectHTTP2settingsSigCtx { id, value }))
}
pub struct DetectU64Data { pub struct DetectU64Data {
pub value: u64, pub value: u64,
@ -844,59 +861,77 @@ pub struct DetectU64Data {
pub mode: DetectUintMode, pub mode: DetectUintMode,
} }
named!(detect_parse_u64_start_equal<&str,DetectU64Data>, fn detect_parse_u64_start_equal(i: &str) -> IResult<&str, DetectU64Data> {
do_parse!( let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, _) = opt(tag("="))(i)?;
opt! (tag!("=") ) >> let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, value) = map_opt(digit1, |s: &str| s.parse::<u64>().ok())(i)?;
value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >> Ok((
(DetectU64Data{value, valrange:0, mode:DetectUintMode::DetectUintModeEqual}) i,
) DetectU64Data {
); value,
valrange: 0,
named!(detect_parse_u64_start_interval<&str,DetectU64Data>, mode: DetectUintMode::DetectUintModeEqual,
do_parse!( },
opt!( is_a!( " " ) ) >> ))
value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >> }
opt!( is_a!( " " ) ) >>
tag!("-") >> fn detect_parse_u64_start_interval(i: &str) -> IResult<&str, DetectU64Data> {
opt!( is_a!( " " ) ) >> let (i, _) = opt(is_a(" "))(i)?;
valrange : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >> let (i, value) = map_opt(digit1, |s: &str| s.parse::<u64>().ok())(i)?;
(DetectU64Data{value, valrange, mode:DetectUintMode::DetectUintModeRange}) let (i, _) = opt(is_a(" "))(i)?;
) let (i, _) = tag("-")(i)?;
); let (i, _) = opt(is_a(" "))(i)?;
let (i, valrange) = map_opt(digit1, |s: &str| s.parse::<u64>().ok())(i)?;
named!(detect_parse_u64_start_lesser<&str,DetectU64Data>, Ok((
do_parse!( i,
opt!( is_a!( " " ) ) >> DetectU64Data {
tag!("<") >> value,
opt!( is_a!( " " ) ) >> valrange,
value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >> mode: DetectUintMode::DetectUintModeRange,
(DetectU64Data{value, valrange:0, mode:DetectUintMode::DetectUintModeLt}) },
) ))
); }
named!(detect_parse_u64_start_greater<&str,DetectU64Data>, fn detect_parse_u64_start_lesser(i: &str) -> IResult<&str, DetectU64Data> {
do_parse!( let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, _) = tag("<")(i)?;
tag!(">") >> let (i, _) = opt(is_a(" "))(i)?;
opt!( is_a!( " " ) ) >> let (i, value) = map_opt(digit1, |s: &str| s.parse::<u64>().ok())(i)?;
value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >> Ok((
(DetectU64Data{value, valrange:0, mode:DetectUintMode::DetectUintModeGt}) i,
) DetectU64Data {
); value,
valrange: 0,
named!(pub detect_parse_u64<&str,DetectU64Data>, mode: DetectUintMode::DetectUintModeLt,
do_parse!( },
u64 : alt! ( ))
detect_parse_u64_start_lesser | }
detect_parse_u64_start_greater |
complete!( detect_parse_u64_start_interval ) | fn detect_parse_u64_start_greater(i: &str) -> IResult<&str, DetectU64Data> {
detect_parse_u64_start_equal let (i, _) = opt(is_a(" "))(i)?;
) >> let (i, _) = tag(">")(i)?;
(u64) let (i, _) = opt(is_a(" "))(i)?;
) let (i, value) = map_opt(digit1, |s: &str| s.parse::<u64>().ok())(i)?;
); Ok((
i,
DetectU64Data {
value,
valrange: 0,
mode: DetectUintMode::DetectUintModeGt,
},
))
}
pub fn detect_parse_u64(i: &str) -> IResult<&str, DetectU64Data> {
let (i, u64) = alt((
detect_parse_u64_start_lesser,
detect_parse_u64_start_greater,
complete(detect_parse_u64_start_interval),
detect_parse_u64_start_equal,
))(i)?;
Ok((i, u64))
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HTTP2FrameSettings { pub struct HTTP2FrameSettings {
@ -904,18 +939,15 @@ pub struct HTTP2FrameSettings {
pub value: u32, pub value: u32,
} }
named!( fn http2_parse_frame_setting(i: &[u8]) -> IResult<&[u8], HTTP2FrameSettings> {
http2_parse_frame_setting<HTTP2FrameSettings>, let (i, id) = map_opt(be_u16, num::FromPrimitive::from_u16)(i)?;
do_parse!( let (i, value) = be_u32(i)?;
id: map_opt!(be_u16, num::FromPrimitive::from_u16) Ok((i, HTTP2FrameSettings { id, value }))
>> value: be_u32 }
>> (HTTP2FrameSettings { id, value })
) pub fn http2_parse_frame_settings(i: &[u8]) -> IResult<&[u8], Vec<HTTP2FrameSettings>> {
); many0(complete(http2_parse_frame_setting))(i)
}
named!(pub http2_parse_frame_settings<Vec<HTTP2FrameSettings>>,
many0!( complete!(http2_parse_frame_setting) )
);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

Loading…
Cancel
Save