QuitOperation/otcat
GitHub: QuitOperation/otcat
otcat 是一款工业级命令行工具,让工程师像使用 netcat 一样在 shell 中直接读取、写入和监控 PLC 的 Modbus TCP 寄存器。
Stars: 1 | Forks: 0
otcat — 工业级 I/O 的 netcat
直接在你的 shell 中读取、写入和监控 PLC 寄存器,就像 nc 检查 TCP socket 一样。
🌐 在线网站 •
📦 包与安装 •
🐍 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?](#-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
```
## 📄 输出格式
| 标志 | 格式描述 | 典型用例 |
| :--- | :--- | :--- |
| `--json` | 换行符分隔的 JSON 对象 | 管道传输至 `jq`、Web API、日志流水线 |
| `--csv` | 标题行 + CSV 数据行 | 电子表格导出与历史审计 |
| `--raw` | 纯数字标量值 | Shell 算术、`awk`、`bc`、`tee` |
## 🚦 退出码
| 代码 | 含义 | 原因 |
| :---: | :--- | :--- |
| **`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工具, 工业互联网, 工控系统, 无后门, 日志审计, 请求拦截, 逆向工具