]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/http2: convert parser to nom7 functions (HTTP2 core functions)
authorPierre Chifflier <chifflier@wzdftpd.net>
Wed, 12 Jan 2022 15:17:40 +0000 (16:17 +0100)
committerVictor Julien <vjulien@oisf.net>
Mon, 17 Jan 2022 12:13:08 +0000 (13:13 +0100)
rust/src/http2/http2.rs
rust/src/http2/huffman.rs
rust/src/http2/parser.rs

index ba5b44e7f044f557f42e5914d100dd6226d7cb0c..821921c5c74121ab5cb7a6e7930f28fdeee97df5 100644 (file)
@@ -24,7 +24,7 @@ use crate::applayer::{self, *};
 use crate::core::*;
 use crate::filecontainer::*;
 use crate::filetracker::*;
-use nom;
+use nom7::Err;
 use std;
 use std::ffi::CString;
 use std::fmt;
@@ -647,7 +647,7 @@ impl HTTP2State {
                         //we could set an event on remaining data
                         return HTTP2FrameTypeData::SETTINGS(set);
                     }
-                    Err(nom::Err::Incomplete(_)) => {
+                    Err(Err::Incomplete(_)) => {
                         if complete {
                             self.set_event(HTTP2Event::InvalidFrameData);
                             return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@@ -738,7 +738,7 @@ impl HTTP2State {
                         self.process_headers(&hs.blocks, dir);
                         return HTTP2FrameTypeData::PUSHPROMISE(hs);
                     }
-                    Err(nom::Err::Incomplete(_)) => {
+                    Err(Err::Incomplete(_)) => {
                         if complete {
                             self.set_event(HTTP2Event::InvalidFrameData);
                             return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@@ -772,7 +772,7 @@ impl HTTP2State {
                         self.process_headers(&hs.blocks, dir);
                         return HTTP2FrameTypeData::CONTINUATION(hs);
                     }
-                    Err(nom::Err::Incomplete(_)) => {
+                    Err(Err::Incomplete(_)) => {
                         if complete {
                             self.set_event(HTTP2Event::InvalidFrameData);
                             return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@@ -807,7 +807,7 @@ impl HTTP2State {
                         }
                         return HTTP2FrameTypeData::HEADERS(hs);
                     }
-                    Err(nom::Err::Incomplete(_)) => {
+                    Err(Err::Incomplete(_)) => {
                         if complete {
                             self.set_event(HTTP2Event::InvalidFrameData);
                             return HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled {
@@ -929,7 +929,7 @@ impl HTTP2State {
                     }
                     input = &rem[hlsafe..];
                 }
-                Err(nom::Err::Incomplete(_)) => {
+                Err(Err::Incomplete(_)) => {
                     //we may have consumed data from previous records
                     return AppLayerResult::incomplete(
                         (il - input.len()) as u32,
@@ -1035,7 +1035,7 @@ pub unsafe extern "C" fn rs_http2_probing_parser_tc(
                 }
                 return ALPROTO_HTTP2;
             }
-            Err(nom::Err::Incomplete(_)) => {
+            Err(Err::Incomplete(_)) => {
                 return ALPROTO_UNKNOWN;
             }
             Err(_) => {
index 05ec03a5f072afec1ca948b18cae587aeab16097..b03fcf3b88e316bb02fadb8d8ba913fa768e1a83 100644 (file)
  * 02110-1301, USA.
  */
 
-use nom::error::ErrorKind;
-use nom::Err;
-use nom::IResult;
+use nom7::bits::streaming::take as take_bits;
+use nom7::branch::alt;
+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> {
     match n {
@@ -35,9 +37,9 @@ fn http2_huffman_table_len5(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len5<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(5u32), http2_huffman_table_len5) )
-);
+fn http2_decode_huffman_len5(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(5u32), http2_huffman_table_len5))(input)
+}
 
 fn http2_huffman_table_len6(n: u32) -> Option<u8> {
     match n {
@@ -71,9 +73,9 @@ fn http2_huffman_table_len6(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len6<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(6u32), http2_huffman_table_len6))
-);
+fn http2_decode_huffman_len6(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(6u32), http2_huffman_table_len6))(input)
+}
 
 fn http2_huffman_table_len7(n: u32) -> Option<u8> {
     match n {
@@ -113,9 +115,9 @@ fn http2_huffman_table_len7(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len7<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(7u32), http2_huffman_table_len7))
-);
+fn http2_decode_huffman_len7(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(7u32), http2_huffman_table_len7))(input)
+}
 
 fn http2_huffman_table_len8(n: u32) -> Option<u8> {
     match n {
@@ -129,9 +131,9 @@ fn http2_huffman_table_len8(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len8<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(8u32), http2_huffman_table_len8))
-);
+fn http2_decode_huffman_len8(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(8u32), http2_huffman_table_len8))(input)
+}
 
 fn http2_huffman_table_len10(n: u32) -> Option<u8> {
     match n {
@@ -144,9 +146,9 @@ fn http2_huffman_table_len10(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len10<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(10u32), http2_huffman_table_len10))
-);
+fn http2_decode_huffman_len10(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(10u32), http2_huffman_table_len10))(input)
+}
 
 fn http2_huffman_table_len11(n: u32) -> Option<u8> {
     match n {
@@ -157,9 +159,9 @@ fn http2_huffman_table_len11(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len11<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(11u32), http2_huffman_table_len11))
-);
+fn http2_decode_huffman_len11(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(11u32), http2_huffman_table_len11))(input)
+}
 
 fn http2_huffman_table_len12(n: u32) -> Option<u8> {
     match n {
@@ -169,9 +171,9 @@ fn http2_huffman_table_len12(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len12<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(12u32), http2_huffman_table_len12))
-);
+fn http2_decode_huffman_len12(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(12u32), http2_huffman_table_len12))(input)
+}
 
 fn http2_huffman_table_len13(n: u32) -> Option<u8> {
     match n {
@@ -185,9 +187,9 @@ fn http2_huffman_table_len13(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len13<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(13u32), http2_huffman_table_len13))
-);
+fn http2_decode_huffman_len13(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(13u32), http2_huffman_table_len13))(input)
+}
 
 fn http2_huffman_table_len14(n: u32) -> Option<u8> {
     match n {
@@ -197,9 +199,9 @@ fn http2_huffman_table_len14(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len14<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(14u32), http2_huffman_table_len14))
-);
+fn http2_decode_huffman_len14(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(14u32), http2_huffman_table_len14))(input)
+}
 
 fn http2_huffman_table_len15(n: u32) -> Option<u8> {
     match n {
@@ -210,9 +212,9 @@ fn http2_huffman_table_len15(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len15<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(15u32), http2_huffman_table_len15))
-);
+fn http2_decode_huffman_len15(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(15u32), http2_huffman_table_len15))(input)
+}
 
 fn http2_huffman_table_len19(n: u32) -> Option<u8> {
     match n {
@@ -223,9 +225,9 @@ fn http2_huffman_table_len19(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len19<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(19u32), http2_huffman_table_len19))
-);
+fn http2_decode_huffman_len19(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(19u32), http2_huffman_table_len19))(input)
+}
 
 fn http2_huffman_table_len20(n: u32) -> Option<u8> {
     match n {
@@ -241,9 +243,9 @@ fn http2_huffman_table_len20(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len20<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(20u32), http2_huffman_table_len20))
-);
+fn http2_decode_huffman_len20(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(20u32), http2_huffman_table_len20))(input)
+}
 
 fn http2_huffman_table_len21(n: u32) -> Option<u8> {
     match n {
@@ -264,9 +266,9 @@ fn http2_huffman_table_len21(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len21<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(21u32), http2_huffman_table_len21))
-);
+fn http2_decode_huffman_len21(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(21u32), http2_huffman_table_len21))(input)
+}
 
 fn http2_huffman_table_len22(n: u32) -> Option<u8> {
     match n {
@@ -300,9 +302,9 @@ fn http2_huffman_table_len22(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len22<(&[u8], usize), u8>,
-complete!( map_opt!(take_bits!(22u32), http2_huffman_table_len22))
-);
+fn http2_decode_huffman_len22(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(22u32), http2_huffman_table_len22))(input)
+}
 
 fn http2_huffman_table_len23(n: u32) -> Option<u8> {
     match n {
@@ -339,9 +341,9 @@ fn http2_huffman_table_len23(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len23<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(23u32), http2_huffman_table_len23))
-);
+fn http2_decode_huffman_len23(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(23u32), http2_huffman_table_len23))(input)
+}
 
 fn http2_huffman_table_len24(n: u32) -> Option<u8> {
     match n {
@@ -361,9 +363,9 @@ fn http2_huffman_table_len24(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len24<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(24u32), http2_huffman_table_len24))
-);
+fn http2_decode_huffman_len24(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(24u32), http2_huffman_table_len24))(input)
+}
 
 fn http2_huffman_table_len25(n: u32) -> Option<u8> {
     match n {
@@ -375,9 +377,9 @@ fn http2_huffman_table_len25(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len25<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(25u32), http2_huffman_table_len25))
-);
+fn http2_decode_huffman_len25(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(25u32), http2_huffman_table_len25))(input)
+}
 
 fn http2_huffman_table_len26(n: u32) -> Option<u8> {
     match n {
@@ -400,9 +402,9 @@ fn http2_huffman_table_len26(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len26<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(26u32), http2_huffman_table_len26))
-);
+fn http2_decode_huffman_len26((i, bit_offset): (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(26u32), http2_huffman_table_len26))((i, bit_offset))
+}
 
 fn http2_huffman_table_len27(n: u32) -> Option<u8> {
     match n {
@@ -429,9 +431,9 @@ fn http2_huffman_table_len27(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len27<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(27u32), http2_huffman_table_len27))
-);
+fn http2_decode_huffman_len27(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(27u32), http2_huffman_table_len27))(input)
+}
 
 fn http2_huffman_table_len28(n: u32) -> Option<u8> {
     match n {
@@ -468,9 +470,9 @@ fn http2_huffman_table_len28(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len28<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(28u32), http2_huffman_table_len28))
-);
+fn http2_decode_huffman_len28(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(28u32), http2_huffman_table_len28))(input)
+}
 
 fn http2_huffman_table_len30(n: u32) -> Option<u8> {
     match n {
@@ -482,23 +484,44 @@ fn http2_huffman_table_len30(n: u32) -> Option<u8> {
     }
 }
 
-named!(http2_decode_huffman_len30<(&[u8], usize), u8>,
-    complete!( map_opt!(take_bits!(30u32), http2_huffman_table_len30))
-);
+fn http2_decode_huffman_len30(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    complete(map_opt(take_bits(30u32), http2_huffman_table_len30))(input)
+}
 
 //hack to end many0 even if some bits are remaining
 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
-named!(pub http2_decode_huffman<(&[u8], usize), u8>,
-    alt!(http2_decode_huffman_len5 | http2_decode_huffman_len6 | http2_decode_huffman_len7 |
-    http2_decode_huffman_len8 | 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_len22 | http2_decode_huffman_len23 |
-    http2_decode_huffman_len24 | http2_decode_huffman_len25 | http2_decode_huffman_len26 |
-    http2_decode_huffman_len27 | http2_decode_huffman_len28 | http2_decode_huffman_len30 |
-    http2_decode_huffman_end)
-);
+pub fn http2_decode_huffman(input: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
+    // trait nom::branch::Alt is implemented for lists up to size 20,
+    // so use nested `alt` as a workaround (see nom documentation for `alt`)
+    alt((
+        http2_decode_huffman_len5,
+        http2_decode_huffman_len6,
+        http2_decode_huffman_len7,
+        http2_decode_huffman_len8,
+        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)
+}
index 87e988389570f0707715c45f0d00eebf5f0b632d..77caa5684c95791dca94a76c4cf424e3d1a97636 100644 (file)
 
 use super::huffman;
 use crate::http2::http2::{HTTP2DynTable, HTTP2_MAX_TABLESIZE};
-use nom::character::complete::digit1;
-use nom::combinator::rest;
-use nom::error::ErrorKind;
-use nom::number::streaming::{be_u16, be_u32, be_u8};
-use nom::Err;
-use nom::IResult;
+use nom7::bits::{bits, streaming::take as take_bits};
+use nom7::branch::alt;
+use nom7::bytes::streaming::{is_a, is_not, tag, take, take_while};
+use nom7::character::complete::digit1;
+use nom7::combinator::{complete, cond, map_opt, opt, rest, verify};
+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::str::FromStr;
 
@@ -79,18 +83,23 @@ pub struct HTTP2FrameHeader {
     pub stream_id: u32,
 }
 
-named!(pub http2_parse_frame_header<HTTP2FrameHeader>,
-    do_parse!(
-        length: bits!( take_bits!(24u32) ) >>
-        ftype: be_u8 >>
-        flags: be_u8 >>
-        stream_id: bits!( tuple!( take_bits!(1u8),
-                                  take_bits!(31u32) ) ) >>
-        (HTTP2FrameHeader{length, ftype, flags,
-                          reserved:stream_id.0,
-                          stream_id:stream_id.1})
-    )
-);
+pub fn http2_parse_frame_header(i: &[u8]) -> IResult<&[u8], HTTP2FrameHeader> {
+    let (i, length) = be_u24(i)?;
+    let (i, ftype) = be_u8(i)?;
+    let (i, flags) = be_u8(i)?;
+    let (i, b) = be_u32(i)?;
+    let (reserved, stream_id) = ((b >> 31) as u8, b & 0x7fff_ffff);
+    Ok((
+        i,
+        HTTP2FrameHeader {
+            length,
+            ftype,
+            flags,
+            reserved,
+            stream_id,
+        },
+    ))
+}
 
 #[repr(u32)]
 #[derive(Clone, Copy, PartialEq, FromPrimitive, Debug)]
@@ -147,24 +156,20 @@ pub struct HTTP2FrameGoAway {
     pub errorcode: u32, //HTTP2ErrorCode
 }
 
-named!(pub http2_parse_frame_goaway<HTTP2FrameGoAway>,
-    do_parse!(
-        errorcode: be_u32 >>
-        (HTTP2FrameGoAway{errorcode})
-    )
-);
+pub fn http2_parse_frame_goaway(i: &[u8]) -> IResult<&[u8], HTTP2FrameGoAway> {
+    let (i, errorcode) = be_u32(i)?;
+    Ok((i, HTTP2FrameGoAway { errorcode }))
+}
 
 #[derive(Clone, Copy, Debug)]
 pub struct HTTP2FrameRstStream {
     pub errorcode: u32, ////HTTP2ErrorCode
 }
 
-named!(pub http2_parse_frame_rststream<HTTP2FrameRstStream>,
-    do_parse!(
-        errorcode: be_u32 >>
-        (HTTP2FrameRstStream{errorcode})
-    )
-);
+pub fn http2_parse_frame_rststream(i: &[u8]) -> IResult<&[u8], HTTP2FrameRstStream> {
+    let (i, errorcode) = be_u32(i)?;
+    Ok((i, HTTP2FrameRstStream { errorcode }))
+}
 
 #[derive(Clone, Copy, Debug)]
 pub struct HTTP2FramePriority {
@@ -173,14 +178,19 @@ pub struct HTTP2FramePriority {
     pub weight: u8,
 }
 
-named!(pub http2_parse_frame_priority<HTTP2FramePriority>,
-    do_parse!(
-        sid: bits!( tuple!( take_bits!(1u8),
-                            take_bits!(31u32) ) ) >>
-        weight: be_u8 >>
-        (HTTP2FramePriority{exclusive:sid.0, dependency:sid.1, weight})
-    )
-);
+pub fn http2_parse_frame_priority(i: &[u8]) -> IResult<&[u8], HTTP2FramePriority> {
+    let (i, b) = be_u32(i)?;
+    let (exclusive, dependency) = ((b >> 31) as u8, b & 0x7fff_ffff);
+    let (i, weight) = be_u8(i)?;
+    Ok((
+        i,
+        HTTP2FramePriority {
+            exclusive,
+            dependency,
+            weight,
+        },
+    ))
+}
 
 #[derive(Clone, Copy, Debug)]
 pub struct HTTP2FrameWindowUpdate {
@@ -188,13 +198,11 @@ pub struct HTTP2FrameWindowUpdate {
     pub sizeinc: u32,
 }
 
-named!(pub http2_parse_frame_windowupdate<HTTP2FrameWindowUpdate>,
-    do_parse!(
-        sizeinc: bits!( tuple!( take_bits!(1u8),
-                                take_bits!(31u32) ) ) >>
-        (HTTP2FrameWindowUpdate{reserved:sizeinc.0, sizeinc:sizeinc.1})
-    )
-);
+pub fn http2_parse_frame_windowupdate(i: &[u8]) -> IResult<&[u8], HTTP2FrameWindowUpdate> {
+    let (i, b) = be_u32(i)?;
+    let (reserved, sizeinc) = ((b >> 31) as u8, b & 0x7fff_ffff);
+    Ok((i, HTTP2FrameWindowUpdate { reserved, sizeinc }))
+}
 
 #[derive(Clone, Copy, Debug)]
 pub struct HTTP2FrameHeadersPriority {
@@ -203,14 +211,19 @@ pub struct HTTP2FrameHeadersPriority {
     pub weight: u8,
 }
 
-named!(pub http2_parse_headers_priority<HTTP2FrameHeadersPriority>,
-    do_parse!(
-        sid: bits!( tuple!( take_bits!(1u8),
-                                take_bits!(31u32) ) ) >>
-        weight: be_u8 >>
-        (HTTP2FrameHeadersPriority{exclusive:sid.0, dependency:sid.1, weight})
-    )
-);
+pub fn http2_parse_headers_priority(i: &[u8]) -> IResult<&[u8], HTTP2FrameHeadersPriority> {
+    let (i, b) = be_u32(i)?;
+    let (exclusive, dependency) = ((b >> 31) as u8, b & 0x7fff_ffff);
+    let (i, weight) = be_u8(i)?;
+    Ok((
+        i,
+        HTTP2FrameHeadersPriority {
+            exclusive,
+            dependency,
+            weight,
+        },
+    ))
+}
 
 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,
 ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
     fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
-        bits!(
-            input,
-            complete!(tuple!(
-                verify!(take_bits!(1u8), |&x| x == 1),
-                take_bits!(7u8)
-            ))
-        )
+        bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
+            verify(take_bits(1u8), |&x| x == 1),
+            take_bits(7u8),
+        ))))(input)
     }
     let (i2, indexed) = parser(input)?;
     let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 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) {
         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 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 (i2, stringlen) = http2_parse_var_uint(i1, huffslen.1 as u64, 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 {
         return Ok((i3, data.to_vec()));
     } 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));
     }
 }
@@ -419,18 +431,15 @@ fn http2_parse_headers_block_literal_incindex<'a>(
     input: &'a [u8], dyn_headers: &mut HTTP2DynTable,
 ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
     fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
-        bits!(
-            input,
-            complete!(tuple!(
-                verify!(take_bits!(2u8), |&x| x == 1),
-                take_bits!(6u8)
-            ))
-        )
+        bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
+            verify(take_bits(2u8), |&x| x == 1),
+            take_bits(6u8),
+        ))))(input)
     }
     let (i2, indexed) = parser(input)?;
     let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 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);
     match r {
@@ -476,18 +485,15 @@ fn http2_parse_headers_block_literal_noindex<'a>(
     input: &'a [u8], dyn_headers: &HTTP2DynTable,
 ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
     fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
-        bits!(
-            input,
-            complete!(tuple!(
-                verify!(take_bits!(4u8), |&x| x == 0),
-                take_bits!(4u8)
-            ))
-        )
+        bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
+            verify(take_bits(4u8), |&x| x == 0),
+            take_bits(4u8),
+        ))))(input)
     }
     let (i2, indexed) = parser(input)?;
     let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 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);
     return r;
@@ -497,18 +503,15 @@ fn http2_parse_headers_block_literal_neverindex<'a>(
     input: &'a [u8], dyn_headers: &HTTP2DynTable,
 ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
     fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
-        bits!(
-            input,
-            complete!(tuple!(
-                verify!(take_bits!(4u8), |&x| x == 1),
-                take_bits!(4u8)
-            ))
-        )
+        bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
+            verify(take_bits(4u8), |&x| x == 1),
+            take_bits(4u8),
+        ))))(input)
     }
     let (i2, indexed) = parser(input)?;
     let (i3, indexreal) = http2_parse_var_uint(i2, indexed.1 as u64, 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);
     return r;
@@ -518,7 +521,7 @@ fn http2_parse_var_uint(input: &[u8], value: u64, max: u64) -> IResult<&[u8], u6
     if value < max {
         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)?;
     if varia.len() > 9 || (varia.len() == 9 && finalv > 1) {
         // this will overflow u64
@@ -540,13 +543,10 @@ fn http2_parse_headers_block_dynamic_size<'a>(
     input: &'a [u8], dyn_headers: &mut HTTP2DynTable,
 ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> {
     fn parser(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
-        bits!(
-            input,
-            complete!(tuple!(
-                verify!(take_bits!(3u8), |&x| x == 1),
-                take_bits!(5u8)
-            ))
-        )
+        bits::<_, _, Error<(&[u8], usize)>, _, _>(complete(tuple((
+            verify(take_bits(3u8), |&x| x == 1),
+            take_bits(5u8),
+        ))))(input)
     }
     let (i2, maxsize) = parser(input)?;
     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>(
     input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable,
 ) -> IResult<&'a [u8], HTTP2FrameHeaders> {
-    let (i2, padlength) = cond!(input, flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)?;
-    let (mut i3, priority) = cond!(
-        i2,
+    let (i2, padlength) = cond(flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)(input)?;
+    let (mut i3, priority) = cond(
         flags & HTTP2_FLAG_HEADER_PRIORITY != 0,
-        http2_parse_headers_priority
-    )?;
+        http2_parse_headers_priority,
+    )(i2)?;
     let mut blocks = Vec::new();
     while i3.len() > 0 {
         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());
                 if i3.len() == rem.len() {
                     //infinite loop
-                    return Err(Err::Error((input, ErrorKind::Eof)));
+                    return Err(Err::Error(make_error(input, ErrorKind::Eof)));
                 }
                 i3 = rem;
             }
@@ -660,8 +659,9 @@ pub struct HTTP2FramePushPromise {
 pub fn http2_parse_frame_push_promise<'a>(
     input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable,
 ) -> IResult<&'a [u8], HTTP2FramePushPromise> {
-    let (i2, padlength) = cond!(input, flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)?;
-    let (mut i3, stream_id) = bits!(i2, tuple!(take_bits!(1u8), take_bits!(31u32)))?;
+    let (i2, padlength) = cond(flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)(input)?;
+    let (mut i3, stream_id) =
+        bits::<_, _, Error<(&[u8], usize)>, _, _>(tuple((take_bits(1u8), take_bits(31u32))))(i2)?;
     let mut blocks = Vec::new();
     while i3.len() > 0 {
         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());
                 if i3.len() == rem.len() {
                     //infinite loop
-                    return Err(Err::Error((input, ErrorKind::Eof)));
+                    return Err(Err::Error(make_error(input, ErrorKind::Eof)));
                 }
                 i3 = rem;
             }
@@ -707,7 +707,7 @@ pub fn http2_parse_frame_continuation<'a>(
                 debug_validate_bug_on!(i3.len() == rem.len());
                 if i3.len() == rem.len() {
                     //infinite loop
-                    return Err(Err::Error((input, ErrorKind::Eof)));
+                    return Err(Err::Error(make_error(input, ErrorKind::Eof)));
                 }
                 i3 = rem;
             }
@@ -774,69 +774,86 @@ pub struct DetectHTTP2settingsSigCtx {
     pub value: Option<DetectU32Data>, //optional value
 }
 
-named!(detect_parse_u32_start_equal<&str,DetectU32Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        opt! (tag!("=") ) >>
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >>
-        (DetectU32Data{value, valrange:0, mode:DetectUintMode::DetectUintModeEqual})
-    )
-);
-
-named!(detect_parse_u32_start_interval<&str,DetectU32Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >>
-        opt!( is_a!( " " ) ) >>
-        tag!("-") >>
-        opt!( is_a!( " " ) ) >>
-        valrange : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >>
-        (DetectU32Data{value, valrange, mode:DetectUintMode::DetectUintModeRange})
-    )
-);
-
-named!(detect_parse_u32_start_lesser<&str,DetectU32Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        tag!("<") >>
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >>
-        (DetectU32Data{value, valrange:0, mode:DetectUintMode::DetectUintModeLt})
-    )
-);
-
-named!(detect_parse_u32_start_greater<&str,DetectU32Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        tag!(">") >>
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u32>().ok()) >>
-        (DetectU32Data{value, valrange:0, mode:DetectUintMode::DetectUintModeGt})
-    )
-);
-
-named!(detect_parse_u32<&str,DetectU32Data>,
-    do_parse!(
-        u32 : alt! (
-            detect_parse_u32_start_lesser |
-            detect_parse_u32_start_greater |
-            complete!( detect_parse_u32_start_interval ) |
-            detect_parse_u32_start_equal
-        ) >>
-        (u32)
-    )
-);
-
-named!(pub http2_parse_settingsctx<&str,DetectHTTP2settingsSigCtx>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        id: map_opt!( alt! ( complete!( is_not!( " <>=" ) ) | rest ),
-            |s: &str| HTTP2SettingsId::from_str(s).ok() ) >>
-        value: opt!( complete!( detect_parse_u32 ) ) >>
-        (DetectHTTP2settingsSigCtx{id, value})
-    )
-);
+fn detect_parse_u32_start_equal(i: &str) -> IResult<&str, DetectU32Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, _) = opt(tag("="))(i)?;
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
+    Ok((
+        i,
+        DetectU32Data {
+            value,
+            valrange: 0,
+            mode: DetectUintMode::DetectUintModeEqual,
+        },
+    ))
+}
+
+fn detect_parse_u32_start_interval(i: &str) -> IResult<&str, DetectU32Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
+    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)?;
+    Ok((
+        i,
+        DetectU32Data {
+            value,
+            valrange,
+            mode: DetectUintMode::DetectUintModeRange,
+        },
+    ))
+}
+
+fn detect_parse_u32_start_lesser(i: &str) -> IResult<&str, DetectU32Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, _) = tag("<")(i)?;
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
+    Ok((
+        i,
+        DetectU32Data {
+            value,
+            valrange: 0,
+            mode: DetectUintMode::DetectUintModeLt,
+        },
+    ))
+}
+
+fn detect_parse_u32_start_greater(i: &str) -> IResult<&str, DetectU32Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, _) = tag(">")(i)?;
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, value) = map_opt(digit1, |s: &str| s.parse::<u32>().ok())(i)?;
+    Ok((
+        i,
+        DetectU32Data {
+            value,
+            valrange: 0,
+            mode: DetectUintMode::DetectUintModeGt,
+        },
+    ))
+}
+
+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 value: u64,
@@ -844,59 +861,77 @@ pub struct DetectU64Data {
     pub mode: DetectUintMode,
 }
 
-named!(detect_parse_u64_start_equal<&str,DetectU64Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        opt! (tag!("=") ) >>
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >>
-        (DetectU64Data{value, valrange:0, mode:DetectUintMode::DetectUintModeEqual})
-    )
-);
-
-named!(detect_parse_u64_start_interval<&str,DetectU64Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >>
-        opt!( is_a!( " " ) ) >>
-        tag!("-") >>
-        opt!( is_a!( " " ) ) >>
-        valrange : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >>
-        (DetectU64Data{value, valrange, mode:DetectUintMode::DetectUintModeRange})
-    )
-);
-
-named!(detect_parse_u64_start_lesser<&str,DetectU64Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        tag!("<") >>
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >>
-        (DetectU64Data{value, valrange:0, mode:DetectUintMode::DetectUintModeLt})
-    )
-);
-
-named!(detect_parse_u64_start_greater<&str,DetectU64Data>,
-    do_parse!(
-        opt!( is_a!( " " ) ) >>
-        tag!(">") >>
-        opt!( is_a!( " " ) ) >>
-        value : map_opt!(digit1, |s: &str| s.parse::<u64>().ok()) >>
-        (DetectU64Data{value, valrange:0, mode:DetectUintMode::DetectUintModeGt})
-    )
-);
-
-named!(pub detect_parse_u64<&str,DetectU64Data>,
-    do_parse!(
-        u64 : alt! (
-            detect_parse_u64_start_lesser |
-            detect_parse_u64_start_greater |
-            complete!( detect_parse_u64_start_interval ) |
-            detect_parse_u64_start_equal
-        ) >>
-        (u64)
-    )
-);
+fn detect_parse_u64_start_equal(i: &str) -> IResult<&str, DetectU64Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, _) = opt(tag("="))(i)?;
+    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::DetectUintModeEqual,
+        },
+    ))
+}
+
+fn detect_parse_u64_start_interval(i: &str) -> IResult<&str, DetectU64Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, value) = map_opt(digit1, |s: &str| s.parse::<u64>().ok())(i)?;
+    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)?;
+    Ok((
+        i,
+        DetectU64Data {
+            value,
+            valrange,
+            mode: DetectUintMode::DetectUintModeRange,
+        },
+    ))
+}
+
+fn detect_parse_u64_start_lesser(i: &str) -> IResult<&str, DetectU64Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, _) = tag("<")(i)?;
+    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::DetectUintModeLt,
+        },
+    ))
+}
+
+fn detect_parse_u64_start_greater(i: &str) -> IResult<&str, DetectU64Data> {
+    let (i, _) = opt(is_a(" "))(i)?;
+    let (i, _) = tag(">")(i)?;
+    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)]
 pub struct HTTP2FrameSettings {
@@ -904,18 +939,15 @@ pub struct HTTP2FrameSettings {
     pub value: u32,
 }
 
-named!(
-    http2_parse_frame_setting<HTTP2FrameSettings>,
-    do_parse!(
-        id: map_opt!(be_u16, num::FromPrimitive::from_u16)
-            >> value: be_u32
-            >> (HTTP2FrameSettings { id, value })
-    )
-);
-
-named!(pub http2_parse_frame_settings<Vec<HTTP2FrameSettings>>,
-    many0!( complete!(http2_parse_frame_setting) )
-);
+fn http2_parse_frame_setting(i: &[u8]) -> IResult<&[u8], HTTP2FrameSettings> {
+    let (i, id) = map_opt(be_u16, num::FromPrimitive::from_u16)(i)?;
+    let (i, value) = be_u32(i)?;
+    Ok((i, HTTP2FrameSettings { id, value }))
+}
+
+pub fn http2_parse_frame_settings(i: &[u8]) -> IResult<&[u8], Vec<HTTP2FrameSettings>> {
+    many0(complete(http2_parse_frame_setting))(i)
+}
 
 #[cfg(test)]
 mod tests {