Skip to content

Commit 42b5fac

Browse files
committed
enip: convert to rust
Ticket: 3958 - enip_command keyword accepts now string enumeration as values. - transactions are now bidirectional - there is a logger - gap support is improved with probing for resync - SEQUENCE_ADDR_ITEM value is fixed to 0x8002 instead of 0xB002 - frames support - app-layer events - add enip.status keyword
1 parent ea7e098 commit 42b5fac

32 files changed

Lines changed: 2262 additions & 2669 deletions

‎doc/userguide/configuration/suricata-yaml.rst‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1761,7 +1761,8 @@ incompatible with ``decode-mime``. If both are enabled,
17611761
Maximum transactions
17621762
~~~~~~~~~~~~~~~~~~~~
17631763

1764-
MQTT, FTP, PostgreSQL, SMB, DCERPC and NFS have each a `max-tx` parameter that can be customized.
1764+
MQTT, FTP, PostgreSQL, SMB, DCERPC, ENIP and NFS have each a `max-tx`
1765+
parameter that can be customized.
17651766
`max-tx` refers to the maximum number of live transactions for each flow.
17661767
An app-layer event `protocol.too_many_transactions` is triggered when this value is reached.
17671768
The point of this parameter is to find a balance between the completeness of analysis
Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,43 @@
11
ENIP/CIP Keywords
22
=================
33

4-
The enip_command and cip_service keywords can be used for matching on various properties of
5-
ENIP requests.
4+
enip_command
5+
------------
66

7-
There are three ways of using this keyword:
7+
For the ENIP command, we are matching against the command field found in the ENIP encapsulation.
8+
9+
Examples::
810

9-
* matching on ENIP command with the setting "enip_command";
10-
* matching on CIP Service with the setting "cip_service".
11-
* matching both the ENIP command and the CIP Service with "enip_command" and "cip_service" together
11+
enip_command:99;
12+
enip_command:ListIdentity;
1213

1314

14-
For the ENIP command, we are matching against the command field found in the ENIP encapsulation.
15+
cip_service
16+
-----------
1517

1618
For the CIP Service, we use a maximum of 3 comma separated values representing the Service, Class and Attribute.
1719
These values are described in the CIP specification. CIP Classes are associated with their Service, and CIP Attributes
1820
are associated with their Service. If you only need to match up until the Service, then only provide the Service value.
1921
If you want to match to the CIP Attribute, then you must provide all 3 values.
2022

21-
22-
Syntax::
23-
24-
enip_command:<value>
25-
cip_service:<value(s)>
26-
enip_command:<value>, cip_service:<value(s)>
27-
28-
2923
Examples::
3024

31-
enip_command:99
3225
cip_service:75
3326
cip_service:16,246,6
34-
enip_command:111, cip_service:5
3527

3628

3729
(cf. http://read.pudn.com/downloads166/ebook/763211/EIP-CIP-V1-1.0.pdf)
3830

3931
Information on the protocol can be found here:
4032
`<http://literature.rockwellautomation.com/idc/groups/literature/documents/wp/enet-wp001_-en-p.pdf>`_
33+
34+
enip.status
35+
-----------
36+
37+
For the ENIP status, we are matching against the status field found in the ENIP encapsulation.
38+
It uses a 32-bit unsigned integer as value.
39+
40+
Examples::
41+
42+
enip.status:100;
43+
enip.status:>106;

‎etc/schema.json‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,75 @@
13991399
},
14001400
"additionalProperties": false
14011401
},
1402+
"enip": {
1403+
"type": "object",
1404+
"properties": {
1405+
"request": {
1406+
"type": "object",
1407+
"properties": {
1408+
"command": {
1409+
"type": "string"
1410+
},
1411+
"status": {
1412+
"type": "string"
1413+
},
1414+
"length": {
1415+
"type": "integer"
1416+
}
1417+
},
1418+
"additionalProperties": false
1419+
},
1420+
"response": {
1421+
"type": "object",
1422+
"properties": {
1423+
"command": {
1424+
"type": "string"
1425+
},
1426+
"status": {
1427+
"type": "string"
1428+
},
1429+
"length": {
1430+
"type": "integer"
1431+
},
1432+
"identity": {
1433+
"type": "object",
1434+
"properties": {
1435+
"protocol_version": {
1436+
"type": "integer"
1437+
},
1438+
"revision": {
1439+
"type": "string"
1440+
},
1441+
"vendor_id": {
1442+
"type": "integer"
1443+
},
1444+
"device_type": {
1445+
"type": "integer"
1446+
},
1447+
"product_code": {
1448+
"type": "integer"
1449+
},
1450+
"status": {
1451+
"type": "integer"
1452+
},
1453+
"serial": {
1454+
"type": "integer"
1455+
},
1456+
"product_name": {
1457+
"type": "string"
1458+
},
1459+
"state": {
1460+
"type": "integer"
1461+
}
1462+
},
1463+
"additionalProperties": false
1464+
}
1465+
},
1466+
"additionalProperties": false
1467+
}
1468+
},
1469+
"additionalProperties": false
1470+
},
14021471
"ether": {
14031472
"type": "object",
14041473
"properties": {

‎rules/Makefile.am‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ decoder-events.rules \
66
dhcp-events.rules \
77
dnp3-events.rules \
88
dns-events.rules \
9+
enip-events.rules \
910
files.rules \
1011
ftp-events.rules \
1112
http-events.rules \

‎rules/enip-events.rules‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# ENIP app layer event rules
2+
#
3+
# SID's fall in the 2223000+ range. See https://redmine.openinfosecfoundation.org/projects/suricata/wiki/AppLayer
4+
#
5+
# These sigs fire at most once per connection.
6+
#
7+
alert enip any any -> any any (msg:"SURICATA ENIP too many transactions"; app-layer-event:enip.too_many_transactions; classtype:protocol-command-decode; sid:2233000; rev:1;)
8+
alert enip any any -> any any (msg:"SURICATA ENIP invalid PDU"; app-layer-event:enip.invalid_pdu; classtype:protocol-command-decode; sid:2233001; rev:1;)

‎rust/src/applayer.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ extern {
487487
pub fn AppLayerParserStateIssetFlag(state: *mut c_void, flag: u16) -> u16;
488488
pub fn AppLayerParserSetStreamDepth(ipproto: u8, alproto: AppProto, stream_depth: u32);
489489
pub fn AppLayerParserConfParserEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int;
490+
pub fn AppLayerParserRegisterParserAcceptableDataDirection(ipproto: u8, alproto: AppProto, dir: u8);
490491
}
491492

492493
#[repr(C)]

0 commit comments

Comments
 (0)