QuitOperation/otcat

GitHub: QuitOperation/otcat

otcat 是一款工业级命令行工具,让工程师像使用 netcat 一样在 shell 中直接读取、写入和监控 PLC 的 Modbus TCP 寄存器。

Stars: 1 | Forks: 0

otcat industrial logo

otcat — 工业级 I/O 的 netcat

直接在你的 shell 中读取、写入和监控 PLC 寄存器,就像 nc 检查 TCP socket 一样。

Version 1.0.0 Go Version PyPI Package MIT License Security Policy Go Docs GitHub Stars

🌐 在线网站📦 包与安装🐍 Python 库🛡️ 安全策略🗺️ 驱动路线图🤝 参与贡献

## ⚡ 快速开始 ``` # 读取保持寄存器 40001 并输出为结构化 JSON otcat --modbus 192.168.1.10:502 --read holding:40001 --json # 使用短二进制别名 'otc' 每 500ms 监控遥测数据 otc --modbus 192.168.1.10:502 --watch holding:40001 --interval 500ms --raw | awk '{print $1*0.1}' # 通过显式安全确认门写入 setpoint otcat --modbus 192.168.1.10:502 --write holding:40001 --value 100 --confirm # 将 setpoint 值直接从 stdin 流式传输到 PLC 寄存器 cat setpoints.txt | otcat --modbus 192.168.1.10:502 --write holding:40001 --from-stdin --confirm ```

otcat quickstart demo recording

## 📋 目录 - [为什么选择 otcat?](#-why-otcat) - [架构与数据流](#-architecture--data-flow) - [协议支持矩阵](#-protocol-support-matrix) - [安装与构建](#-install--build) - [地址规范](#-address-specification) - [写入安全闸门](#-write-safety-gate) - [输出格式](#-output-formats) - [退出码](#-exit-codes) - [Python 绑定](#-python-bindings) - [测试与基准测试](#-testing--benchmarks) - [项目布局](#-project-layout) - [许可证](#-license) ## 💡 为什么选择 otcat? 70% 的现场 OT 故障排除仅仅是验证寄存器读数。传统的供应商 SCADA 软件需要数 GB 的专有安装包、复杂的授权许可和 Windows GUI。 `otcat` 将标准的 Unix 管道哲学带入了工业自动化领域: - **零依赖**:单个静态 Go 二进制文件。无 CGO,无外部库。 - **内置简短别名**:附带 `otc` 二进制别名(`nc` : `netcat` :: `otc` : `otcat`)。 - **故障安全写入闸门**:内置的交互式确认和 `--confirm` 标志可防止意外的物理寄存器突变。 - **可组合性强**:输出换行符分隔的 JSON、CSV 或原始数字,可直接用于 `jq`、`awk` 或 `grep`。 ## 🏗️ 架构与数据流 ``` +-------------------------------------------------------------------------+ | OPERATOR / SHELL / CI | | otcat --modbus 192.168.1.10:502 --read holding:40001 --json | awk | +-------------------------------------+-----------------------------------+ | v +-------------------------------------------------------------------------+ | OTCAT ENGINE (v1.0.0) | | +--------------------+ +-------------------+ +------------------+ | | | Codec (JSON/CSV) | | Safety Gate | | Watch Loop | | | +---------+----------+ +---------+---------+ +--------+---------+ | +------------|------------------------|----------------------|------------+ | | | +------------------------v----------------------+ | [ Driver Abstraction ] | +------------------------+-----------------------+ | | | v v v +-------------------+ +--------------------+ +--------------------+ | Modbus TCP Driver | | EtherNet/IP (stub) | | S7comm/BACnet (sub)| +---------+---------+ +--------------------+ +--------------------+ | v (TCP Port 502) +-------------------------------------------------------------------------+ | FIELD PLC / CONTROLLER / GATEWAY | +-------------------------------------------------------------------------+ ``` ## 📊 协议支持矩阵 | 协议 | 驱动标志 | 状态 | 支持的功能码与数据表 | | :--- | :---: | :---: | :--- | | **Modbus TCP** | `--modbus` | **完整 (100%)** | Coils (FC01/05/15), Discrete (FC02), Holding (FC03/06/16), Input (FC04) | | **EtherNet/IP** | `--eip` | *路线图* | 已注册的 CLI 桩。见 [`docs/driver_roadmap.md`](docs/driver_roadmap.md) | | **S7comm** | `--s7comm` | *路线图* | 已注册的 CLI 桩。见 [`docs/driver_roadmap.md`](docs/driver_roadmap.md) | | **BACnet/IP** | `--bacnet` | *路线图* | 已注册的 CLI 桩。见 [`docs/driver_roadmap.md`](docs/driver_roadmap.md) | ## 📦 安装与构建 ### 包管理器 通过 APT、DNF、APK、pip 或 Go 工具链安装原生包: ``` # Debian / Ubuntu (APT) sudo apt install -y otcat # Fedora / RHEL (DNF) sudo dnf install -y --nogpgcheck otcat # Alpine Linux (APK) apk add --allow-untrusted otcat # Python PyPI (pip) pip install otcat # Go Toolchain (Go 1.22+) go install github.com/QuitOperation/otcat/cmd/otc@latest # Docker Container (GitHub Container Registry) docker pull ghcr.io/quitoperation/otcat:latest ``` ### 从源码构建 ``` git clone https://github.com/QuitOperation/otcat.git cd otcat # 构建 main 二进制文件 go build -o otcat ./cmd/otcat go build -o otc ./cmd/otc # 构建模拟与诊断工具 go build -o otcat-mockplc ./cmd/otcat-mockplc go build -o otcat-latencyprobe ./cmd/otcat-latencyprobe ``` ## 🎯 地址规范 地址遵循标准格式:`table:address[:count]` ``` holding:40001 # Holding Register 40001 (0-indexed wire offset 0x0000) input:30005 # Input Register 30005 coil:00001 # Coil 1 discrete:10010 # Discrete Input 10010 ``` 使用 `--raw-address` 时,地址将直接被解释为字面意义上的从零开始的协议线路偏移量(`holding:0`)。有关详细的解析逻辑,请参见 [`docs/classic_addressing.md`](docs/classic_addressing.md)。 ## 🛡️ 写入安全闸门 为了保护物理机械设备和运营技术网络,**所有写入操作均受安全闸门保护**: ``` # stderr 上的交互式确认提示: $ otcat --modbus 192.168.1.10:502 --write holding:40001 --value 100 CONFIRM WRITE: Write 100 to holding:40001 on 192.168.1.10:502? [y/N] y SUCCESS: Register 40001 updated to 100. # 非交互式自动化脚本需要 --confirm: otcat --modbus 192.168.1.10:502 --write holding:40001 --value 100 --confirm ```

otcat write safety demo

## 📄 输出格式 | 标志 | 格式描述 | 典型用例 | | :--- | :--- | :--- | | `--json` | 换行符分隔的 JSON 对象 | 管道传输至 `jq`、Web API、日志流水线 | | `--csv` | 标题行 + CSV 数据行 | 电子表格导出与历史审计 | | `--raw` | 纯数字标量值 | Shell 算术、`awk`、`bc`、`tee` |

otcat piping into awk and jq demo

## 🚦 退出码 | 代码 | 含义 | 原因 | | :---: | :--- | :--- | | **`0`** | **成功** | 查询或写入顺利完成 | | **`1`** | **用法错误** | 标志无效,寄存器地址规范格式错误 | | **`2`** | **连接错误** | 超时、网络不可达、拒绝连接 | | **`3`** | **协议错误** | PLC 返回了 Modbus 异常 PDU | | **`4`** | **写入中止** | 安全确认被拒绝 | | **`5`** | **I/O 错误** | 输出管道破裂 | | **`130`** | **被中断** | `--watch` 数据流被 SIGINT / SIGTERM 终止 | ## 🐍 Python 绑定 `otcat` 提供了一个官方的 Python 包,封装了编译好的 Go 核心二进制文件,且没有任何额外依赖: ``` from otcat import Client # 连接到目标 PLC c = Client("192.168.1.10:502") # 单次读取查询 val = c.read("holding:40001") print(val.value, val.quality, val.ts) # 流式传输连续遥测数据 for item in c.watch("holding:40001", interval="500ms", count=10): print(item.ts, item.value) ``` ``` pip install otcat # Core client pip install otcat[pandas] # + DataFrame helpers pip install otcat[fastapi] # + Async WebSockets client ``` 有关完整的 Python 文档,请参见 [`python/README.md`](python/README.md)。 ## 🧪 测试与基准测试 ``` # 运行完整的单元与集成测试套件 go test ./... # Race detector + 代码覆盖率 go test ./... -race -cover # 运行延迟基准测试 go test ./... -bench=. -benchmem # Coverage-guided fuzzing go test ./internal/modbus/ -fuzz=FuzzDecodeMBAP -fuzztime=60s ``` ## 📁 项目布局 ``` . ├── cmd/ │ ├── otcat/ # Primary CLI binary │ ├── otc/ # Short binary alias │ ├── otcat-mockplc/ # Standalone Modbus TCP mock server │ └── otcat-latencyprobe/ # Latency measurement tool ├── internal/ │ ├── modbus/ # Modbus TCP driver implementation │ ├── codec/ # JSON, CSV, and Raw formatters │ ├── watch/ # Watch loop & exponential backoff │ └── cliapp/ # CLI flags & safety confirmation gates ├── docs/ # Technical design decision write-ups ├── python/ # Python package bindings ├── demo/ # Terminal GIF recordings & VHS tapes └── assets/ # Brand assets & logos ``` ## 📄 许可证 基于 **MIT License** 分发。详情请见 [`LICENSE`](LICENSE)。

QuitOperation 创建 — 拒绝臃肿的供应商软件,实现工业级 I/O。

标签:EVTX分析, Go, impacket, PLC, Python, Ruby工具, 工业互联网, 工控系统, 无后门, 日志审计, 请求拦截, 逆向工具