summaryrefslogtreecommitdiffstats
path: root/src/app-layer-enip-common.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
commita0aa2307322cd47bbf416810ac0292925e03be87 (patch)
tree37076262a026c4b48c8a0e84f44ff9187556ca35 /src/app-layer-enip-common.h
parentInitial commit. (diff)
downloadsuricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz
suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/app-layer-enip-common.h')
-rw-r--r--src/app-layer-enip-common.h245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/app-layer-enip-common.h b/src/app-layer-enip-common.h
new file mode 100644
index 0000000..1578343
--- /dev/null
+++ b/src/app-layer-enip-common.h
@@ -0,0 +1,245 @@
+/* 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>
+ */
+
+#ifndef __APP_LAYER_ENIP_COMMON_H__
+#define __APP_LAYER_ENIP_COMMON_H__
+
+#include "rust.h"
+
+// EtherNet/IP commands
+#define NOP 0x0000
+#define LIST_SERVICES 0x0004
+#define LIST_IDENTITY 0x0063
+#define LIST_INTERFACES 0x0064
+#define REGISTER_SESSION 0x0065
+#define UNREGISTER_SESSION 0x0066
+#define SEND_RR_DATA 0x006F
+#define SEND_UNIT_DATA 0x0070
+#define INDICATE_STATUS 0x0072
+#define CANCEL 0x0073
+
+//Common Packet Format Types
+#define NULL_ADDR 0x0000
+#define CONNECTION_BASED 0x00a1
+#define CONNECTED_DATA_ITEM 0x00b1
+#define UNCONNECTED_DATA_ITEM 0x00b2
+#define SEQUENCE_ADDR_ITEM 0xB002
+
+//status codes
+#define SUCCESS 0x0000
+#define INVALID_CMD 0x0001
+#define NO_RESOURCES 0x0002
+#define INCORRECT_DATA 0x0003
+#define INVALID_SESSION 0x0064
+#define INVALID_LENGTH 0x0065
+#define UNSUPPORTED_PROT_REV 0x0069
+//Found in wireshark
+#define ENCAP_HEADER_ERROR 0x006A
+
+#define MAX_CIP_SERVICE 127
+#define MAX_CIP_CLASS 65535
+#define MAX_CIP_ATTRIBUTE 65535
+
+// CIP service codes
+#define CIP_RESERVED 0x00
+#define CIP_GET_ATTR_ALL 0x01
+#define CIP_GET_ATTR_LIST 0x03
+#define CIP_SET_ATTR_LIST 0x04
+#define CIP_RESET 0x05
+#define CIP_START 0x06
+#define CIP_STOP 0x07
+#define CIP_CREATE 0x08
+#define CIP_DELETE 0x09
+#define CIP_MSP 0x0a
+#define CIP_APPLY_ATTR 0x0d
+#define CIP_GET_ATTR_SINGLE 0x0e
+#define CIP_SET_ATTR_SINGLE 0x10
+#define CIP_KICK_TIMER 0x4b
+#define CIP_OPEN_CONNECTION 0x4c
+#define CIP_CHANGE_START 0x4f
+#define CIP_GET_STATUS 0x50
+
+//PATH sizing codes
+#define PATH_CLASS_8BIT 0x20
+#define PATH_CLASS_16BIT 0x21
+#define PATH_INSTANCE_8BIT 0x24
+#define PATH_INSTANCE_16BIT 0x25
+#define PATH_ATTR_8BIT 0x30
+#define PATH_ATTR_16BIT 0x31 //possible value
+
+/**
+ * ENIP encapsulation header
+ */
+typedef struct ENIPEncapHdr_
+{
+ uint64_t context;
+ uint32_t session;
+ uint32_t status;
+ uint32_t option;
+ uint16_t command;
+ uint16_t length;
+} ENIPEncapHdr;
+
+/**
+ * ENIP encapsulation data header
+ */
+typedef struct ENIPEncapDataHdr_
+{
+ uint32_t interface_handle;
+ uint16_t timeout;
+ uint16_t item_count;
+} ENIPEncapDataHdr;
+
+/**
+ * ENIP encapsulation address item
+ */
+typedef struct ENIPEncapAddressItem_ {
+ uint16_t type;
+ uint16_t length;
+ uint32_t conn_id;
+ uint32_t sequence_num;
+} ENIPEncapAddressItem;
+
+/**
+ * ENIP encapsulation data item
+ */
+typedef struct ENIPEncapDataItem_
+{
+ uint16_t type;
+ uint16_t length;
+ uint16_t sequence_count;
+} ENIPEncapDataItem;
+
+/**
+ * CIP Request Header
+ */
+typedef struct CIPReqHdr_
+{
+ uint8_t service;
+ uint8_t path_size;
+} CIPReqHdr;
+
+/**
+ * CIP Response Header
+ */
+typedef struct CIPRespHdr_
+{
+ uint8_t service;
+ uint8_t pad;
+ uint8_t status;
+ uint8_t status_size;
+} CIPRespHdr;
+
+typedef struct SegmentEntry_
+{
+ uint16_t segment; /**< segment type */
+ uint16_t value; /**< segment value (class or attribute) */
+
+ TAILQ_ENTRY(SegmentEntry_) next;
+} SegmentEntry;
+
+typedef struct AttributeEntry_
+{
+ uint16_t attribute; /**< segment class */
+
+ TAILQ_ENTRY(AttributeEntry_) next;
+} AttributeEntry;
+
+typedef struct CIPServiceEntry_
+{
+ uint8_t service; /**< cip service */
+ uint8_t direction;
+ union
+ {
+ struct
+ {
+ uint8_t path_size; /**< cip path size */
+ uint16_t path_offset; /**< offset to cip path */
+ } request;
+ struct
+ {
+ uint16_t status;
+ } response;
+ };
+
+ TAILQ_HEAD(, SegmentEntry_) segment_list; /**< list for CIP segment */
+ TAILQ_HEAD(, AttributeEntry_) attrib_list; /**< list for CIP segment */
+
+ TAILQ_ENTRY(CIPServiceEntry_) next;
+} CIPServiceEntry;
+
+typedef struct ENIPTransaction_
+{
+ struct ENIPState_ *enip;
+ uint64_t tx_num; /**< internal: id */
+ uint16_t tx_id; /**< transaction id */
+ uint16_t service_count;
+
+ ENIPEncapHdr header; /**< encapsulation header */
+ ENIPEncapDataHdr encap_data_header; /**< encapsulation data header */
+ ENIPEncapAddressItem encap_addr_item; /**< encapsulated address item */
+ ENIPEncapDataItem encap_data_item; /**< encapsulated data item */
+
+ TAILQ_HEAD(, CIPServiceEntry_) service_list; /**< list for CIP */
+
+ TAILQ_ENTRY(ENIPTransaction_) next;
+ AppLayerTxData tx_data;
+} ENIPTransaction;
+
+/** \brief Per flow ENIP state container */
+typedef struct ENIPState_
+{
+ AppLayerStateData state_data;
+ TAILQ_HEAD(, ENIPTransaction_) tx_list; /**< transaction list */
+ ENIPTransaction *curr; /**< ptr to current tx */
+ ENIPTransaction *iter;
+ uint64_t transaction_max;
+ uint64_t tx_with_detect_state_cnt;
+
+ uint16_t events;
+ uint16_t givenup;
+
+ /* used by TCP only */
+ uint16_t offset;
+ uint16_t record_len;
+ uint8_t *buffer;
+} ENIPState;
+
+int DecodeENIPPDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data);
+int DecodeCommonPacketFormatPDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data, uint16_t offset);
+int DecodeCIPPDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data, uint16_t offset);
+int DecodeCIPRequestPDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data, uint16_t offset);
+int DecodeCIPResponsePDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data, uint16_t offset);
+int DecodeCIPRequestPathPDU(const uint8_t *input, uint32_t input_len,
+ CIPServiceEntry *node, uint16_t offset);
+int DecodeCIPRequestMSPPDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data, uint16_t offset);
+int DecodeCIPResponseMSPPDU(const uint8_t *input, uint32_t input_len,
+ ENIPTransaction *enip_data, uint16_t offset);
+
+#endif /* __APP_LAYER_ENIP_COMMON_H__ */