189 lines
4.7 KiB
Markdown
189 lines
4.7 KiB
Markdown
# API Documentation
|
|
|
|
This document describes the input/output formats and the checker program API.
|
|
|
|
## CLI API
|
|
|
|
Command:
|
|
|
|
```bash
|
|
checker --pcap <trace.pcapng> --meta <trace.meta.jsonl> --config <modbus.json> \
|
|
--report <report.json> [--port 502] [--mode mvp|strict] [--fail-fast]
|
|
```
|
|
|
|
Exit behavior:
|
|
|
|
- Returns a non-zero exit code only on process-level errors (I/O, parse failures).
|
|
- Validation findings are written to the report file.
|
|
|
|
## JSONL Sidecar (`trace.meta.jsonl`)
|
|
|
|
Each line corresponds to one packet, in the same order as the PCAP.
|
|
|
|
```json
|
|
{
|
|
"trace_id": "c7f1...",
|
|
"event_id": 42,
|
|
"pcap_index": 42,
|
|
"ts_ns": 1736451234567890123,
|
|
"direction": "c2s",
|
|
"flow": {
|
|
"src_ip": "10.0.0.10",
|
|
"src_port": 51012,
|
|
"dst_ip": "10.0.0.20",
|
|
"dst_port": 502
|
|
},
|
|
"expected": {
|
|
"modbus": {
|
|
"transaction_id": 513,
|
|
"unit_id": 1,
|
|
"function_code": 3
|
|
},
|
|
"fields": {
|
|
"starting_address": 0,
|
|
"quantity": 10
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Example: `docs/examples/trace.meta.jsonl`
|
|
|
|
Fields:
|
|
|
|
- `trace_id` (string, optional): Trace identifier.
|
|
- `event_id` (integer, optional): Event identifier from generator.
|
|
- `pcap_index` (integer, optional): Packet index for reference.
|
|
- `ts_ns` (integer, optional): Timestamp in nanoseconds.
|
|
- `direction` (string, required): `c2s` (request) or `s2c` (response).
|
|
- `flow` (object, required): Flow metadata used for request/response tracking.
|
|
- `expected` (object, optional): Expected Modbus header and/or field values.
|
|
|
|
`expected.modbus`:
|
|
|
|
- `transaction_id` (u16, optional)
|
|
- `unit_id` (u8, optional)
|
|
- `function_code` (u8, optional)
|
|
|
|
`expected.fields`:
|
|
|
|
- Arbitrary JSON object whose keys match descriptor field names.
|
|
- Values are compared against parsed output.
|
|
|
|
## Modbus Descriptor JSON (`modbus.json`)
|
|
|
|
Top-level:
|
|
|
|
```json
|
|
{
|
|
"functions": [
|
|
{
|
|
"function": 3,
|
|
"name": "read_holding_registers",
|
|
"request": [
|
|
{"name":"starting_address","type":"u16"},
|
|
{"name":"quantity","type":"u16"}
|
|
],
|
|
"response": [
|
|
{"name":"byte_count","type":"u8"},
|
|
{"name":"registers","type":"bytes","length_from":"byte_count"}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Example: `docs/examples/modbus.json`
|
|
|
|
Function descriptor:
|
|
|
|
- `function` (u8, required): Function code.
|
|
- `name` (string, optional): Human-readable function name.
|
|
- `request` (array, optional): Field list for client-to-server PDUs.
|
|
- `response` (array, optional): Field list for server-to-client PDUs.
|
|
|
|
Field descriptor:
|
|
|
|
- `name` (string, required): Field name used in output JSON.
|
|
- `type` (string, required): `u8`, `u16`, `u32`, `i16`, `i32`, `bytes`.
|
|
- `length` (integer, optional): Fixed length for `bytes`.
|
|
- `length_from` (string, optional): Name of a previous numeric field.
|
|
- `scale` (number, optional): Multiply numeric values by this scale.
|
|
- `enum_map` (object, optional): Map numeric strings to JSON values.
|
|
|
|
Notes:
|
|
|
|
- `length_from` uses values parsed earlier in the same descriptor.
|
|
- `bytes` output is an array of integers.
|
|
|
|
## Report JSON (`report.json`)
|
|
|
|
Structure:
|
|
|
|
```json
|
|
{
|
|
"summary": {
|
|
"total_packets": 1000,
|
|
"total_findings": 8,
|
|
"fatal": 1,
|
|
"error": 4,
|
|
"warn": 3,
|
|
"info": 0
|
|
},
|
|
"findings": [
|
|
{
|
|
"pcap_index": 7,
|
|
"event_id": 42,
|
|
"severity": "error",
|
|
"code": "mbap_protocol",
|
|
"message": "Protocol id is 1, expected 0",
|
|
"flow": {
|
|
"src_ip": "10.0.0.10",
|
|
"src_port": 51012,
|
|
"dst_ip": "10.0.0.20",
|
|
"dst_port": 502
|
|
},
|
|
"observed": {"payload_len": 42, "mbap_length": 10},
|
|
"expected": null
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Example: `docs/examples/report.json`
|
|
|
|
Summary fields:
|
|
|
|
- `total_packets`: Total packets processed.
|
|
- `total_findings`: Total findings emitted.
|
|
- `fatal`, `error`, `warn`, `info`: Counts by severity.
|
|
|
|
Finding fields:
|
|
|
|
- `pcap_index` (u64): Index in PCAP stream.
|
|
- `event_id` (u64, optional): Event identifier from metadata.
|
|
- `severity` (string): `fatal`, `error`, `warn`, `info`.
|
|
- `code` (string): Short machine-friendly code.
|
|
- `message` (string): Human-readable description.
|
|
- `flow` (object, optional): Source/destination addresses.
|
|
- `observed` (JSON, optional): Observed values for comparison.
|
|
- `expected` (JSON, optional): Expected values for comparison.
|
|
|
|
## Validation Modes
|
|
|
|
- `mvp`: Core checks only.
|
|
- `strict`: Treat MBAP length mismatch as a stopping condition.
|
|
|
|
## Internal Module API (Rust)
|
|
|
|
Primary modules:
|
|
|
|
- `config`: Descriptor types and loader for JSON config.
|
|
- `meta`: JSONL metadata structs.
|
|
- `decode`: PCAP packet decode to TCP payload.
|
|
- `mbap`: MBAP parsing utilities.
|
|
- `modbus_desc`: Descriptor-based field parsing.
|
|
- `state`: Outstanding request tracking.
|
|
- `validate`: End-to-end validation pipeline.
|
|
- `report`: Report data structures.
|