use crate::core::*;
use crate::filecontainer::*;
use crate::filetracker::*;
+use crate::frames::Frame;
use crate::dns::dns::{dns_parse_request, dns_parse_response, DNSTransaction};
static mut HTTP2_MAX_REASS: usize = 102400;
static mut HTTP2_MAX_STREAMS: usize = 4096; // 0x1000
+#[derive(AppLayerFrameType)]
+pub enum Http2FrameType {
+ Hdr,
+ Data,
+ Pdu,
+}
+
#[repr(u8)]
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Debug)]
pub enum HTTP2FrameUnhandledReason {
fn parse_frames(
&mut self, mut input: &[u8], il: usize, dir: Direction, flow: *const Flow,
+ stream_slice: &StreamSlice,
) -> AppLayerResult {
while !input.is_empty() {
match parser::http2_parse_frame_header(input) {
(hl, true)
};
+ let frame_hdr = Frame::new(
+ flow,
+ stream_slice,
+ input,
+ HTTP2_FRAME_HEADER_LEN as i64,
+ Http2FrameType::Hdr as u8,
+ None,
+ );
+ let frame_data = Frame::new(
+ flow,
+ stream_slice,
+ &input[HTTP2_FRAME_HEADER_LEN..],
+ head.length as i64,
+ Http2FrameType::Data as u8,
+ None,
+ );
+ let frame_pdu = Frame::new(
+ flow,
+ stream_slice,
+ input,
+ HTTP2_FRAME_HEADER_LEN as i64 + head.length as i64,
+ Http2FrameType::Pdu as u8,
+ None,
+ );
if head.length == 0 && head.ftype == parser::HTTP2FrameType::Settings as u8 {
input = &rem[hlsafe..];
continue;
return AppLayerResult::err();
}
let tx = tx.unwrap();
+ if let Some(frame) = frame_hdr {
+ frame.set_tx(flow, tx.tx_id);
+ }
+ if let Some(frame) = frame_data {
+ frame.set_tx(flow, tx.tx_id);
+ }
+ if let Some(frame) = frame_pdu {
+ frame.set_tx(flow, tx.tx_id);
+ }
if let Some(doh_req_buf) = tx.handle_frame(&head, &txdata, dir) {
if let Ok(mut dtx) = dns_parse_request(&doh_req_buf) {
dtx.id = 1;
if let Some(doh) = &mut tx.doh {
doh.dns_request_tx = Some(dtx);
} else {
- let doh = DohHttp2Tx { dns_request_tx: Some(dtx), ..Default::default() };
+ let doh = DohHttp2Tx {
+ dns_request_tx: Some(dtx),
+ ..Default::default()
+ };
tx.doh = Some(doh);
}
}
return AppLayerResult::ok();
}
- fn parse_ts(&mut self, mut input: &[u8], flow: *const Flow) -> AppLayerResult {
+ fn parse_ts(&mut self, flow: *const Flow, stream_slice: StreamSlice) -> AppLayerResult {
//very first : skip magic
+ let mut input = stream_slice.as_slice();
let mut magic_consumed = 0;
if self.progress < HTTP2ConnectionState::Http2StateMagicDone {
//skip magic
}
//then parse all we can
- let r = self.parse_frames(input, il, Direction::ToServer, flow);
+ let r = self.parse_frames(input, il, Direction::ToServer, flow, &stream_slice);
if r.status == 1 {
//adds bytes consumed by banner to incomplete result
return AppLayerResult::incomplete(r.consumed + magic_consumed as u32, r.needed);
}
}
- fn parse_tc(&mut self, mut input: &[u8], flow: *const Flow) -> AppLayerResult {
+ fn parse_tc(&mut self, flow: *const Flow, stream_slice: StreamSlice) -> AppLayerResult {
//first consume frame bytes
+ let mut input = stream_slice.as_slice();
let il = input.len();
if self.response_frame_size > 0 {
let ilen = input.len() as u32;
}
}
//then parse all we can
- return self.parse_frames(input, il, Direction::ToClient, flow);
+ return self.parse_frames(input, il, Direction::ToClient, flow, &stream_slice);
}
}
stream_slice: StreamSlice, _data: *const std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, HTTP2State);
- let buf = stream_slice.as_slice();
- return state.parse_ts(buf, flow);
+ return state.parse_ts(flow, stream_slice);
}
#[no_mangle]
stream_slice: StreamSlice, _data: *const std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, HTTP2State);
- let buf = stream_slice.as_slice();
- return state.parse_tc(buf, flow);
+ return state.parse_tc(flow, stream_slice);
}
#[no_mangle]
get_state_data: rs_http2_get_state_data,
apply_tx_config: None,
flags: 0,
- get_frame_id_by_name: None,
- get_frame_name_by_id: None,
+ get_frame_id_by_name: Some(Http2FrameType::ffi_id_from_name),
+ get_frame_name_by_id: Some(Http2FrameType::ffi_name_from_id),
};
let ip_proto_str = CString::new("tcp").unwrap();