use nom7::error::{make_error, ErrorKind};
use nom7::IResult;
-use std::ffi::c_void;
+use std::os::raw::{c_int, c_void};
-use crate::enip::constant::{EnipCommand, EnipStatus};
-use crate::enip::enip::EnipTransaction;
-use crate::enip::parser::{
+use super::constant::{EnipCommand, EnipStatus};
+use super::enip::{EnipTransaction, ALPROTO_ENIP};
+use super::parser::{
CipData, CipDir, EnipCipRequestPayload, EnipCipResponsePayload, EnipItemPayload, EnipPayload,
CIP_MULTIPLE_SERVICE,
};
-use crate::detect::uint::{detect_match_uint, detect_parse_uint_enum, DetectUintData};
+use crate::detect::uint::{
+ detect_match_uint, detect_parse_uint_enum, rs_detect_u16_free, rs_detect_u16_match,
+ rs_detect_u16_parse, rs_detect_u32_free, rs_detect_u32_match, rs_detect_u32_parse,
+ rs_detect_u8_free, rs_detect_u8_match, rs_detect_u8_parse, DetectUintData,
+};
+use crate::detect::{
+ DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperBufferRegister,
+ DetectHelperGetData, DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt,
+ SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT,
+};
use crate::core::Direction;
use std::ffi::CStr;
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipParseCommand(
- raw: *const std::os::raw::c_char,
-) -> *mut DetectUintData<u16> {
+unsafe fn parse_command(raw: *const std::os::raw::c_char) -> *mut DetectUintData<u16> {
let raw: &CStr = CStr::from_ptr(raw); //unsafe
if let Ok(s) = raw.to_str() {
if let Some(ctx) = detect_parse_uint_enum::<u16, EnipCommand>(s) {
return std::ptr::null_mut();
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipParseStatus(
- raw: *const std::os::raw::c_char,
-) -> *mut DetectUintData<u32> {
+unsafe fn parse_status(raw: *const std::os::raw::c_char) -> *mut DetectUintData<u32> {
let raw: &CStr = CStr::from_ptr(raw); //unsafe
if let Ok(s) = raw.to_str() {
if let Some(ctx) = detect_parse_uint_enum::<u32, EnipStatus>(s) {
return std::ptr::null_mut();
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetCommand(
- tx: &mut EnipTransaction, direction: u8, value: *mut u16,
-) -> bool {
- let direction: Direction = direction.into();
- if direction == Direction::ToServer {
- if let Some(req) = &tx.request {
- *value = req.header.cmd;
- return true;
- }
- } else if let Some(resp) = &tx.response {
- *value = resp.header.cmd;
- return true;
- }
- return false;
-}
-
#[derive(Clone, Debug, Default)]
pub struct DetectCipServiceData {
pub service: u8,
));
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipParseCipService(raw: *const std::os::raw::c_char) -> *mut c_void {
- let raw: &CStr = CStr::from_ptr(raw); //unsafe
- if let Ok(s) = raw.to_str() {
- if let Ok((_, ctx)) = enip_parse_cip_service(s) {
- let boxed = Box::new(ctx);
- return Box::into_raw(boxed) as *mut _;
- }
- }
- return std::ptr::null_mut();
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipCipServiceFree(ctx: *mut c_void) {
- std::mem::drop(Box::from_raw(ctx as *mut DetectCipServiceData));
-}
-
fn enip_cip_has_attribute(cipdir: &CipDir, attr: u32) -> std::os::raw::c_int {
if let CipDir::Request(req) = cipdir {
for seg in req.path.iter() {
return 0;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxHasCipService(
- tx: &mut EnipTransaction, direction: u8, ctx: *const c_void,
-) -> std::os::raw::c_int {
- let ctx = cast_pointer!(ctx, DetectCipServiceData);
- return enip_tx_has_cip_service(tx, direction.into(), ctx);
-}
-
fn enip_cip_match_status(d: &CipData, ctx: &DetectUintData<u8>) -> std::os::raw::c_int {
if let CipDir::Response(resp) = &d.cipdir {
if detect_match_uint(ctx, resp.status) {
return 0;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxHasCipStatus(
- tx: &mut EnipTransaction, ctx: *const c_void,
-) -> std::os::raw::c_int {
- let ctx = cast_pointer!(ctx, DetectUintData<u8>);
- return enip_tx_has_cip_status(tx, ctx);
-}
-
fn enip_cip_match_extendedstatus(d: &CipData, ctx: &DetectUintData<u16>) -> std::os::raw::c_int {
if let CipDir::Response(resp) = &d.cipdir {
if resp.status_extended.len() == 2 {
return 0;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxHasCipExtendedstatus(
- tx: &mut EnipTransaction, ctx: *const c_void,
-) -> std::os::raw::c_int {
- let ctx = cast_pointer!(ctx, DetectUintData<u16>);
- return enip_tx_has_cip_extendedstatus(tx, ctx);
-}
-
fn enip_get_status(tx: &mut EnipTransaction, direction: Direction) -> Option<u32> {
if direction == Direction::ToServer {
if let Some(req) = &tx.request {
return 0;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxHasCipClass(
- tx: &mut EnipTransaction, ctx: *const c_void,
-) -> std::os::raw::c_int {
- let ctx = cast_pointer!(ctx, DetectUintData<u32>);
- return enip_tx_has_cip_segment(tx, ctx, 8);
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxHasCipInstance(
- tx: &mut EnipTransaction, ctx: *const c_void,
-) -> std::os::raw::c_int {
- let ctx = cast_pointer!(ctx, DetectUintData<u32>);
- return enip_tx_has_cip_segment(tx, ctx, 9);
-}
-
fn enip_cip_match_attribute(d: &CipData, ctx: &DetectUintData<u32>) -> std::os::raw::c_int {
if let CipDir::Request(req) = &d.cipdir {
for seg in req.path.iter() {
return 0;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxHasCipAttribute(
- tx: &mut EnipTransaction, ctx: *const c_void,
-) -> std::os::raw::c_int {
- let ctx = cast_pointer!(ctx, DetectUintData<u32>);
- return enip_tx_has_cip_attribute(tx, ctx);
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetStatus(
- tx: &mut EnipTransaction, direction: u8, value: *mut u32,
-) -> bool {
- if let Some(x) = enip_get_status(tx, direction.into()) {
- *value = x;
- return true;
- }
- return false;
-}
-
-fn enip_tx_get_protocol_version(tx: &mut EnipTransaction, direction: Direction) -> Option<u16> {
+fn tx_get_protocol_version(tx: &mut EnipTransaction, direction: Direction) -> Option<u16> {
if direction == Direction::ToServer {
if let Some(req) = &tx.request {
if let EnipPayload::RegisterSession(rs) = &req.payload {
return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetProtocolVersion(
- tx: &mut EnipTransaction, direction: u8, value: *mut u16,
-) -> bool {
- if let Some(val) = enip_tx_get_protocol_version(tx, direction.into()) {
- *value = val;
- return true;
+static mut G_ENIP_CIPSERVICE_KW_ID: c_int = 0;
+static mut G_ENIP_CIPSERVICE_BUFFER_ID: c_int = 0;
+static mut G_ENIP_CAPABILITIES_KW_ID: c_int = 0;
+static mut G_ENIP_CAPABILITIES_BUFFER_ID: c_int = 0;
+static mut G_ENIP_CIP_ATTRIBUTE_KW_ID: c_int = 0;
+static mut G_ENIP_CIP_ATTRIBUTE_BUFFER_ID: c_int = 0;
+static mut G_ENIP_CIP_CLASS_KW_ID: c_int = 0;
+static mut G_ENIP_CIP_CLASS_BUFFER_ID: c_int = 0;
+static mut G_ENIP_VENDOR_ID_KW_ID: c_int = 0;
+static mut G_ENIP_VENDOR_ID_BUFFER_ID: c_int = 0;
+static mut G_ENIP_STATUS_KW_ID: c_int = 0;
+static mut G_ENIP_STATUS_BUFFER_ID: c_int = 0;
+static mut G_ENIP_STATE_KW_ID: c_int = 0;
+static mut G_ENIP_STATE_BUFFER_ID: c_int = 0;
+static mut G_ENIP_SERIAL_KW_ID: c_int = 0;
+static mut G_ENIP_SERIAL_BUFFER_ID: c_int = 0;
+static mut G_ENIP_REVISION_KW_ID: c_int = 0;
+static mut G_ENIP_REVISION_BUFFER_ID: c_int = 0;
+static mut G_ENIP_PROTOCOL_VERSION_KW_ID: c_int = 0;
+static mut G_ENIP_PROTOCOL_VERSION_BUFFER_ID: c_int = 0;
+static mut G_ENIP_PRODUCT_CODE_KW_ID: c_int = 0;
+static mut G_ENIP_PRODUCT_CODE_BUFFER_ID: c_int = 0;
+static mut G_ENIP_IDENTITY_STATUS_KW_ID: c_int = 0;
+static mut G_ENIP_IDENTITY_STATUS_BUFFER_ID: c_int = 0;
+static mut G_ENIP_DEVICE_TYPE_KW_ID: c_int = 0;
+static mut G_ENIP_DEVICE_TYPE_BUFFER_ID: c_int = 0;
+static mut G_ENIP_COMMAND_KW_ID: c_int = 0;
+static mut G_ENIP_COMMAND_BUFFER_ID: c_int = 0;
+static mut G_ENIP_CIP_STATUS_KW_ID: c_int = 0;
+static mut G_ENIP_CIP_STATUS_BUFFER_ID: c_int = 0;
+static mut G_ENIP_CIP_INSTANCE_KW_ID: c_int = 0;
+static mut G_ENIP_CIP_INSTANCE_BUFFER_ID: c_int = 0;
+static mut G_ENIP_CIP_EXTENDEDSTATUS_KW_ID: c_int = 0;
+static mut G_ENIP_CIP_EXTENDEDSTATUS_BUFFER_ID: c_int = 0;
+static mut G_ENIP_PRODUCT_NAME_BUFFER_ID: c_int = 0;
+static mut G_ENIP_SERVICE_NAME_BUFFER_ID: c_int = 0;
+
+unsafe fn parse_cip_service(raw: *const std::os::raw::c_char) -> *mut c_void {
+ let raw: &CStr = CStr::from_ptr(raw); //unsafe
+ if let Ok(s) = raw.to_str() {
+ if let Ok((_, ctx)) = enip_parse_cip_service(s) {
+ let boxed = Box::new(ctx);
+ return Box::into_raw(boxed) as *mut _;
+ }
}
- return false;
+ return std::ptr::null_mut();
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetCapabilities(
- tx: &mut EnipTransaction, value: *mut u16,
-) -> bool {
+unsafe extern "C" fn cipservice_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = parse_cip_service(raw);
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CIPSERVICE_KW_ID,
+ ctx,
+ G_ENIP_CIPSERVICE_BUFFER_ID,
+ )
+ .is_null()
+ {
+ cipservice_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn cipservice_free(_de: *mut c_void, ctx: *mut c_void) {
+ std::mem::drop(Box::from_raw(ctx as *mut DetectCipServiceData));
+}
+
+unsafe extern "C" fn cipservice_match(
+ _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectCipServiceData);
+ return enip_tx_has_cip_service(tx, flags.into(), ctx);
+}
+
+unsafe extern "C" fn capabilities_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CAPABILITIES_KW_ID,
+ ctx,
+ G_ENIP_CAPABILITIES_BUFFER_ID,
+ )
+ .is_null()
+ {
+ capabilities_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_capabilities(tx: &mut EnipTransaction) -> Option<u16> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListServices(lsp) = &response.payload {
if !lsp.is_empty() {
if let EnipItemPayload::Services(ls) = &lsp[0].payload {
- *value = ls.capabilities;
- return true;
+ return Some(ls.capabilities);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetRevision(tx: &mut EnipTransaction, value: *mut u16) -> bool {
+unsafe extern "C" fn capabilities_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(v) = tx_get_capabilities(tx) {
+ return rs_detect_u16_match(v, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn capabilities_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn cip_attribute_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u32_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CIP_ATTRIBUTE_KW_ID,
+ ctx,
+ G_ENIP_CIP_ATTRIBUTE_BUFFER_ID,
+ )
+ .is_null()
+ {
+ cip_attribute_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn cip_attribute_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ return enip_tx_has_cip_attribute(tx, ctx);
+}
+
+unsafe extern "C" fn cip_attribute_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ rs_detect_u32_free(ctx);
+}
+
+unsafe extern "C" fn cip_class_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u32_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CIP_CLASS_KW_ID,
+ ctx,
+ G_ENIP_CIP_CLASS_BUFFER_ID,
+ )
+ .is_null()
+ {
+ cip_class_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn cip_class_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ return enip_tx_has_cip_segment(tx, ctx, 8);
+}
+
+unsafe extern "C" fn cip_class_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ rs_detect_u32_free(ctx);
+}
+
+unsafe extern "C" fn vendor_id_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_VENDOR_ID_KW_ID,
+ ctx,
+ G_ENIP_VENDOR_ID_BUFFER_ID,
+ )
+ .is_null()
+ {
+ vendor_id_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_vendor_id(tx: &mut EnipTransaction) -> Option<u16> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = ((li.revision_major as u16) << 8) | (li.revision_minor as u16);
- return true;
+ return Some(li.vendor_id);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetIdentityStatus(
- tx: &mut EnipTransaction, value: *mut u16,
-) -> bool {
+unsafe extern "C" fn vendor_id_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(val) = tx_get_vendor_id(tx) {
+ return rs_detect_u16_match(val, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn vendor_id_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn status_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = parse_status(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(de, s, G_ENIP_STATUS_KW_ID, ctx, G_ENIP_STATUS_BUFFER_ID).is_null() {
+ status_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn status_match(
+ _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ if let Some(x) = enip_get_status(tx, flags.into()) {
+ return rs_detect_u32_match(x, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn status_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ rs_detect_u32_free(ctx);
+}
+
+unsafe extern "C" fn state_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u8_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(de, s, G_ENIP_STATE_KW_ID, ctx, G_ENIP_STATE_BUFFER_ID).is_null() {
+ state_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_state(tx: &mut EnipTransaction) -> Option<u8> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = li.status;
- return true;
+ return Some(li.state);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetState(tx: &mut EnipTransaction, value: *mut u8) -> bool {
+unsafe extern "C" fn state_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u8>);
+ if let Some(val) = tx_get_state(tx) {
+ return rs_detect_u8_match(val, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn state_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u8>);
+ rs_detect_u8_free(ctx);
+}
+
+unsafe extern "C" fn serial_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u32_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(de, s, G_ENIP_SERIAL_KW_ID, ctx, G_ENIP_SERIAL_BUFFER_ID).is_null() {
+ serial_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_serial(tx: &mut EnipTransaction) -> Option<u32> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = li.state;
- return true;
+ return Some(li.serial);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetSerial(tx: &mut EnipTransaction, value: *mut u32) -> bool {
+unsafe extern "C" fn serial_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ if let Some(val) = tx_get_serial(tx) {
+ return rs_detect_u32_match(val, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn serial_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ rs_detect_u32_free(ctx);
+}
+
+unsafe extern "C" fn revision_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(de, s, G_ENIP_REVISION_KW_ID, ctx, G_ENIP_REVISION_BUFFER_ID)
+ .is_null()
+ {
+ revision_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_revision(tx: &mut EnipTransaction) -> Option<u16> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = li.serial;
- return true;
+ return Some(((li.revision_major as u16) << 8) | (li.revision_minor as u16));
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetProductCode(tx: &mut EnipTransaction, value: *mut u16) -> bool {
+unsafe extern "C" fn revision_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(val) = tx_get_revision(tx) {
+ return rs_detect_u16_match(val, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn revision_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn protocol_version_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_PROTOCOL_VERSION_KW_ID,
+ ctx,
+ G_ENIP_PROTOCOL_VERSION_BUFFER_ID,
+ )
+ .is_null()
+ {
+ protocol_version_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn protocol_version_match(
+ _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(val) = tx_get_protocol_version(tx, flags.into()) {
+ return rs_detect_u16_match(val, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn protocol_version_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn product_code_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_PRODUCT_CODE_KW_ID,
+ ctx,
+ G_ENIP_PRODUCT_CODE_BUFFER_ID,
+ )
+ .is_null()
+ {
+ product_code_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_product_code(tx: &mut EnipTransaction) -> Option<u16> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = li.product_code;
- return true;
+ return Some(li.product_code);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetDeviceType(tx: &mut EnipTransaction, value: *mut u16) -> bool {
+unsafe extern "C" fn product_code_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(v) = tx_get_product_code(tx) {
+ return rs_detect_u16_match(v, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn product_code_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn identity_status_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_IDENTITY_STATUS_KW_ID,
+ ctx,
+ G_ENIP_IDENTITY_STATUS_BUFFER_ID,
+ )
+ .is_null()
+ {
+ identity_status_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_identity_status(tx: &mut EnipTransaction) -> Option<u16> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = li.device_type;
- return true;
+ return Some(li.status);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetVendorId(tx: &mut EnipTransaction, value: *mut u16) -> bool {
+unsafe extern "C" fn identity_status_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(v) = tx_get_identity_status(tx) {
+ return rs_detect_u16_match(v, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn identity_status_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn device_type_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_DEVICE_TYPE_KW_ID,
+ ctx,
+ G_ENIP_DEVICE_TYPE_BUFFER_ID,
+ )
+ .is_null()
+ {
+ device_type_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_device_type(tx: &mut EnipTransaction) -> Option<u16> {
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
- *value = li.vendor_id;
- return true;
+ return Some(li.device_type);
}
}
}
}
- return false;
+ return None;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetProductName(
- tx: &EnipTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
-) -> u8 {
+unsafe extern "C" fn device_type_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(v) = tx_get_device_type(tx) {
+ return rs_detect_u16_match(v, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn device_type_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn command_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = parse_command(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(de, s, G_ENIP_COMMAND_KW_ID, ctx, G_ENIP_COMMAND_BUFFER_ID).is_null()
+ {
+ command_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+fn tx_get_command(tx: &mut EnipTransaction, direction: u8) -> Option<u16> {
+ let direction: Direction = direction.into();
+ if direction == Direction::ToServer {
+ if let Some(req) = &tx.request {
+ return Some(req.header.cmd);
+ }
+ } else if let Some(resp) = &tx.response {
+ return Some(resp.header.cmd);
+ }
+ return None;
+}
+
+unsafe extern "C" fn command_match(
+ _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ if let Some(v) = tx_get_command(tx, flags) {
+ return rs_detect_u16_match(v, ctx);
+ }
+ return 0;
+}
+
+unsafe extern "C" fn command_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+unsafe extern "C" fn cip_status_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u8_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CIP_STATUS_KW_ID,
+ ctx,
+ G_ENIP_CIP_STATUS_BUFFER_ID,
+ )
+ .is_null()
+ {
+ cip_status_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn cip_status_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u8>);
+ return enip_tx_has_cip_status(tx, ctx);
+}
+
+unsafe extern "C" fn cip_status_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u8>);
+ rs_detect_u8_free(ctx);
+}
+
+unsafe extern "C" fn cip_instance_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u32_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CIP_INSTANCE_KW_ID,
+ ctx,
+ G_ENIP_CIP_INSTANCE_BUFFER_ID,
+ )
+ .is_null()
+ {
+ cip_instance_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn cip_instance_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ return enip_tx_has_cip_segment(tx, ctx, 9);
+}
+
+unsafe extern "C" fn cip_instance_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u32>);
+ rs_detect_u32_free(ctx);
+}
+
+unsafe extern "C" fn cip_extendedstatus_setup(
+ de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ let ctx = rs_detect_u16_parse(raw) as *mut c_void;
+ if ctx.is_null() {
+ return -1;
+ }
+ if SigMatchAppendSMToList(
+ de,
+ s,
+ G_ENIP_CIP_EXTENDEDSTATUS_KW_ID,
+ ctx,
+ G_ENIP_CIP_EXTENDEDSTATUS_BUFFER_ID,
+ )
+ .is_null()
+ {
+ cip_extendedstatus_free(std::ptr::null_mut(), ctx);
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn cip_extendedstatus_match(
+ _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void,
+ _sig: *const c_void, ctx: *const c_void,
+) -> c_int {
+ let tx = cast_pointer!(tx, EnipTransaction);
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ return enip_tx_has_cip_extendedstatus(tx, ctx);
+}
+
+unsafe extern "C" fn cip_extendedstatus_free(_de: *mut c_void, ctx: *mut c_void) {
+ // Just unbox...
+ let ctx = cast_pointer!(ctx, DetectUintData<u16>);
+ rs_detect_u16_free(ctx);
+}
+
+pub unsafe extern "C" fn product_name_setup(
+ de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ if DetectBufferSetActiveList(de, s, G_ENIP_PRODUCT_NAME_BUFFER_ID) < 0 {
+ return -1;
+ }
+ return 0;
+}
+
+unsafe extern "C" fn product_name_get(
+ tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32,
+) -> bool {
+ let tx = cast_pointer!(tx, EnipTransaction);
if let Some(ref response) = tx.response {
if let EnipPayload::ListIdentity(lip) = &response.payload {
if !lip.is_empty() {
if let EnipItemPayload::Identity(li) = &lip[0].payload {
*buffer = li.product_name.as_ptr();
*buffer_len = li.product_name.len() as u32;
- return 1;
+ return true;
}
}
}
}
-
*buffer = std::ptr::null();
*buffer_len = 0;
+ return false;
+}
+
+unsafe extern "C" fn product_name_get_data(
+ de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,
+ tx: *const c_void, list_id: c_int,
+) -> *mut c_void {
+ return DetectHelperGetData(
+ de,
+ transforms,
+ flow,
+ flow_flags,
+ tx,
+ list_id,
+ product_name_get,
+ );
+}
+
+pub unsafe extern "C" fn service_name_setup(
+ de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char,
+) -> c_int {
+ if DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0 {
+ return -1;
+ }
+ if DetectBufferSetActiveList(de, s, G_ENIP_SERVICE_NAME_BUFFER_ID) < 0 {
+ return -1;
+ }
return 0;
}
-#[no_mangle]
-pub unsafe extern "C" fn SCEnipTxGetServiceName(
- tx: &EnipTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
-) -> u8 {
+unsafe extern "C" fn service_name_get(
+ tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32,
+) -> bool {
+ let tx = cast_pointer!(tx, EnipTransaction);
if let Some(ref response) = tx.response {
if let EnipPayload::ListServices(lsp) = &response.payload {
if !lsp.is_empty() {
if let EnipItemPayload::Services(ls) = &lsp[0].payload {
*buffer = ls.service_name.as_ptr();
*buffer_len = ls.service_name.len() as u32;
- return 1;
+ return true;
}
}
}
}
-
*buffer = std::ptr::null();
*buffer_len = 0;
- return 0;
+ return false;
+}
+
+unsafe extern "C" fn service_name_get_data(
+ de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,
+ tx: *const c_void, list_id: c_int,
+) -> *mut c_void {
+ return DetectHelperGetData(
+ de,
+ transforms,
+ flow,
+ flow_flags,
+ tx,
+ list_id,
+ service_name_get,
+ );
+}
+#[no_mangle]
+pub unsafe extern "C" fn ScDetectEnipRegister() {
+ let kw = SCSigTableElmt {
+ name: b"cip_service\0".as_ptr() as *const libc::c_char,
+ desc: b"match on CIP Service, and optionnally class and attribute\0".as_ptr()
+ as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#cip_service\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(cipservice_match),
+ Setup: cipservice_setup,
+ Free: Some(cipservice_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CIPSERVICE_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CIPSERVICE_BUFFER_ID = DetectHelperBufferRegister(
+ b"cip\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.capabilities\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP capabilities\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-capabilities\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(capabilities_match),
+ Setup: capabilities_setup,
+ Free: Some(capabilities_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CAPABILITIES_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CAPABILITIES_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.capabilities\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.cip_attribute\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP cip_attribute\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-cip-attribute\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(cip_attribute_match),
+ Setup: cip_attribute_setup,
+ Free: Some(cip_attribute_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CIP_ATTRIBUTE_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CIP_ATTRIBUTE_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.cip_attribute\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.cip_class\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP cip_class\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-cip-class\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(cip_class_match),
+ Setup: cip_class_setup,
+ Free: Some(cip_class_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CIP_CLASS_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CIP_CLASS_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.cip_class\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.vendor_id\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP vendor_id\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-vendor-id\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(vendor_id_match),
+ Setup: vendor_id_setup,
+ Free: Some(vendor_id_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_VENDOR_ID_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_VENDOR_ID_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.vendor_id\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.status\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP status\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-status\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(status_match),
+ Setup: status_setup,
+ Free: Some(status_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_STATUS_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_STATUS_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.status\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.state\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP state\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-state\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(state_match),
+ Setup: state_setup,
+ Free: Some(state_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_STATE_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_STATE_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.state\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.serial\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP serial\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-serial\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(serial_match),
+ Setup: serial_setup,
+ Free: Some(serial_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_SERIAL_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_SERIAL_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.serial\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.revision\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP revision\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-revision\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(revision_match),
+ Setup: revision_setup,
+ Free: Some(revision_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_REVISION_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_REVISION_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.revision\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.protocol_version\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP protocol_version\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-protocol-version\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(protocol_version_match),
+ Setup: protocol_version_setup,
+ Free: Some(protocol_version_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_PROTOCOL_VERSION_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_PROTOCOL_VERSION_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.protocol_version\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.product_code\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP product_code\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-product-code\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(product_code_match),
+ Setup: product_code_setup,
+ Free: Some(product_code_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_PRODUCT_CODE_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_PRODUCT_CODE_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.product_code\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip_command\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP command\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip_command\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(command_match),
+ Setup: command_setup,
+ Free: Some(command_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_COMMAND_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_COMMAND_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.command\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.identity_status\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP identity_status\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-identity-status\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(identity_status_match),
+ Setup: identity_status_setup,
+ Free: Some(identity_status_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_IDENTITY_STATUS_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_IDENTITY_STATUS_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.identity_status\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.device_type\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP device_type\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-device-type\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(device_type_match),
+ Setup: device_type_setup,
+ Free: Some(device_type_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_DEVICE_TYPE_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_DEVICE_TYPE_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.device_type\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip_command\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP command\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip_command\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(command_match),
+ Setup: command_setup,
+ Free: Some(command_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_COMMAND_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_COMMAND_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.command\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.cip_status\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP cip_status\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-cip-status\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(cip_status_match),
+ Setup: cip_status_setup,
+ Free: Some(cip_status_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CIP_STATUS_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CIP_STATUS_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.cip_status\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.cip_instance\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP cip_instance\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-cip-instance\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(cip_instance_match),
+ Setup: cip_instance_setup,
+ Free: Some(cip_instance_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CIP_INSTANCE_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CIP_INSTANCE_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.cip_instance\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.cip_extendedstatus\0".as_ptr() as *const libc::c_char,
+ desc: b"rules for detecting EtherNet/IP cip_extendedstatus\0".as_ptr()
+ as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-cip-extendedstatus\0".as_ptr() as *const libc::c_char,
+ AppLayerTxMatch: Some(cip_extendedstatus_match),
+ Setup: cip_extendedstatus_setup,
+ Free: Some(cip_extendedstatus_free),
+ flags: 0,
+ };
+ unsafe {
+ G_ENIP_CIP_EXTENDEDSTATUS_KW_ID = DetectHelperKeywordRegister(&kw);
+ G_ENIP_CIP_EXTENDEDSTATUS_BUFFER_ID = DetectHelperBufferRegister(
+ b"enip.cip_extendedstatus\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.product_name\0".as_ptr() as *const libc::c_char,
+ desc: b"sticky buffer to match EtherNet/IP product name\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-product-name\0".as_ptr() as *const libc::c_char,
+ Setup: product_name_setup,
+ flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
+ AppLayerTxMatch: None,
+ Free: None,
+ };
+ unsafe {
+ let _g_enip_product_name_kw_id = DetectHelperKeywordRegister(&kw);
+ G_ENIP_PRODUCT_NAME_BUFFER_ID = DetectHelperBufferMpmRegister(
+ b"enip.product_name\0".as_ptr() as *const libc::c_char,
+ b"ENIP product name\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ product_name_get_data,
+ );
+ }
+ let kw = SCSigTableElmt {
+ name: b"enip.service_name\0".as_ptr() as *const libc::c_char,
+ desc: b"sticky buffer to match EtherNet/IP service name\0".as_ptr() as *const libc::c_char,
+ url: b"/rules/enip-keyword.html#enip-service-name\0".as_ptr() as *const libc::c_char,
+ Setup: service_name_setup,
+ flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
+ AppLayerTxMatch: None,
+ Free: None,
+ };
+ unsafe {
+ let _g_enip_service_name_kw_id = DetectHelperKeywordRegister(&kw);
+ G_ENIP_SERVICE_NAME_BUFFER_ID = DetectHelperBufferMpmRegister(
+ b"enip.service_name\0".as_ptr() as *const libc::c_char,
+ b"ENIP service name\0".as_ptr() as *const libc::c_char,
+ ALPROTO_ENIP,
+ true,
+ true,
+ service_name_get_data,
+ );
+ }
}
#[cfg(test)]
use std::ffi::CString;
use std::os::raw::{c_char, c_int, c_void};
-static mut ALPROTO_ENIP: AppProto = ALPROTO_UNKNOWN;
+pub(super) static mut ALPROTO_ENIP: AppProto = ALPROTO_UNKNOWN;
static mut ENIP_MAX_TX: usize = 1024;
detect-bytejump.h \
detect-bytemath.h \
detect-bytetest.h \
- detect-cipservice.h \
detect-classtype.h \
detect-config.h \
detect-content.h \
detect-engine-tag.h \
detect-engine-threshold.h \
detect-engine-uint.h \
- detect-enip-command.h \
- detect-enip-status.h \
- detect-enip-product-name.h \
- detect-enip-protocol-version.h \
- detect-enip-cip-attribute.h \
- detect-enip-cip-instance.h \
- detect-enip-cip-class.h \
- detect-enip-cip-extendedstatus.h \
- detect-enip-cip-status.h \
- detect-enip-service-name.h \
- detect-enip-capabilities.h \
- detect-enip-revision.h \
- detect-enip-identity-status.h \
- detect-enip-state.h \
- detect-enip-serial.h \
- detect-enip-product-code.h \
- detect-enip-device-type.h \
- detect-enip-vendor-id.h \
detect-fast-pattern.h \
detect-file-data.h \
detect-file-hash-common.h \
detect-bytemath.c \
detect-bytetest.c \
detect.c \
- detect-cipservice.c \
detect-classtype.c \
detect-config.c \
detect-content.c \
detect-engine-tag.c \
detect-engine-threshold.c \
detect-engine-uint.c \
- detect-enip-command.c \
- detect-enip-status.c \
- detect-enip-product-name.c \
- detect-enip-protocol-version.c \
- detect-enip-cip-attribute.c \
- detect-enip-cip-instance.c \
- detect-enip-cip-class.c \
- detect-enip-cip-extendedstatus.c \
- detect-enip-cip-status.c \
- detect-enip-service-name.c \
- detect-enip-capabilities.c \
- detect-enip-revision.c \
- detect-enip-identity-status.c \
- detect-enip-state.c \
- detect-enip-serial.c \
- detect-enip-product-code.c \
- detect-enip-device-type.c \
- detect-enip-vendor-id.c \
detect-fast-pattern.c \
detect-file-data.c \
detect-file-hash-common.c \
+++ /dev/null
-/* Copyright (C) 2015 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Kevin Wong <kwong@solananetworks.com>
- *
- * Set up ENIP Command and CIP Service rule parsing and entry point for matching
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "rust.h"
-
-#include "detect-cipservice.h"
-
-/*
- * CIP SERVICE CODE
- */
-
-static int g_cip_buffer_id = 0;
-
-/**
- * \brief this function will free memory associated with DetectCipServiceData
- *
- * \param ptr pointer to DetectCipServiceData
- */
-static void DetectCipServiceFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- SCEnipCipServiceFree(ptr);
-}
-
-/**
- * \brief this function is used to a cipserviced the parsed cip_service data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided cip_service options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectCipServiceSetup(DetectEngineCtx *de_ctx, Signature *s,
- const char *rulestr)
-{
- SCEnter();
-
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- void *cipserviced = SCEnipParseCipService(rulestr);
- if (cipserviced == NULL)
- return -1;
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_CIPSERVICE, (SigMatchCtx *)cipserviced,
- g_cip_buffer_id) == NULL) {
- DetectCipServiceFree(de_ctx, cipserviced);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip command type rule option on a transaction with those
- * passed via enip_command:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectCipServiceMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- return SCEnipTxHasCipService(txv, flags, ctx);
-}
-
-/**
- * \brief Registration function for cip_service: keyword
- */
-void DetectCipServiceRegister(void)
-{
- SCEnter();
- sigmatch_table[DETECT_CIPSERVICE].name = "cip_service"; // rule keyword
- sigmatch_table[DETECT_CIPSERVICE].desc =
- "match on CIP Service, and optionnally class and attribute";
- sigmatch_table[DETECT_CIPSERVICE].url = "/rules/enip-keyword.html#cip_service";
- sigmatch_table[DETECT_CIPSERVICE].Match = NULL;
- sigmatch_table[DETECT_CIPSERVICE].AppLayerTxMatch = DetectCipServiceMatch;
- sigmatch_table[DETECT_CIPSERVICE].Setup = DetectCipServiceSetup;
- sigmatch_table[DETECT_CIPSERVICE].Free = DetectCipServiceFree;
-
- DetectAppLayerInspectEngineRegister(
- "cip", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister(
- "cip", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
-
- g_cip_buffer_id = DetectBufferTypeGetByName("cip");
-
- SCReturn;
-}
+++ /dev/null
-/* Copyright (C) 2015-2022 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Kevin Wong <kwong@solananetworks.com>
- */
-
-#ifndef SURICATA_DETECT_CIPSERVICE_H
-#define SURICATA_DETECT_CIPSERVICE_H
-
-void DetectCipServiceRegister(void);
-
-#endif /* SURICATA_DETECT_CIPSERVICE_H */
#include "detect-ssl-version.h"
#include "detect-ssl-state.h"
#include "detect-modbus.h"
-#include "detect-cipservice.h"
-#include "detect-enip-command.h"
-#include "detect-enip-status.h"
-#include "detect-enip-product-name.h"
-#include "detect-enip-protocol-version.h"
-#include "detect-enip-cip-attribute.h"
-#include "detect-enip-cip-instance.h"
-#include "detect-enip-cip-class.h"
-#include "detect-enip-cip-extendedstatus.h"
-#include "detect-enip-cip-status.h"
-#include "detect-enip-service-name.h"
-#include "detect-enip-capabilities.h"
-#include "detect-enip-revision.h"
-#include "detect-enip-identity-status.h"
-#include "detect-enip-state.h"
-#include "detect-enip-serial.h"
-#include "detect-enip-product-code.h"
-#include "detect-enip-device-type.h"
-#include "detect-enip-vendor-id.h"
#include "detect-dnp3.h"
#include "detect-ike-exch-type.h"
#include "detect-ike-spi.h"
DetectDnsAnswerNameRegister();
DetectDnsQueryNameRegister();
DetectModbusRegister();
- DetectCipServiceRegister();
- DetectEnipCommandRegister();
- DetectEnipStatusRegister();
- DetectEnipProductNameRegister();
- DetectEnipProtocolVersionRegister();
- DetectEnipCipAttributeRegister();
- DetectEnipCipInstanceRegister();
- DetectEnipCipClassRegister();
- DetectEnipCipExtendedstatusRegister();
- DetectEnipCipStatusRegister();
- DetectEnipServiceNameRegister();
- DetectEnipCapabilitiesRegister();
- DetectEnipRevisionRegister();
- DetectEnipIdentityStatusRegister();
- DetectEnipStateRegister();
- DetectEnipSerialRegister();
- DetectEnipProductCodeRegister();
- DetectEnipDeviceTypeRegister();
- DetectEnipVendorIdRegister();
DetectDNP3Register();
DetectIkeExchTypeRegister();
ScDetectSNMPRegister();
ScDetectDHCPRegister();
ScDetectWebsocketRegister();
+ ScDetectEnipRegister();
/* close keyword registration */
DetectBufferTypeCloseRegistration();
DETECT_AL_TLS_JA3S_STRING,
DETECT_AL_MODBUS,
- DETECT_CIPSERVICE,
- DETECT_ENIPCOMMAND,
- DETECT_ENIPSTATUS,
- DETECT_ENIP_PRODUCTNAME,
- DETECT_ENIP_PROTOCOLVERSION,
- DETECT_ENIP_CIPATTRIBUTE,
- DETECT_ENIP_CIPINSTANCE,
- DETECT_ENIP_CIPCLASS,
- DETECT_ENIP_CIPEXTENDEDSTATUS,
- DETECT_ENIP_CIPSTATUS,
- DETECT_ENIP_SERVICENAME,
- DETECT_ENIP_CAPABILITIES,
- DETECT_ENIP_REVISION,
- DETECT_ENIP_IDENTITYSTATUS,
- DETECT_ENIP_STATE,
- DETECT_ENIP_SERIAL,
- DETECT_ENIP_PRODUCTCODE,
- DETECT_ENIP_DEVICETYPE,
- DETECT_ENIP_VENDORID,
DETECT_AL_DNP3DATA,
DETECT_AL_DNP3FUNC,
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP capabilities keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-capabilities.h"
-
-static int g_enip_capabilities_id = 0;
-
-static void DetectEnipCapabilitiesFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_capabilities data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip capabilities options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCapabilitiesSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_CAPABILITIES, (SigMatchCtx *)du16,
- g_enip_capabilities_id) == NULL) {
- DetectEnipCapabilitiesFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip capabilities type rule option on a transaction
- * with those passed via enip_capabilities:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCapabilitiesMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetCapabilities(txv, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_capabilities: keyword
- */
-void DetectEnipCapabilitiesRegister(void)
-{
- sigmatch_table[DETECT_ENIP_CAPABILITIES].name = "enip.capabilities"; // rule keyword
- sigmatch_table[DETECT_ENIP_CAPABILITIES].desc = "rules for detecting EtherNet/IP capabilities";
- sigmatch_table[DETECT_ENIP_CAPABILITIES].url = "/rules/enip-keyword.html#enip-capabilities";
- sigmatch_table[DETECT_ENIP_CAPABILITIES].Match = NULL;
- sigmatch_table[DETECT_ENIP_CAPABILITIES].AppLayerTxMatch = DetectEnipCapabilitiesMatch;
- sigmatch_table[DETECT_ENIP_CAPABILITIES].Setup = DetectEnipCapabilitiesSetup;
- sigmatch_table[DETECT_ENIP_CAPABILITIES].Free = DetectEnipCapabilitiesFree;
-
- DetectAppLayerInspectEngineRegister("enip.capabilities", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.capabilities", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_capabilities_id = DetectBufferTypeGetByName("enip.capabilities");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_CAPABILITIES_H
-#define SURICATA_DETECT_ENIP_CAPABILITIES_H
-
-void DetectEnipCapabilitiesRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_CAPABILITIES_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP cip attribute keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-cip-attribute.h"
-
-static int g_enip_cip_attribute_id = 0;
-
-static void DetectEnipCipAttributeFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u32_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_cip_attribute data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip cip_attribute options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCipAttributeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU32Data *du32 = DetectU32Parse(rulestr);
- if (du32 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_CIPATTRIBUTE, (SigMatchCtx *)du32,
- g_enip_cip_attribute_id) == NULL) {
- DetectEnipCipAttributeFree(de_ctx, du32);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip cip_attribute type rule option on a transaction
- * with those passed via enip_cip_attribute:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCipAttributeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- return SCEnipTxHasCipAttribute(txv, ctx);
-}
-
-/**
- * \brief Registration function for enip_cip_attribute: keyword
- */
-void DetectEnipCipAttributeRegister(void)
-{
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].name = "enip.cip_attribute"; // rule keyword
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].desc = "rules for detecting EtherNet/IP cip_attribute";
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].url = "/rules/enip-keyword.html#enip-cip-attribute";
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].Match = NULL;
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].AppLayerTxMatch = DetectEnipCipAttributeMatch;
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].Setup = DetectEnipCipAttributeSetup;
- sigmatch_table[DETECT_ENIP_CIPATTRIBUTE].Free = DetectEnipCipAttributeFree;
-
- DetectAppLayerInspectEngineRegister("enip.cip_attribute", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.cip_attribute", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_cip_attribute_id = DetectBufferTypeGetByName("enip.cip_attribute");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_CIP_ATTRIBUTE_H
-#define SURICATA_DETECT_ENIP_CIP_ATTRIBUTE_H
-
-void DetectEnipCipAttributeRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_CIP_ATTRIBUTE_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP cip class keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-cip-class.h"
-
-static int g_enip_cip_class_id = 0;
-
-static void DetectEnipCipClassFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u32_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_cip_class data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip cip_class options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCipClassSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- SCReturnInt(-1);
-
- DetectU32Data *du32 = DetectU32Parse(rulestr);
- if (du32 == NULL)
- SCReturnInt(-1);
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_CIPCLASS, (SigMatchCtx *)du32,
- g_enip_cip_class_id) == NULL) {
- DetectEnipCipClassFree(de_ctx, du32);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip cip_class type rule option on a transaction
- * with those passed via enip_cip_class:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCipClassMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- return SCEnipTxHasCipClass(txv, ctx);
-}
-
-/**
- * \brief Registration function for enip_cip_class: keyword
- */
-void DetectEnipCipClassRegister(void)
-{
- sigmatch_table[DETECT_ENIP_CIPCLASS].name = "enip.cip_class"; // rule keyword
- sigmatch_table[DETECT_ENIP_CIPCLASS].desc = "rules for detecting EtherNet/IP cip_class";
- sigmatch_table[DETECT_ENIP_CIPCLASS].url = "/rules/enip-keyword.html#enip-cip-class";
- sigmatch_table[DETECT_ENIP_CIPCLASS].Match = NULL;
- sigmatch_table[DETECT_ENIP_CIPCLASS].AppLayerTxMatch = DetectEnipCipClassMatch;
- sigmatch_table[DETECT_ENIP_CIPCLASS].Setup = DetectEnipCipClassSetup;
- sigmatch_table[DETECT_ENIP_CIPCLASS].Free = DetectEnipCipClassFree;
-
- DetectAppLayerInspectEngineRegister("enip.cip_class", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.cip_class", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_cip_class_id = DetectBufferTypeGetByName("enip.cip_class");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_CIP_CLASS_H
-#define SURICATA_DETECT_ENIP_CIP_CLASS_H
-
-void DetectEnipCipClassRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_CIP_CLASS_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP cip extendedstatus keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-cip-extendedstatus.h"
-
-static int g_enip_cip_extendedstatus_id = 0;
-
-static void DetectEnipCipExtendedstatusFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_cip_extendedstatus data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip cip_extendedstatus options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCipExtendedstatusSetup(
- DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_CIPEXTENDEDSTATUS, (SigMatchCtx *)du16,
- g_enip_cip_extendedstatus_id) == NULL) {
- DetectEnipCipExtendedstatusFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip cip_extendedstatus type rule option on a transaction
- * with those passed via enip_cip_extendedstatus:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCipExtendedstatusMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- return SCEnipTxHasCipExtendedstatus(txv, ctx);
-}
-
-/**
- * \brief Registration function for enip_cip_extendedstatus: keyword
- */
-void DetectEnipCipExtendedstatusRegister(void)
-{
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].name = "enip.cip_extendedstatus"; // rule keyword
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].desc =
- "rules for detecting EtherNet/IP cip_extendedstatus";
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].url =
- "/rules/enip-keyword.html#enip-cip-extendedstatus";
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].Match = NULL;
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].AppLayerTxMatch =
- DetectEnipCipExtendedstatusMatch;
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].Setup = DetectEnipCipExtendedstatusSetup;
- sigmatch_table[DETECT_ENIP_CIPEXTENDEDSTATUS].Free = DetectEnipCipExtendedstatusFree;
-
- DetectAppLayerInspectEngineRegister("enip.cip_extendedstatus", ALPROTO_ENIP, SIG_FLAG_TOSERVER,
- 0, DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.cip_extendedstatus", ALPROTO_ENIP, SIG_FLAG_TOCLIENT,
- 0, DetectEngineInspectGenericList, NULL);
-
- g_enip_cip_extendedstatus_id = DetectBufferTypeGetByName("enip.cip_extendedstatus");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_CIP_EXTENDEDSTATUS_H
-#define SURICATA_DETECT_ENIP_CIP_EXTENDEDSTATUS_H
-
-void DetectEnipCipExtendedstatusRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_CIP_EXTENDEDSTATUS_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP cip instance keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-cip-instance.h"
-
-static int g_enip_cip_instance_id = 0;
-
-static void DetectEnipCipInstanceFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u32_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_cip_instance data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip cip_instance options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCipInstanceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU32Data *du32 = DetectU32Parse(rulestr);
- if (du32 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_CIPINSTANCE, (SigMatchCtx *)du32,
- g_enip_cip_instance_id) == NULL) {
- DetectEnipCipInstanceFree(de_ctx, du32);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip cip_instance type rule option on a transaction
- * with those passed via enip_cip_instance:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCipInstanceMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- return SCEnipTxHasCipInstance(txv, ctx);
-}
-
-/**
- * \brief Registration function for enip_cip_instance: keyword
- */
-void DetectEnipCipInstanceRegister(void)
-{
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].name = "enip.cip_instance"; // rule keyword
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].desc = "rules for detecting EtherNet/IP cip_instance";
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].url = "/rules/enip-keyword.html#enip-cip-instance";
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].Match = NULL;
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].AppLayerTxMatch = DetectEnipCipInstanceMatch;
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].Setup = DetectEnipCipInstanceSetup;
- sigmatch_table[DETECT_ENIP_CIPINSTANCE].Free = DetectEnipCipInstanceFree;
-
- DetectAppLayerInspectEngineRegister("enip.cip_instance", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.cip_instance", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_cip_instance_id = DetectBufferTypeGetByName("enip.cip_instance");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_CIP_INSTANCE_H
-#define SURICATA_DETECT_ENIP_CIP_INSTANCE_H
-
-void DetectEnipCipInstanceRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_CIP_INSTANCE_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP cip status keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-cip-status.h"
-
-static int g_enip_cip_status_id = 0;
-
-static void DetectEnipCipStatusFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u8_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_cip_status data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip cip_status options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCipStatusSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU8Data *du8 = DetectU8Parse(rulestr);
- if (du8 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_CIPSTATUS, (SigMatchCtx *)du8,
- g_enip_cip_status_id) == NULL) {
- DetectEnipCipStatusFree(de_ctx, du8);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip cip_status type rule option on a transaction
- * with those passed via enip_cip_status:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCipStatusMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- return SCEnipTxHasCipStatus(txv, ctx);
-}
-
-/**
- * \brief Registration function for enip_cip_status: keyword
- */
-void DetectEnipCipStatusRegister(void)
-{
- sigmatch_table[DETECT_ENIP_CIPSTATUS].name = "enip.cip_status"; // rule keyword
- sigmatch_table[DETECT_ENIP_CIPSTATUS].desc = "rules for detecting EtherNet/IP cip_status";
- sigmatch_table[DETECT_ENIP_CIPSTATUS].url = "/rules/enip-keyword.html#enip-cip-status";
- sigmatch_table[DETECT_ENIP_CIPSTATUS].Match = NULL;
- sigmatch_table[DETECT_ENIP_CIPSTATUS].AppLayerTxMatch = DetectEnipCipStatusMatch;
- sigmatch_table[DETECT_ENIP_CIPSTATUS].Setup = DetectEnipCipStatusSetup;
- sigmatch_table[DETECT_ENIP_CIPSTATUS].Free = DetectEnipCipStatusFree;
-
- DetectAppLayerInspectEngineRegister("enip.cip_status", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.cip_status", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_cip_status_id = DetectBufferTypeGetByName("enip.cip_status");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_CIP_STATUS_H
-#define SURICATA_DETECT_ENIP_CIP_STATUS_H
-
-void DetectEnipCipStatusRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_CIP_STATUS_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP Command rule parsing and entry point for matching
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-command.h"
-
-static int g_enip_buffer_id = 0;
-
-/**
- * \brief this function will free memory associated
- *
- * \param ptr pointer to u16
- */
-static void DetectEnipCommandFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used by enipcmdd to parse enip_command data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip command options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipCommandSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *enipcmdd = SCEnipParseCommand(rulestr);
- if (enipcmdd == NULL) {
- SCLogWarning("rule %u has invalid value for enip_command %s", s->id, rulestr);
- return -1;
- }
-
- if (SigMatchAppendSMToList(
- de_ctx, s, DETECT_ENIPCOMMAND, (SigMatchCtx *)enipcmdd, g_enip_buffer_id) == NULL) {
- DetectEnipCommandFree(de_ctx, enipcmdd);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip command type rule option on a transaction with those
- * passed via enip_command:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipCommandMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetCommand(txv, flags, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_command: keyword
- */
-void DetectEnipCommandRegister(void)
-{
- sigmatch_table[DETECT_ENIPCOMMAND].name = "enip_command"; // rule keyword
- sigmatch_table[DETECT_ENIPCOMMAND].desc = "rules for detecting EtherNet/IP command";
- sigmatch_table[DETECT_ENIPCOMMAND].url = "/rules/enip-keyword.html#enip_command";
- sigmatch_table[DETECT_ENIPCOMMAND].Match = NULL;
- sigmatch_table[DETECT_ENIPCOMMAND].AppLayerTxMatch = DetectEnipCommandMatch;
- sigmatch_table[DETECT_ENIPCOMMAND].Setup = DetectEnipCommandSetup;
- sigmatch_table[DETECT_ENIPCOMMAND].Free = DetectEnipCommandFree;
-
- DetectAppLayerInspectEngineRegister(
- "enip", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister(
- "enip", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
-
- g_enip_buffer_id = DetectBufferTypeGetByName("enip");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_COMMAND_H
-#define SURICATA_DETECT_ENIP_COMMAND_H
-
-void DetectEnipCommandRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_COMMAND_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP device type keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-device-type.h"
-
-static int g_enip_device_type_id = 0;
-
-static void DetectEnipDeviceTypeFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_device_type data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip device_type options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipDeviceTypeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_DEVICETYPE, (SigMatchCtx *)du16,
- g_enip_device_type_id) == NULL) {
- DetectEnipDeviceTypeFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip device_type type rule option on a transaction with
- * those passed via enip_device_type:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipDeviceTypeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetDeviceType(txv, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_device_type: keyword
- */
-void DetectEnipDeviceTypeRegister(void)
-{
- sigmatch_table[DETECT_ENIP_DEVICETYPE].name = "enip.device_type"; // rule keyword
- sigmatch_table[DETECT_ENIP_DEVICETYPE].desc = "rules for detecting EtherNet/IP device_type";
- sigmatch_table[DETECT_ENIP_DEVICETYPE].url = "/rules/enip-keyword.html#enip-device-type";
- sigmatch_table[DETECT_ENIP_DEVICETYPE].Match = NULL;
- sigmatch_table[DETECT_ENIP_DEVICETYPE].AppLayerTxMatch = DetectEnipDeviceTypeMatch;
- sigmatch_table[DETECT_ENIP_DEVICETYPE].Setup = DetectEnipDeviceTypeSetup;
- sigmatch_table[DETECT_ENIP_DEVICETYPE].Free = DetectEnipDeviceTypeFree;
-
- DetectAppLayerInspectEngineRegister("enip.device_type", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.device_type", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_device_type_id = DetectBufferTypeGetByName("enip.device_type");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_DEVICE_TYPE_H
-#define SURICATA_DETECT_ENIP_DEVICE_TYPE_H
-
-void DetectEnipDeviceTypeRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_DEVICE_TYPE_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP identity status keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-identity-status.h"
-
-static int g_enip_identity_status_id = 0;
-
-static void DetectEnipIdentityStatusFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_identity_status data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip identity_status options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipIdentityStatusSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_IDENTITYSTATUS, (SigMatchCtx *)du16,
- g_enip_identity_status_id) == NULL) {
- DetectEnipIdentityStatusFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip identity_status type rule option on a transaction with
- * those passed via enip_identity_status:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipIdentityStatusMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetIdentityStatus(txv, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_identity_status: keyword
- */
-void DetectEnipIdentityStatusRegister(void)
-{
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].name = "enip.identity_status"; // rule keyword
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].desc =
- "rules for detecting EtherNet/IP identity_status";
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].url =
- "/rules/enip-keyword.html#enip-identity-status";
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].Match = NULL;
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].AppLayerTxMatch = DetectEnipIdentityStatusMatch;
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].Setup = DetectEnipIdentityStatusSetup;
- sigmatch_table[DETECT_ENIP_IDENTITYSTATUS].Free = DetectEnipIdentityStatusFree;
-
- DetectAppLayerInspectEngineRegister("enip.identity_status", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.identity_status", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_identity_status_id = DetectBufferTypeGetByName("enip.identity_status");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_IDENTITY_STATUS_H
-#define SURICATA_DETECT_ENIP_IDENTITY_STATUS_H
-
-void DetectEnipIdentityStatusRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_IDENTITY_STATUS_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP product code keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-product-code.h"
-
-static int g_enip_product_code_id = 0;
-
-static void DetectEnipProductCodeFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_product_code data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip product_code options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipProductCodeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_PRODUCTCODE, (SigMatchCtx *)du16,
- g_enip_product_code_id) == NULL) {
- DetectEnipProductCodeFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip product_code type rule option on a transaction with
- * those passed via enip_product_code:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipProductCodeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetProductCode(txv, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_product_code: keyword
- */
-void DetectEnipProductCodeRegister(void)
-{
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].name = "enip.product_code"; // rule keyword
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].desc = "rules for detecting EtherNet/IP product_code";
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].url = "/rules/enip-keyword.html#enip-product-code";
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].Match = NULL;
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].AppLayerTxMatch = DetectEnipProductCodeMatch;
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].Setup = DetectEnipProductCodeSetup;
- sigmatch_table[DETECT_ENIP_PRODUCTCODE].Free = DetectEnipProductCodeFree;
-
- DetectAppLayerInspectEngineRegister("enip.product_code", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.product_code", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_product_code_id = DetectBufferTypeGetByName("enip.product_code");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_PRODUCT_CODE_H
-#define SURICATA_DETECT_ENIP_PRODUCT_CODE_H
-
-void DetectEnipProductCodeRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_PRODUCT_CODE_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP Product name keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-prefilter.h"
-#include "rust.h"
-
-#include "detect-enip-product-name.h"
-
-static int g_enip_product_name_id = 0;
-
-/**
- * \brief this function is used to setup sticky buffer inspection for product_name
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip product name options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipProductNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectBufferSetActiveList(de_ctx, s, g_enip_product_name_id) < 0)
- return -1;
-
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- return 0;
-}
-
-static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
- const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv,
- const int list_id)
-{
- InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
- if (buffer->inspect == NULL) {
- const uint8_t *b = NULL;
- uint32_t b_len = 0;
-
- if (SCEnipTxGetProductName(txv, &b, &b_len) != 1)
- return NULL;
- if (b == NULL || b_len == 0)
- return NULL;
-
- InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len);
- InspectionBufferApplyTransforms(buffer, transforms);
- }
- return buffer;
-}
-
-/**
- * \brief Registration function for enip.product_name: keyword
- */
-void DetectEnipProductNameRegister(void)
-{
- sigmatch_table[DETECT_ENIP_PRODUCTNAME].name = "enip.product_name"; // rule keyword
- sigmatch_table[DETECT_ENIP_PRODUCTNAME].desc =
- "sticky buffer to match EtherNet/IP product name";
- sigmatch_table[DETECT_ENIP_PRODUCTNAME].url = "/rules/enip-keyword.html#enip-product-name";
- sigmatch_table[DETECT_ENIP_PRODUCTNAME].Setup = DetectEnipProductNameSetup;
- sigmatch_table[DETECT_ENIP_PRODUCTNAME].flags |= SIGMATCH_NOOPT;
-
- DetectAppLayerInspectEngineRegister("enip.product_name", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectBufferGeneric, GetData);
-
- DetectAppLayerMpmRegister("enip.product_name", SIG_FLAG_TOCLIENT, 2,
- PrefilterGenericMpmRegister, GetData, ALPROTO_ENIP, 1);
-
- DetectBufferTypeSetDescriptionByName("enip.product_name", "ENIP product name");
- g_enip_product_name_id = DetectBufferTypeGetByName("enip.product_name");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_PRODUCT_NAME_H
-#define SURICATA_DETECT_ENIP_PRODUCT_NAME_H
-
-void DetectEnipProductNameRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_PRODUCT_NAME_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP protocol version keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-protocol-version.h"
-
-static int g_enip_protocol_version_id = 0;
-
-static void DetectEnipProtocolVersionFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_protocol_version data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip protocol_version options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipProtocolVersionSetup(
- DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_PROTOCOLVERSION, (SigMatchCtx *)du16,
- g_enip_protocol_version_id) == NULL) {
- DetectEnipProtocolVersionFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip protocol_version type rule option on a transaction
- * with those passed via enip_protocol_version:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipProtocolVersionMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetProtocolVersion(txv, flags, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_protocol_version: keyword
- */
-void DetectEnipProtocolVersionRegister(void)
-{
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].name = "enip.protocol_version"; // rule keyword
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].desc =
- "rules for detecting EtherNet/IP protocol_version";
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].url =
- "/rules/enip-keyword.html#enip-protocol-version";
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].Match = NULL;
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].AppLayerTxMatch = DetectEnipProtocolVersionMatch;
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].Setup = DetectEnipProtocolVersionSetup;
- sigmatch_table[DETECT_ENIP_PROTOCOLVERSION].Free = DetectEnipProtocolVersionFree;
-
- DetectAppLayerInspectEngineRegister("enip.protocol_version", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.protocol_version", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_protocol_version_id = DetectBufferTypeGetByName("enip.protocol_version");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_PROTOCOL_VERSION_H
-#define SURICATA_DETECT_ENIP_PROTOCOL_VERSION_H
-
-void DetectEnipProtocolVersionRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_PROTOCOL_VERSION_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP revision keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-revision.h"
-
-static int g_enip_revision_id = 0;
-
-static void DetectEnipRevisionFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_revision data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip revision options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipRevisionSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(
- de_ctx, s, DETECT_ENIP_REVISION, (SigMatchCtx *)du16, g_enip_revision_id) == NULL) {
- DetectEnipRevisionFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip revision type rule option on a transaction with those
- * passed via enip_revision:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipRevisionMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetRevision(txv, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_revision: keyword
- */
-void DetectEnipRevisionRegister(void)
-{
- sigmatch_table[DETECT_ENIP_REVISION].name = "enip.revision"; // rule keyword
- sigmatch_table[DETECT_ENIP_REVISION].desc = "rules for detecting EtherNet/IP revision";
- sigmatch_table[DETECT_ENIP_REVISION].url = "/rules/enip-keyword.html#enip-revision";
- sigmatch_table[DETECT_ENIP_REVISION].Match = NULL;
- sigmatch_table[DETECT_ENIP_REVISION].AppLayerTxMatch = DetectEnipRevisionMatch;
- sigmatch_table[DETECT_ENIP_REVISION].Setup = DetectEnipRevisionSetup;
- sigmatch_table[DETECT_ENIP_REVISION].Free = DetectEnipRevisionFree;
-
- DetectAppLayerInspectEngineRegister("enip.revision", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.revision", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_revision_id = DetectBufferTypeGetByName("enip.revision");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_REVISION_H
-#define SURICATA_DETECT_ENIP_REVISION_H
-
-void DetectEnipRevisionRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_REVISION_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP serial keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-serial.h"
-
-static int g_enip_serial_id = 0;
-
-static void DetectEnipSerialFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u32_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_serial data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip serial options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipSerialSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU32Data *du32 = DetectU32Parse(rulestr);
- if (du32 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(
- de_ctx, s, DETECT_ENIP_SERIAL, (SigMatchCtx *)du32, g_enip_serial_id) == NULL) {
- DetectEnipSerialFree(de_ctx, du32);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip serial type rule option on a transaction with those
- * passed via enip_serial:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipSerialMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint32_t value;
- if (!SCEnipTxGetSerial(txv, &value))
- SCReturnInt(0);
- const DetectU32Data *du32 = (const DetectU32Data *)ctx;
- return DetectU32Match(value, du32);
-}
-
-/**
- * \brief Registration function for enip_serial: keyword
- */
-void DetectEnipSerialRegister(void)
-{
- sigmatch_table[DETECT_ENIP_SERIAL].name = "enip.serial"; // rule keyword
- sigmatch_table[DETECT_ENIP_SERIAL].desc = "rules for detecting EtherNet/IP serial";
- sigmatch_table[DETECT_ENIP_SERIAL].url = "/rules/enip-keyword.html#enip-serial";
- sigmatch_table[DETECT_ENIP_SERIAL].Match = NULL;
- sigmatch_table[DETECT_ENIP_SERIAL].AppLayerTxMatch = DetectEnipSerialMatch;
- sigmatch_table[DETECT_ENIP_SERIAL].Setup = DetectEnipSerialSetup;
- sigmatch_table[DETECT_ENIP_SERIAL].Free = DetectEnipSerialFree;
-
- DetectAppLayerInspectEngineRegister("enip.serial", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.serial", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_serial_id = DetectBufferTypeGetByName("enip.serial");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_SERIAL_H
-#define SURICATA_DETECT_ENIP_SERIAL_H
-
-void DetectEnipSerialRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_SERIAL_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP service name keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-prefilter.h"
-#include "rust.h"
-
-#include "detect-enip-service-name.h"
-
-static int g_enip_service_name_id = 0;
-
-/**
- * \brief this function is used to parse enip_service_name data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip service_name options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipServiceNameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectBufferSetActiveList(de_ctx, s, g_enip_service_name_id) < 0)
- return -1;
-
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- return 0;
-}
-
-static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
- const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv,
- const int list_id)
-{
- InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
- if (buffer->inspect == NULL) {
- const uint8_t *b = NULL;
- uint32_t b_len = 0;
-
- if (SCEnipTxGetServiceName(txv, &b, &b_len) != 1)
- return NULL;
- if (b == NULL || b_len == 0)
- return NULL;
-
- InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len);
- InspectionBufferApplyTransforms(buffer, transforms);
- }
- return buffer;
-}
-
-/**
- * \brief Registration function for enip_service_name: keyword
- */
-void DetectEnipServiceNameRegister(void)
-{
- sigmatch_table[DETECT_ENIP_SERVICENAME].name = "enip.service_name"; // rule keyword
- sigmatch_table[DETECT_ENIP_SERVICENAME].desc = "rules for detecting EtherNet/IP service_name";
- sigmatch_table[DETECT_ENIP_SERVICENAME].url = "/rules/enip-keyword.html#enip-service-name";
- sigmatch_table[DETECT_ENIP_SERVICENAME].Setup = DetectEnipServiceNameSetup;
- sigmatch_table[DETECT_ENIP_PRODUCTNAME].flags |= SIGMATCH_NOOPT;
-
- DetectAppLayerInspectEngineRegister("enip.service_name", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectBufferGeneric, GetData);
- DetectAppLayerMpmRegister("enip.service_name", SIG_FLAG_TOCLIENT, 2,
- PrefilterGenericMpmRegister, GetData, ALPROTO_ENIP, 1);
-
- DetectBufferTypeSetDescriptionByName("enip.service_name", "ENIP service name");
- g_enip_service_name_id = DetectBufferTypeGetByName("enip.service_name");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_SERVICE_NAME_H
-#define SURICATA_DETECT_ENIP_SERVICE_NAME_H
-
-void DetectEnipServiceNameRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_SERVICE_NAME_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP state keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-state.h"
-
-static int g_enip_state_id = 0;
-
-static void DetectEnipStateFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u8_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_state data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip state options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipStateSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU8Data *du8 = DetectU8Parse(rulestr);
- if (du8 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_STATE, (SigMatchCtx *)du8, g_enip_state_id) ==
- NULL) {
- DetectEnipStateFree(de_ctx, du8);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip state type rule option on a transaction with those
- * passed via enip_state:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipStateMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state,
- void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint8_t value;
- if (!SCEnipTxGetState(txv, &value))
- SCReturnInt(0);
- const DetectU8Data *du8 = (const DetectU8Data *)ctx;
- return DetectU8Match(value, du8);
-}
-
-/**
- * \brief Registration function for enip_state: keyword
- */
-void DetectEnipStateRegister(void)
-{
- sigmatch_table[DETECT_ENIP_STATE].name = "enip.state"; // rule keyword
- sigmatch_table[DETECT_ENIP_STATE].desc = "rules for detecting EtherNet/IP state";
- sigmatch_table[DETECT_ENIP_STATE].url = "/rules/enip-keyword.html#enip-state";
- sigmatch_table[DETECT_ENIP_STATE].Match = NULL;
- sigmatch_table[DETECT_ENIP_STATE].AppLayerTxMatch = DetectEnipStateMatch;
- sigmatch_table[DETECT_ENIP_STATE].Setup = DetectEnipStateSetup;
- sigmatch_table[DETECT_ENIP_STATE].Free = DetectEnipStateFree;
-
- DetectAppLayerInspectEngineRegister(
- "enip.state", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister(
- "enip.state", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
-
- g_enip_state_id = DetectBufferTypeGetByName("enip.state");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_STATE_H
-#define SURICATA_DETECT_ENIP_STATE_H
-
-void DetectEnipStateRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_STATE_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP Status rule parsing and entry point for matching
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-status.h"
-
-static int g_enip_status_id = 0;
-
-/**
- * \brief this function will free memory associated
- *
- * \param ptr pointer to u16
- */
-static void DetectEnipStatusFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u32_free(ptr);
-}
-
-/**
- * \brief this function is used by enipcmdd to parse enip_status data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip status options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipStatusSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU32Data *du32 = SCEnipParseStatus(rulestr);
- if (du32 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(
- de_ctx, s, DETECT_ENIPSTATUS, (SigMatchCtx *)du32, g_enip_status_id) == NULL) {
- DetectEnipStatusFree(de_ctx, du32);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip status type rule option on a transaction with those
- * passed via enip_status:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipStatusMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint32_t status;
- if (!SCEnipTxGetStatus(txv, flags, &status))
- SCReturnInt(0);
- const DetectU32Data *du32 = (const DetectU32Data *)ctx;
- return DetectU32Match(status, du32);
-}
-
-/**
- * \brief Registration function for enip_status: keyword
- */
-void DetectEnipStatusRegister(void)
-{
- sigmatch_table[DETECT_ENIPSTATUS].name = "enip.status"; // rule keyword
- sigmatch_table[DETECT_ENIPSTATUS].desc = "rules for detecting EtherNet/IP status";
- sigmatch_table[DETECT_ENIPSTATUS].url = "/rules/enip-keyword.html#enip-status";
- sigmatch_table[DETECT_ENIPSTATUS].Match = NULL;
- sigmatch_table[DETECT_ENIPSTATUS].AppLayerTxMatch = DetectEnipStatusMatch;
- sigmatch_table[DETECT_ENIPSTATUS].Setup = DetectEnipStatusSetup;
- sigmatch_table[DETECT_ENIPSTATUS].Free = DetectEnipStatusFree;
-
- DetectAppLayerInspectEngineRegister("enip.status", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.status", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_status_id = DetectBufferTypeGetByName("enip.status");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_STATUS_H
-#define SURICATA_DETECT_ENIP_STATUS_H
-
-void DetectEnipStatusRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_STATUS_H */
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- *
- * Set up ENIP vendor id keyword
- */
-
-#include "suricata-common.h"
-#include "detect-parse.h"
-#include "detect-engine.h"
-#include "detect-engine-uint.h"
-#include "rust.h"
-
-#include "detect-enip-vendor-id.h"
-
-static int g_enip_vendor_id_id = 0;
-
-static void DetectEnipVendorIdFree(DetectEngineCtx *de_ctx, void *ptr)
-{
- rs_detect_u16_free(ptr);
-}
-
-/**
- * \brief this function is used to parse enip_vendor_id data into the current signature
- *
- * \param de_ctx pointer to the Detection Engine Context
- * \param s pointer to the Current Signature
- * \param rulestr pointer to the user provided enip vendor_id options
- *
- * \retval 0 on Success
- * \retval -1 on Failure
- */
-static int DetectEnipVendorIdSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr)
-{
- if (DetectSignatureSetAppProto(s, ALPROTO_ENIP) != 0)
- return -1;
-
- DetectU16Data *du16 = DetectU16Parse(rulestr);
- if (du16 == NULL) {
- return -1;
- }
-
- if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENIP_VENDORID, (SigMatchCtx *)du16,
- g_enip_vendor_id_id) == NULL) {
- DetectEnipVendorIdFree(de_ctx, du16);
- SCReturnInt(-1);
- }
- SCReturnInt(0);
-}
-
-/**
- * \brief This function is used to match enip vendor_id type rule option on a transaction with those
- * passed via enip_vendor_id:
- *
- * \retval 0 no match
- * \retval 1 match
- */
-static int DetectEnipVendorIdMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
- void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
-
-{
- uint16_t value;
- if (!SCEnipTxGetVendorId(txv, &value))
- SCReturnInt(0);
- const DetectU16Data *du16 = (const DetectU16Data *)ctx;
- return DetectU16Match(value, du16);
-}
-
-/**
- * \brief Registration function for enip_vendor_id: keyword
- */
-void DetectEnipVendorIdRegister(void)
-{
- sigmatch_table[DETECT_ENIP_VENDORID].name = "enip.vendor_id"; // rule keyword
- sigmatch_table[DETECT_ENIP_VENDORID].desc = "rules for detecting EtherNet/IP vendor_id";
- sigmatch_table[DETECT_ENIP_VENDORID].url = "/rules/enip-keyword.html#enip-vendor-id";
- sigmatch_table[DETECT_ENIP_VENDORID].Match = NULL;
- sigmatch_table[DETECT_ENIP_VENDORID].AppLayerTxMatch = DetectEnipVendorIdMatch;
- sigmatch_table[DETECT_ENIP_VENDORID].Setup = DetectEnipVendorIdSetup;
- sigmatch_table[DETECT_ENIP_VENDORID].Free = DetectEnipVendorIdFree;
-
- DetectAppLayerInspectEngineRegister("enip.vendor_id", ALPROTO_ENIP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectGenericList, NULL);
- DetectAppLayerInspectEngineRegister("enip.vendor_id", ALPROTO_ENIP, SIG_FLAG_TOCLIENT, 0,
- DetectEngineInspectGenericList, NULL);
-
- g_enip_vendor_id_id = DetectBufferTypeGetByName("enip.vendor_id");
-}
+++ /dev/null
-/* Copyright (C) 2023 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Philippe Antoine
- */
-
-#ifndef SURICATA_DETECT_ENIP_VENDOR_ID_H
-#define SURICATA_DETECT_ENIP_VENDOR_ID_H
-
-void DetectEnipVendorIdRegister(void);
-
-#endif /* SURICATA_DETECT_ENIP_VENDOR_ID_H */