Feature #3958
closedenip: convert protocol parser to rust
Description
ENIP implementation already exists for Suricata but in order to make it more secure and trustworthy, we'd like to convert it to Rust.
Below is a (very) brief step by step overview of going about the implementation:
- Get to know more about the protocol from the official RFC.
- Match the RFC defined header structs and handling with C code and understand and note down the flow and handling.
- Create basic header structures in Rust. (These do not have to be same as C but should follow the protocol standards (e.g. alignment and data types of certain fields) as per the RFC)
- Use test data from C for headers and try to write a parser such that those tests pass as they did in C.
- After the header parsers work in Rust, move to UDP implementation of packet handling (start with creating a <Protocol>State struct to store all important info).
- Try to replicate UDP handling in C for the protocol and make unit tests pass for one transaction only.
- Integrate with C, make sure the tests pass.
- Find PCAPs for the application layer protocol over UDP covering all the modes (in case there are diff modes of operation for a protocol e.g. diff versions of protocol)
- Write a (few) suricata-verify tests (you could use createst.py to create those for you with the PCAP) with those PCAPS and make sure all the tests pass.
This completes UDP conversion of the protocol and some basic chassis for protocol over TCP (structures and header parsing).
10. Try and replicate the TCP implementation in C of the protocol.
11. Learn more about stream handling and how Suricata does internal reassembly of packets, etc.
12. Repeat steps 6-9 for TCP.
This completes TCP conversion of the protocol as well but all works only for one transaction.
13. Try adding more transactions to tests and make them pass.
14. Make sure suricata-verify tests pass too.
This completes multi-transaction handling of the protocols.
15. Check out TCP stream gap handling for other protocols and try to implement the same for the protocol in Rust.
16. Enable gap handling for the protocol in C and integrate Rust code.
17. Find out or create PCAPs with TCP stream gaps, add tests with them to suricata-verify, make sure they pass.
This almost completes the conversion of the protocol.
18. Enable logging for the protocol, convert json logging from C to Rust.
19. Test that logging results pass with `--enable-debug-validation` and jsonbuilder does not panic anywhere.
20. Write suricata-verify tests for the same, make sure they pass.
This completes the protocol conversion to Rust. Now, fix bugs as when they arrive. :)
Pro tips:
- Take inspiration from other protocols, smaller/popular protocols (e.g. DNS, SIP) are easier to follow.
- Git is your best friend. (e.g. to see how a particular protocol's conversion progressed check all the closed PRs corresponding to that, a lot of useful content might be there)
Updated by Victor Julien over 4 years ago
- Related to Task #3195: tracking: rustify all input added
Updated by Victor Julien over 4 years ago
PCAPS to test with: https://github.com/scy-phy/bro-cip-enip/tree/master/testing/btest/Traces/enip
Updated by Shivani Bhardwaj about 4 years ago
- Related to Task #2778: tracking: port app-layer parsers to Rust added
Updated by Shivani Bhardwaj about 4 years ago
- Related to Optimization #2781: Convert ENIP from C to Rust added
Updated by Simon Dugas almost 4 years ago
Could I be assigned this ticket? We are currently working on an ENIP rust parser to go along with our DNP3 and modbus parsers.
Updated by Philippe Antoine over 1 year ago
- Assignee set to Community Ticket
- Target version set to TBD
Tickets with no assignee are free to be taken
Updated by Philippe Antoine about 1 year ago
- Assignee changed from Community Ticket to Philippe Antoine
Updated by Philippe Antoine about 1 year ago
- Target version changed from TBD to 8.0.0-beta1
Updated by Philippe Antoine about 1 year ago
- Status changed from New to In Progress
Updated by Philippe Antoine about 1 year ago
- Status changed from In Progress to In Review
https://github.com/OISF/suricata/pull/9940 is no longer a draft
Updated by Philippe Antoine 11 months ago
- Blocked by Optimization #3827: clean up logging initialization code added
Updated by Philippe Antoine 7 months ago
- Related to Bug #6753: detect/cip: missing return-value check for a 'scanf'-like function added
Updated by Philippe Antoine 7 months ago
- Status changed from In Review to Closed
Updated by Philippe Antoine 6 months ago
Simple follow up https://github.com/OISF/suricata/pull/11290
Updated by Victor Julien 6 months ago
- Blocks Story #7140: protocols: C to Rust conversions added
Updated by Victor Julien 6 months ago
- Subject changed from Convert protocol to Rust: ENIP to enip: convert protocol parser to rust
Updated by Philippe Antoine 2 months ago
https://github.com/OISF/suricata/pull/11981 small follow up