pub bindack: Option<DCERPCBindAck>,
pub transactions: VecDeque<DCERPCTransaction>,
tx_index_completed: usize,
- pub buffer_ts: Vec<u8>,
- pub buffer_tc: Vec<u8>,
pub pad: u8,
pub padleft: u16,
pub bytes_consumed: i32,
pub fn clean_buffer(&mut self, direction: Direction) {
match direction {
Direction::ToServer => {
- self.buffer_ts.clear();
self.ts_gap = false;
}
Direction::ToClient => {
- self.buffer_tc.clear();
self.tc_gap = false;
}
}
self.bytes_consumed = 0;
}
- pub fn extend_buffer(&mut self, buffer: &[u8], direction: Direction) {
- match direction {
- Direction::ToServer => {
- self.buffer_ts.extend_from_slice(buffer);
- }
- Direction::ToClient => {
- self.buffer_tc.extend_from_slice(buffer);
- }
- }
- self.data_needed_for_dir = direction;
- }
-
pub fn reset_direction(&mut self, direction: Direction) {
if direction == Direction::ToServer {
self.data_needed_for_dir = Direction::ToClient;
}
pub fn handle_input_data(&mut self, input: &[u8], direction: Direction) -> AppLayerResult {
- let mut parsed;
+ let mut parsed = 0;
let retval;
let mut cur_i = input;
- let input_len = cur_i.len();
- let mut v: Vec<u8>;
+ let mut input_len = cur_i.len();
// Set any query's completion status to false in the beginning
self.query_completed = false;
}
}
- // Overwrite the dcerpc_state data in case of multiple complete queries in the
- // same direction
- if self.prev_dir == direction {
- self.data_needed_for_dir = direction;
- }
-
- let buffer = match direction {
- Direction::ToServer => {
- v = self.buffer_ts.split_off(0);
- v.extend_from_slice(cur_i);
- v.as_slice()
- }
- Direction::ToClient => {
- v = self.buffer_tc.split_off(0);
- v.extend_from_slice(cur_i);
- v.as_slice()
- }
- };
-
- if self.data_needed_for_dir != direction && !buffer.is_empty() {
- return AppLayerResult::err();
- }
-
- // Set data_needed_for_dir in the same direction in case there is an issue with upcoming parsing
- self.data_needed_for_dir = direction;
-
// Check if header data was complete. In case of EoF or incomplete data, wait for more
// data else return error
- if self.bytes_consumed < DCERPC_HDR_LEN.into() && input_len > 0 {
- parsed = self.process_header(buffer);
+ if self.header.is_none() && !cur_i.is_empty() {
+ parsed = self.process_header(cur_i);
if parsed == -1 {
- self.extend_buffer(buffer, direction);
- return AppLayerResult::ok();
+ return AppLayerResult::incomplete(0, DCERPC_HDR_LEN as u32);
}
if parsed < 0 {
return AppLayerResult::err();
}
self.bytes_consumed += parsed;
+ input_len -= parsed as usize;
}
let fraglen = self.get_hdr_fraglen().unwrap_or(0);
- if (buffer.len()) < fraglen as usize {
+ if (input_len + self.bytes_consumed as usize) < fraglen as usize {
SCLogDebug!("Possibly fragmented data, waiting for more..");
- self.extend_buffer(buffer, direction);
- return AppLayerResult::ok();
+ return AppLayerResult::incomplete(self.bytes_consumed as u32, (fraglen - self.bytes_consumed as u16) as u32);
} else {
self.query_completed = true;
}
- parsed = self.bytes_consumed;
let current_call_id = self.get_hdr_call_id().unwrap_or(0);
match self.get_hdr_type() {
Some(x) => match x {
DCERPC_TYPE_BIND | DCERPC_TYPE_ALTER_CONTEXT => {
- retval = self.process_bind_pdu(&buffer[parsed as usize..]);
+ retval = self.process_bind_pdu(&cur_i[parsed as usize..]);
if retval == -1 {
return AppLayerResult::err();
}
}
DCERPC_TYPE_BINDACK | DCERPC_TYPE_ALTER_CONTEXT_RESP => {
- retval = self.process_bindack_pdu(&buffer[parsed as usize..]);
+ retval = self.process_bindack_pdu(&cur_i[parsed as usize..]);
if retval == -1 {
return AppLayerResult::err();
}
}
}
DCERPC_TYPE_REQUEST => {
- retval = self.process_request_pdu(&buffer[parsed as usize..]);
+ retval = self.process_request_pdu(&cur_i[parsed as usize..]);
if retval < 0 {
return AppLayerResult::err();
}
}
};
retval = self.handle_common_stub(
- &buffer[parsed as usize..],
+ &cur_i[parsed as usize..],
0,
Direction::ToClient,
);
}
self.post_gap_housekeeping(direction);
self.prev_dir = direction;
+ self.header = None;
return AppLayerResult::ok();
}
}
input: &[u8], input_len: usize, hdrflags: u8, lenleft: u16,
stub_data_buffer: &mut Vec<u8>,stub_data_buffer_reset: &mut bool,
) -> u16 {
-
+
let fragtype = hdrflags & (PFC_FIRST_FRAG | PFC_LAST_FRAG);
// min of usize and u16 is a valid u16
let stub_len: u16 = cmp::min(lenleft as usize, input_len) as u16;