在 IoTSploit Toolkit 中监控 CAN 总线并发送报文
CAN Bus Monitor 把一个 SocketCAN 接口放到界面上。你可以选择报文的来源——实时总线、录制日志,或不做解码的原始套接字——页面随即显示其承载的流量。若所选目标记录了自己的 CAN 总线,同一页面还会把每一帧解码成信号值;另一个独立的编辑器则负责向总线上发送一帧经过校验的报文。

可用范围与前提
Section titled “可用范围与前提”CAN Bus Monitor 是仅限桌面版的工具:它依赖操作系统的 SocketCAN 套接字以及拥有这些套接字的后端,因此 Web、Android 和 iOS 版本不会显示它。入口在 Toolkit → CAN Bus Monitor。
要让它真正可用,需要三件事:
- 内核能识别的 SocketCAN 接口。 在 Linux 上,这可以是物理适配器(PEAK、Kvaser、8devices USB2CAN 等),也可以是虚拟的
vcan接口。适配器必须在 IoTSploit 之外先行启用并配置比特率——应用只读取链路,从不配置它。 - 后端启用了
drv_socketcan设备驱动。 扫描接口、打开总线、转发报文的都是这个驱动。 - IoTSploit 服务可访问。 设备列表、命令接口、插件和报文流都运行在后端,而不是 UI 进程里。
本页用到的后端接口
Section titled “本页用到的后端接口”排查部署问题时,界面背后调用的是这些接口:
| 用途 | 接口 |
|---|---|
列出设备(页面只保留动态的 SocketCAN_* 条目) | POST /api/list_devices/ |
| 在接口上 start、stop、dump 或 send | POST /api/execute_device_command/drv_socketcan/ |
| 单个设备的原始报文 | WebSocket /ws/device/stream/<device_id>/ |
| 实时解码采集或日志回放 | POST /api/execute_plugin/,使用 CAN Live Capture 插件 |
| 解码后的采集快照 | WebSocket /ws/device/stream/can_capture_<bus_id>/ |
| 预览或发送目标定义的帧 | POST /api/execute_plugin/,使用 CAN Frame Composer 插件 |
| 用目标的总线为流量或日志打分 | POST /api/identify_can_bus/ |
| 读取日志的格式与通道 | POST /api/inspect_can_log/ |
选择来源并连接
Section titled “选择来源并连接”左上角的选择器决定整个页面做什么。它有三个取值,并且只保留该取值真正会用到输入项。
- Live bus——读取正在运行的接口,并按目标解码。除设备外,还需要 Decode target 和 Bus。
- Recorded log——回放
.asc、.blf、.log或.trc文件并解码。文件会上传到后端,并在播放前先被打分。 - Raw——不选目标、不解码地读取报文,并可发送手写的帧。没有可解码的定义时,这是兜底选项;选择它是明确的动作,而不是”没选到目标”的意外结果。
无论选择哪种来源,Raw 模式下的帧只被当作字节;同样的字节在 Live bus 模式下会去目标定义中查找。这正是本页的核心区别,也是运行期间来源选择器会被禁用的原因。
接口与连接状态
Section titled “接口与连接状态”Source device 列表中是后端扫描到的接口,已筛选为动态的 SocketCAN_* 条目。每一行是一个 device_id(例如 vcan_001)和一个接口名(例如 vcan0);表头上方显示流量表所绑定的接口,未绑定时显示 no interface。
表格上方的一条信息栏按内核的实际情况报告链路:
vcan/vxcan显示 virtual interface,物理适配器显示 hardware interface;- 已配置的比特率,未配置时显示
bitrate not configured; - 依据接口 MTU 显示 CAN FD 或 classic;
- 一个控制器状态标签:
ERROR-ACTIVE表示健康,ERROR-WARNING表示告警,ERROR-PASSIVE或BUS-OFF按错误显示。
比特率和 FD 模式被刻意设为只读。它们属于主机配置,界面上的控件只能谎称自己改动了它。将鼠标悬停在信息栏上会显示真正负责配置它们的命令,例如:
sudo ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on要打开原始会话,选择设备并点击 Open port。页面先请后端启动驱动,再打开报文套接字。端口打开期间页脚显示 Connected · N identities,关闭后显示 Disconnected;Close port 会停止驱动并关闭套接字。
要进行解码会话,选择 Decode target 和 Bus,然后点击 Start monitor。页面以 monitor 模式运行 CAN Live Capture 插件,并跟随它的快照流。页脚显示 Monitoring · N frames;Stop monitor 会取消后端执行。
当一个目标记录了不止一条 CAN 总线时,Bus 字段旁会出现雷达按钮。Identify bus 会用线上的实际情况——六秒实时流量,或整个日志——去为目标的每条总线打分,并报告命中的观测 ID 数量。选错总线不会报错,它会把每一帧都解码成一个看似合理的错误值,因此在你信任某个解码结果前,值得先做这一步。字段旁的提示随后会说明该总线是自动选择、手动选择,还是识别得出的。
Raw 模式的表格有四列:
| 列 | 含义 |
|---|---|
| ID | 驱动报告的十六进制仲裁 ID(如 0x123)。 |
| Frame count | 自表格开始以来该 ID 的到达帧数。 |
| DLC | 最近一帧的数据长度码。 |
| Data | 十六进制的负载字节。 |
帧按 ID 折叠:同一 ID 重复到达时只更新一行并累加计数,而不是新增一行。表格只保留最近 100 个身份,因此再繁忙的总线也不会让表格无限增长。空状态会区分两种关键情况:连接前是 Open the port to monitor raw CAN traffic.,连接后则是 No frames seen yet.,此时总线只是安静而已。
在 Live bus 或 Recorded log 模式下,表格信息更丰富。每一行显示帧 ID、来自目标的消息名(目标没有对应定义时显示 Undocumented)、实测周期、计数和最后一次负载。选中某一行会打开检查器,显示解码后的信号及其值。表格上方的合计显示 N frames · N ids · N undocumented,未记录的 ID 会作为一项发现保留,而不是被隐藏。
切换来源会清空解码表并重置本次运行的合计与总线故障提示;更换目标或总线会重置解码视图,避免一条总线的流量显示在另一条总线的定义之下。只要页面保持打开,原始表会保留它已经见过的身份。原始发送被确认后,编辑器会清空 Data 字段,以防同一个负载被误发第二次;ID 和 DLC 保持不变。
当来源为 Raw 且端口已打开时,应用栏中的编辑按钮会打开原始编辑器。它有三个字段:
- CAN ID (hex)——例如
7DF。 - Data length (DLC)——
1到8之间的数字。 - Data (hex)——完整的字节,例如
0102030405060708。
在服务器确认之前,任何东西都不会发出去。页面会在帧到达套接字之前先做校验,每一条检查都有其理由:否则远端会把一个坏请求变成堆栈跟踪,或发出一帧长度并非你本意的报文:
- ID 必须是十六进制;
- DLC 必须是
1到8之间的整数; - 数据必须是偶数个十六进制字符;
- 数据字节数必须与 DLC 一致。
如果服务器拒绝该帧(ID 非法、负载被拒、驱动无法发送),编辑器会显示原因并保持打开。如果五秒内没有收到确认,它会如实说明,而不是报告成功:No confirmation came back within 5s; the frame may not have been sent. 只有确认发送成功,对话框才会关闭。
该编辑器发送的是标准、经典 CAN 帧。扩展 ID 和 CAN FD 由面向目标的编辑器与驱动处理,不在此对话框中。
收到帧并不等于知道它的含义
Section titled “收到帧并不等于知道它的含义”原始的 ID 和字节本身并不自解释。0x123 加上 DE AD BE EF 在线上只是四个字节,除非有定义说明每一位是什么,否则它没有任何含义。从原始流量里猜测含义就是臆测,而一个看似自信的猜测比坦率承认未知更糟。
只有你给出目标时,页面才会解码。目标的 CAN 定义——以 DBC、ARXML 导入,或属于目标模型的一部分——提供帧名、信号布局、缩放和单位。选定目标后,每一帧都会按该目标的总线查找并解码;没有目标时,Raw 表格显示的就是实际到达的内容。
即使选定了目标,下面两类发现也不是错误,会按原样显示:
- undocumented——目标在该总线上没有记录这个 ID 对应的帧。流量是真实的,只是目标尚未描述它。
- decode failed——ID 已知,但字节无法解码,并会显示原因。
解码的可信度取决于目标本身。比特率、采样点以及录制设置都决定了这些字节是否就是发送方本意的字节,而选错总线会得到一个错误却看似合理的解码结果。请把解码值当作待确认的假设,而不是事实。
总线故障与流量分开处理。SocketCAN 套接字会把控制器故障和数据一起送达,而错误帧在数据帧放地址的位置放的是错误类别。页面绝不会把错误帧列为帧,而是显示 Bus fault: <描述> (次数),这正是”总线安静”与”控制器根本读不了总线”之间的区别。
面向目标发送
Section titled “面向目标发送”对于目标已定义的帧,编辑按钮会打开另一个编辑器。它基于目标的目录逐信号工作:选择帧、填写每一个活动信号(全部必填),然后预览。预览会解析并编码该帧并返回确切的字节,而不接触硬件——即使主机没有任何 CAN 接口也能工作。
发送需要基于当前表单的新鲜预览。每次预览都会带一个摘要,覆盖目标、帧定义、信号值、结果字节和通道。若预览与发送之间任何一项发生变化,摘要就不再匹配,发送会被拒绝,而不会把与你批准的字节不同的内容放到线上。如果目标未被标记为 active,编辑器会警告其拓扑可能只是不完整的片段,并要求单独确认后才能发送。
摘要是一致性校验,不是授权。它不是一次性令牌,重复一次已确认的调用就会再发一帧。认证与限流属于部署层面的问题。请务必在 IoTSploit 之外启用接口并设置比特率;编辑器不会改动链路配置。
- 仅限桌面版,不支持 Web、Android 和 iOS。
- 链路的比特率、FD 模式与上下线状态属于主机配置,在此只读。
- 同一时刻应由一个进程独占接口;第二个读取方可能与正在进行的采集或编辑会话冲突。
- 解码值的可信度取决于目标的定义和你所选的总线。
- 发送成功只意味着字节已离开套接字,它不是安全性或兼容性的结论。
| 现象 | 检查项 |
|---|---|
| Source device 列表为空 | 接口是否作为动态 SocketCAN_* 设备存在;运行 ip link 确认其已启用 |
Open port 失败 | 后端无法打开接口;确认 drv_socketcan 已启用且接口名正确 |
页脚一直显示 Disconnected | 报文套接字未打开;确认服务可达且 device_id 仍然有效 |
| 连接后没有报文 | 总线安静、比特率/终端电阻不对,或对端没有在发送 |
显示 bitrate not configured | 在 IoTSploit 之外配置链路,然后重新打开端口 |
出现 Bus fault: … | 这是控制器故障而非流量;检查接线、终端电阻与比特率 |
某帧显示 Undocumented | 目标在该总线上没有该 ID 的定义;导入定义后即可解码 |
| 发送返回校验信息 | 按提示修正 ID、DLC 或数据的长度/格式不一致 |
| 发送提示可能未发出 | 五秒内没有收到确认;检查后端与接口 |
实验环境验证
Section titled “实验环境验证”接收与发送路径已在一台隔离的虚拟总线上复现,全程未涉及车辆或适配器:
- 创建并启用
vcan0接口(sudo modprobe vcan;sudo ip link add dev vcan0 type vcan;sudo ip link set up vcan0)。虚拟总线会把发出的帧回送给其上的每一个套接字,因此一台机器就能同时充当两端。 - 后端扫描到该接口为
SocketCAN_vcan0(device_id为vcan_001),标记为virtual、支持 FD、无比特率——正是 CAN 页面会列出的内容。 - 接收: 一个独立的对端套接字向总线放入一帧无害报文,ID 为
0x123,数据为DE AD BE EF。drv_socketcan驱动收到并把它归类为数据,字段为id=0x123、data=deadbeef、dlc=4,元数据为interface=vcan0、is_extended_id=false、is_fd=false、is_remote_frame=false。 - 发送: 驱动的
send命令把0x123 / DEADBEEF放回总线,对端套接字成功接收。 - 校验: 不带负载的发送被拒绝,提示
send requires data;不带 ID 的发送被拒绝,提示send requires a CAN id。 - 随后驱动状态显示
interface=vcan0、owns_link=false,表明它使用的是一条并非由自己启用的链路,并保持其原状。
这就是应用在任何 SocketCAN 接口上使用的软件路径。验证它并不需要真实的车辆总线,本次也未连接任何车辆。
要了解 CAN 分析如何与 Toolkit 的其他设备工具配合,请阅读目标与硬件驱动。若想了解每个工具运行在何处,请参阅 IoTSploit UI 功能地图与入门路径。