use crate::dcerpc::parser;
use crate::direction::{Direction, DIR_BOTH};
use crate::flow::Flow;
+use crate::frames::*;
use nom7::error::{Error, ErrorKind};
use nom7::number::Endianness;
use nom7::{Err, IResult, Needed};
pub static mut ALPROTO_DCERPC: AppProto = ALPROTO_UNKNOWN;
+#[derive(AppLayerFrameType)]
+pub enum DCERPCFrameType {
+ Pdu,
+ Hdr,
+ Data,
+}
+
pub fn dcerpc_type_string(t: u8) -> String {
match t {
DCERPC_TYPE_REQUEST => "REQUEST",
}
}
- pub fn handle_input_data(&mut self, input: &[u8], direction: Direction) -> AppLayerResult {
+ pub fn handle_input_data(&mut self, stream_slice: StreamSlice, direction: Direction) -> AppLayerResult {
let mut parsed = 0;
let retval;
- let mut cur_i = input;
+ let mut cur_i = stream_slice.as_slice();
// Skip the record since this means that its in the middle of a known length record
if (self.ts_gap && direction == Direction::ToServer) || (self.tc_gap && direction == Direction::ToClient) {
}
let mut frag_bytes_consumed: u16 = 0;
+ let mut flow = std::ptr::null();
+ if let Some(f) = self.flow {
+ flow = f;
+ }
// Check if header data was complete. In case of EoF or incomplete data, wait for more
// data else return error
if self.header.is_none() && !cur_i.is_empty() {
return AppLayerResult::incomplete(parsed as u32, fraglen as u32 - parsed as u32);
}
+ let _hdr = Frame::new(flow, &stream_slice, cur_i, parsed as i64, DCERPCFrameType::Hdr as u8, None);
+ let _pdu = Frame::new(flow, &stream_slice, cur_i, fraglen as i64, DCERPCFrameType::Pdu as u8, None);
+ if fraglen >= DCERPC_HDR_LEN && cur_i.len() > DCERPC_HDR_LEN as usize {
+ let _data = Frame::new(flow, &stream_slice, &cur_i[DCERPC_HDR_LEN as usize..], (fraglen - DCERPC_HDR_LEN) as i64, DCERPCFrameType::Data as u8, None);
+ }
let current_call_id = self.get_hdr_call_id().unwrap_or(0);
match self.get_hdr_type() {
}
if !stream_slice.is_gap() {
state.flow = Some(flow);
- return state.handle_input_data(stream_slice.as_slice(), Direction::ToServer);
+ return state.handle_input_data(stream_slice, Direction::ToServer);
}
AppLayerResult::err()
}
}
if !stream_slice.is_gap() {
state.flow = Some(flow);
- return state.handle_input_data(stream_slice.as_slice(), Direction::ToClient);
+ return state.handle_input_data(stream_slice, Direction::ToClient);
}
AppLayerResult::err()
}
get_state_data: rs_dcerpc_get_state_data,
apply_tx_config: None,
flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS,
- get_frame_id_by_name: None,
- get_frame_name_by_id: None,
+ get_frame_id_by_name: Some(DCERPCFrameType::ffi_id_from_name),
+ get_frame_name_by_id: Some(DCERPCFrameType::ffi_name_from_id),
};
let ip_proto_str = CString::new("tcp").unwrap();
#[cfg(test)]
mod tests {
- use crate::applayer::AppLayerResult;
+ use crate::applayer::{AppLayerResult, StreamSlice};
+ use crate::core::*;
use crate::dcerpc::dcerpc::DCERPCState;
use crate::direction::Direction;
use std::cmp;
let mut dcerpc_state = DCERPCState::new();
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(request, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(request, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(hdr) = dcerpc_state.header {
assert_eq!(0, hdr.hdrtype);
let mut dcerpc_state = DCERPCState::new();
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind1, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind1, STREAM_TOSERVER, 0), Direction::ToServer)
);
assert_eq!(
AppLayerResult::ok(), // TODO ASK if this is correct?
- dcerpc_state.handle_input_data(bind2, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind2, STREAM_TOSERVER, 0), Direction::ToServer)
);
}
];
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bindbuf, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bindbuf, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(ref bind) = dcerpc_state.bind {
let bind_uuid = &bind.uuid_list[0].uuid;
let mut dcerpc_state = DCERPCState::new();
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bindbuf, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bindbuf, STREAM_TOSERVER, 0), Direction::ToServer)
);
}
let mut dcerpc_state = DCERPCState::new();
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind_ack, Direction::ToClient)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack, STREAM_TOSERVER, 0), Direction::ToServer)
);
}
];
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind1, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind1, STREAM_TOSERVER, 0), Direction::ToServer)
);
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind_ack1, Direction::ToClient)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack1, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(ref back) = dcerpc_state.bindack {
assert_eq!(1, back.accepted_uuid_list.len());
}
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind2, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind2, STREAM_TOSERVER, 0), Direction::ToServer)
);
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind_ack2, Direction::ToClient)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack2, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(ref back) = dcerpc_state.bindack {
assert_eq!(1, back.accepted_uuid_list.len());
}
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind3, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind3, STREAM_TOSERVER, 0), Direction::ToServer)
);
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind_ack3, Direction::ToClient)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack3, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(ref back) = dcerpc_state.bindack {
assert_eq!(1, back.accepted_uuid_list.len());
];
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bind, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bind, STREAM_TOSERVER, 0), Direction::ToServer)
);
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(bindack, Direction::ToClient)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(bindack, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(ref back) = dcerpc_state.bindack {
assert_eq!(1, back.accepted_uuid_list.len());
}
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(alter_context, Direction::ToServer)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(alter_context, STREAM_TOSERVER, 0), Direction::ToServer)
);
assert_eq!(
AppLayerResult::ok(),
- dcerpc_state.handle_input_data(alter_context_resp, Direction::ToClient)
+ dcerpc_state.handle_input_data(StreamSlice::from_slice(alter_context_resp, STREAM_TOSERVER, 0), Direction::ToServer)
);
if let Some(ref back) = dcerpc_state.bindack {
assert_eq!(1, back.accepted_uuid_list.len());