smb1: disable 'generic tx's for common commands

Don't create a generic TX for each READ, WRITE, TRANS, TRANS2,
except if they cause events to trigger.
pull/3281/head
Victor Julien 8 years ago
parent 78cd92a933
commit 28f16e38ac

@ -1252,7 +1252,6 @@ impl SMBState {
}; };
self.check_gap_resync(max_tx_id); self.check_gap_resync(max_tx_id);
self._debug_tx_stats();
0 0
} }
@ -1482,6 +1481,7 @@ impl SMBState {
} }
}; };
self.check_gap_resync(max_tx_id); self.check_gap_resync(max_tx_id);
self._debug_tx_stats();
0 0
} }

@ -122,11 +122,13 @@ pub fn smb1_command_string(c: u8) -> String {
// later we'll use this to determine if we need to // later we'll use this to determine if we need to
// track a ssn per type // track a ssn per type
pub fn smb1_create_new_tx(_cmd: u8) -> bool { pub fn smb1_create_new_tx(_cmd: u8) -> bool {
// if _cmd == SMB1_COMMAND_READ_ANDX { match _cmd {
// false SMB1_COMMAND_READ_ANDX |
// } else { SMB1_COMMAND_WRITE_ANDX |
true SMB1_COMMAND_TRANS |
// } SMB1_COMMAND_TRANS2 => { false },
_ => { true },
}
} }
fn smb1_close_file(state: &mut SMBState, fid: &Vec<u8>) fn smb1_close_file(state: &mut SMBState, fid: &Vec<u8>)
@ -609,7 +611,6 @@ pub fn smb1_trans_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
{ {
let mut events : Vec<SMBEvent> = Vec::new(); let mut events : Vec<SMBEvent> = Vec::new();
if r.nt_status == SMB_NTSTATUS_SUCCESS || r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW {
match parse_smb_trans_response_record(r.data) { match parse_smb_trans_response_record(r.data) {
IResult::Done(_, rd) => { IResult::Done(_, rd) => {
SCLogDebug!("TRANS response {:?}", rd); SCLogDebug!("TRANS response {:?}", rd);
@ -650,17 +651,11 @@ pub fn smb1_trans_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
events.push(SMBEvent::MalformedData); events.push(SMBEvent::MalformedData);
}, },
} }
}
// generic tx as well. Set events if needed. // generic tx as well. Set events if needed.
smb1_response_record_generic(state, r, events); smb1_response_record_generic(state, r, events);
} }
fn smb1_request_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec<SMBEvent>) {
let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let tx = state.new_generic_tx(1, r.command as u16, tx_key);
tx.set_events(events);
}
/// Handle WRITE, WRITE_ANDX, WRITE_AND_CLOSE request records /// Handle WRITE, WRITE_ANDX, WRITE_AND_CLOSE request records
pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
{ {
@ -739,21 +734,6 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
smb1_request_record_generic(state, r, events); smb1_request_record_generic(state, r, events);
} }
fn smb1_response_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec<SMBEvent>) {
// see if we want a tx per READ command
if smb1_create_new_tx(r.command) {
let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let tx = state.get_generic_tx(1, r.command as u16, &tx_key);
if let Some(tx) = tx {
tx.request_done = true;
tx.response_done = true;
SCLogDebug!("tx {} cmd {} is done", tx.id, r.command);
tx.set_status(r.nt_status, r.is_dos_error);
tx.set_events(events);
}
}
}
pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
{ {
let mut events : Vec<SMBEvent> = Vec::new(); let mut events : Vec<SMBEvent> = Vec::new();
@ -834,3 +814,42 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
// generic tx as well. Set events if needed. // generic tx as well. Set events if needed.
smb1_response_record_generic(state, r, events); smb1_response_record_generic(state, r, events);
} }
/// create a tx for a command / response pair if we're
/// configured to do so, or if this is a tx especially
/// for setting an event.
fn smb1_request_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec<SMBEvent>) {
if smb1_create_new_tx(r.command) || events.len() > 0 {
let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let tx = state.new_generic_tx(1, r.command as u16, tx_key);
tx.set_events(events);
}
}
/// update or create a tx for a command / reponse pair based
/// on the response. We only create a tx for the response side
/// if we didn't already update a tx, and we have to set events
fn smb1_response_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec<SMBEvent>) {
// see if we want a tx per command
if smb1_create_new_tx(r.command) {
let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let tx = state.get_generic_tx(1, r.command as u16, &tx_key);
if let Some(tx) = tx {
tx.request_done = true;
tx.response_done = true;
SCLogDebug!("tx {} cmd {} is done", tx.id, r.command);
tx.set_status(r.nt_status, r.is_dos_error);
tx.set_events(events);
return;
}
}
if events.len() > 0 {
let tx_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let tx = state.new_generic_tx(1, r.command as u16, tx_key);
tx.request_done = true;
tx.response_done = true;
SCLogDebug!("tx {} cmd {} is done", tx.id, r.command);
tx.set_status(r.nt_status, r.is_dos_error);
tx.set_events(events);
}
}

@ -223,7 +223,7 @@ pub fn smb1_session_setup_response(state: &mut SMBState, r: &SmbRecord)
SCLogDebug!("smb1_session_setup_response: tx {:?}", tx); SCLogDebug!("smb1_session_setup_response: tx {:?}", tx);
}, },
None => { None => {
SCLogNotice!("smb1_session_setup_response: tx not found for {:?}", r); SCLogDebug!("smb1_session_setup_response: tx not found for {:?}", r);
}, },
} }
} }

Loading…
Cancel
Save