*/
use std::mem::transmute;
-use crate::applayer::{AppLayerResult, AppLayerTxData};
+use crate::applayer::*;
use crate::core::{self, sc_detect_engine_state_free};
use crate::dcerpc::parser;
use nom::error::ErrorKind;
*endianness = tx.get_endianness();
}
+/// Probe input to see if it looks like DCERPC.
+fn probe(input: &[u8]) -> (bool, bool) {
+ match parser::parse_dcerpc_header(input) {
+ Ok((_, hdr)) => {
+ let is_request = hdr.hdrtype == 0x00;
+ let is_dcerpc = hdr.rpc_vers == 0x05 && hdr.rpc_vers_minor == 0x00;
+ return (is_dcerpc, is_request);
+ },
+ Err(_) => (false, false),
+ }
+}
+
+#[no_mangle]
+pub extern "C" fn rs_dcerpc_probe_tcp(direction: u8, input: *const u8,
+ len: u32, rdir: *mut u8) -> i32
+{
+ SCLogDebug!("Probing packet for DCERPC");
+ if len == 0 {
+ return core::ALPROTO_UNKNOWN;
+ }
+ let slice: &[u8] = unsafe {
+ std::slice::from_raw_parts(input as *mut u8, len as usize)
+ };
+ //is_incomplete is checked by caller
+ let (is_dcerpc, is_request, ) = probe(slice);
+ if is_dcerpc {
+ let dir = if is_request {
+ core::STREAM_TOSERVER
+ } else {
+ core::STREAM_TOCLIENT
+ };
+ if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir {
+ unsafe { *rdir = dir };
+ }
+ return 1;
+ }
+ return 0;
+
+}
+
#[cfg(test)]
mod tests {
use crate::applayer::AppLayerResult;
dce_state.tx_id
}
+/// Probe input to see if it looks like DCERPC.
+fn probe(input: &[u8]) -> (bool, bool) {
+ match parser::parse_dcerpc_udp_header(input) {
+ Ok((_, hdr)) => {
+ let is_request = hdr.pkt_type == 0x00;
+ let is_dcerpc = hdr.rpc_vers == 0x04;
+ return (is_dcerpc, is_request);
+ },
+ Err(_) => (false, false),
+ }
+}
+
+#[no_mangle]
+pub extern "C" fn rs_dcerpc_probe_udp(direction: u8, input: *const u8,
+ len: u32, rdir: *mut u8) -> i32
+{
+ SCLogDebug!("Probing the packet for DCERPC/UDP");
+ if len == 0 {
+ return core::ALPROTO_UNKNOWN;
+ }
+ let slice: &[u8] = unsafe {
+ std::slice::from_raw_parts(input as *mut u8, len as usize)
+ };
+ //is_incomplete is checked by caller
+ let (is_dcerpc, is_request) = probe(slice);
+ if is_dcerpc {
+ let dir = if is_request {
+ core::STREAM_TOSERVER
+ } else {
+ core::STREAM_TOCLIENT
+ };
+ if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir {
+ unsafe { *rdir = dir };
+ }
+ return 1;
+ }
+ return 0;
+
+}
+
+
#[cfg(test)]
mod tests {
use crate::applayer::AppLayerResult;
return rs_dcerpc_get_alstate_progress(tx, direction);
}
+static uint16_t DCERPCUDPProbe(
+ Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir)
+{
+ SCLogDebug("DCERPCUDPProbe");
+
+ const int r = rs_dcerpc_probe_udp(direction, input, len, rdir);
+ switch (r) {
+ case 1:
+ return ALPROTO_DCERPC;
+ case 0:
+ return ALPROTO_UNKNOWN;
+ case -1:
+ default:
+ return ALPROTO_FAILED;
+ }
+}
+
static int DCERPCUDPRegisterPatternsForProtocolDetection(void)
{
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_DCERPC,
- "|04 00|", 2, 0, STREAM_TOSERVER) < 0)
- {
+ if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_UDP, ALPROTO_DCERPC, "|04 00|", 2, 0,
+ STREAM_TOSERVER, DCERPCUDPProbe, 0, 0) < 0) {
return -1;
}
return rs_dcerpc_get_alstate_progress(tx, direction);
}
+static uint16_t DCERPCTCPProbe(
+ Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir)
+{
+ SCLogDebug("DCERPCTCPProbe");
+
+ const int r = rs_dcerpc_probe_tcp(direction, input, len, rdir);
+ switch (r) {
+ case 1:
+ return ALPROTO_DCERPC;
+ case 0:
+ return ALPROTO_UNKNOWN;
+ case -1:
+ default:
+ return ALPROTO_FAILED;
+ }
+}
+
static int DCERPCRegisterPatternsForProtocolDetection(void)
{
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC,
- "|05 00|", 2, 0, STREAM_TOSERVER) < 0)
- {
+ if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0,
+ STREAM_TOSERVER, DCERPCTCPProbe, 0, 0) < 0) {
return -1;
}
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC,
- "|05 00|", 2, 0, STREAM_TOCLIENT) < 0)
- {
+ if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0,
+ STREAM_TOCLIENT, DCERPCTCPProbe, 0, 0) < 0) {
return -1;
}