smb: generic event per trans/read/write for tx events

pull/3281/head
Victor Julien 9 years ago
parent 05992f1772
commit 78cd92a933

@ -561,6 +561,8 @@ pub fn get_service_for_nameslice(nameslice: &[u8]) -> (&'static str, bool)
pub fn smb1_trans_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
{
let mut events : Vec<SMBEvent> = Vec::new();
match parse_smb_trans_request_record(r.data, r) {
IResult::Done(_, rd) => {
SCLogDebug!("TRANS request {:?}", rd);
@ -597,64 +599,73 @@ pub fn smb1_trans_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
}
},
_ => {
state.set_event(SMBEvent::MalformedData);
events.push(SMBEvent::MalformedData);
},
}
smb1_request_record_generic(state, r, events);
}
pub fn smb1_trans_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
{
match parse_smb_trans_response_record(r.data) {
IResult::Done(_, rd) => {
SCLogDebug!("TRANS response {:?}", rd);
let mut events : Vec<SMBEvent> = Vec::new();
// see if we have a stored fid
let fid = match state.ssn2vec_map.remove(
&SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID)) {
Some(f) => f,
None => Vec::new(),
};
SCLogDebug!("FID {:?}", fid);
if r.nt_status == SMB_NTSTATUS_SUCCESS || r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW {
match parse_smb_trans_response_record(r.data) {
IResult::Done(_, rd) => {
SCLogDebug!("TRANS response {:?}", rd);
// if we get status 'BUFFER_OVERFLOW' this is only a part of
// the data. Store it in the ssn/tree for later use.
if r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW {
state.ssnguid2vec_map.insert(SMBHashKeyHdrGuid::new(
SMBCommonHdr::from1(r, SMBHDR_TYPE_TRANS_FRAG), fid),
rd.data.to_vec());
} else {
let txn_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_TXNAME);
let is_dcerpc = match state.ssn2vec_map.remove(&txn_hdr) {
None => false,
Some(s) => {
let (sername, is_dcerpc) = get_service_for_nameslice(&s);
SCLogDebug!("service: {} dcerpc {}", sername, is_dcerpc);
is_dcerpc
},
// see if we have a stored fid
let fid = match state.ssn2vec_map.remove(
&SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID)) {
Some(f) => f,
None => Vec::new(),
};
if is_dcerpc {
SCLogDebug!("SMBv1 TRANS TO PIPE");
let hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_HEADER);
let vercmd = SMBVerCmdStat::new1_with_ntstatus(r.command, r.nt_status);
smb_read_dcerpc_record(state, vercmd, hdr, &fid, &rd.data);
SCLogDebug!("FID {:?}", fid);
// if we get status 'BUFFER_OVERFLOW' this is only a part of
// the data. Store it in the ssn/tree for later use.
if r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW {
state.ssnguid2vec_map.insert(SMBHashKeyHdrGuid::new(
SMBCommonHdr::from1(r, SMBHDR_TYPE_TRANS_FRAG), fid),
rd.data.to_vec());
} else {
let txn_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_TXNAME);
let is_dcerpc = match state.ssn2vec_map.remove(&txn_hdr) {
None => false,
Some(s) => {
let (sername, is_dcerpc) = get_service_for_nameslice(&s);
SCLogDebug!("service: {} dcerpc {}", sername, is_dcerpc);
is_dcerpc
},
};
if is_dcerpc {
SCLogDebug!("SMBv1 TRANS TO PIPE");
let hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_HEADER);
let vercmd = SMBVerCmdStat::new1_with_ntstatus(r.command, r.nt_status);
smb_read_dcerpc_record(state, vercmd, hdr, &fid, &rd.data);
}
}
}
},
_ => {
state.set_event(SMBEvent::MalformedData);
},
},
_ => {
events.push(SMBEvent::MalformedData);
},
}
}
// generic tx as well. Set events if needed.
smb1_response_record_generic(state, r, events);
}
fn smb1_write_request_record_generic_error<'b>(state: &mut SMBState, r: &SmbRecord<'b>, event: SMBEvent) {
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_event(event);
tx.set_events(events);
}
/// Handle WRITE, WRITE_ANDX, WRITE_AND_CLOSE request records
pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
{
let mut events : Vec<SMBEvent> = Vec::new();
let result = if r.command == SMB1_COMMAND_WRITE_ANDX {
parse_smb1_write_andx_request_record(r.data)
} else if r.command == SMB1_COMMAND_WRITE {
@ -722,12 +733,13 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
}
},
_ => {
smb1_write_request_record_generic_error(state, r, SMBEvent::MalformedData);
events.push(SMBEvent::MalformedData);
},
}
smb1_request_record_generic(state, r, events);
}
fn smb1_read_response_record_generic<'b>(state: &mut SMBState, r: &SmbRecord<'b>, events: Vec<SMBEvent>) {
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);
@ -820,5 +832,5 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
}
// generic tx as well. Set events if needed.
smb1_read_response_record_generic(state, r, events);
smb1_response_record_generic(state, r, events);
}

Loading…
Cancel
Save