跳转到内容

在 IoTSploit Toolkit 中监控 CAN 总线并发送报文

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

Live bus 模式下的 CAN Bus Monitor,显示 Live bus / Recorded log / Raw 选择器,Source device、Decode target 与 Bus 字段,CAN-B selected automatically 提示,以及空的流量表

CAN Bus Monitor 是仅限桌面版的工具:它依赖操作系统的 SocketCAN 套接字以及拥有这些套接字的后端,因此 Web、Android 和 iOS 版本不会显示它。入口在 Toolkit → CAN Bus Monitor。

要让它真正可用,需要三件事:

  • 内核能识别的 SocketCAN 接口。 在 Linux 上,这可以是物理适配器(PEAK、Kvaser、8devices USB2CAN 等),也可以是虚拟的 vcan 接口。适配器必须在 IoTSploit 之外先行启用并配置比特率——应用只读取链路,从不配置它。
  • 后端启用了 drv_socketcan 设备驱动。 扫描接口、打开总线、转发报文的都是这个驱动。
  • IoTSploit 服务可访问。 设备列表、命令接口、插件和报文流都运行在后端,而不是 UI 进程里。

排查部署问题时,界面背后调用的是这些接口:

用途接口
列出设备(页面只保留动态的 SocketCAN_* 条目)POST /api/list_devices/
在接口上 start、stop、dump 或 sendPOST /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/

左上角的选择器决定整个页面做什么。它有三个取值,并且只保留该取值真正会用到输入项。

  • Live bus——读取正在运行的接口,并按目标解码。除设备外,还需要 Decode target 和 Bus。
  • Recorded log——回放 .asc、.blf、.log 或 .trc 文件并解码。文件会上传到后端,并在播放前先被打分。
  • Raw——不选目标、不解码地读取报文,并可发送手写的帧。没有可解码的定义时,这是兜底选项;选择它是明确的动作,而不是”没选到目标”的意外结果。

无论选择哪种来源,Raw 模式下的帧只被当作字节;同样的字节在 Live bus 模式下会去目标定义中查找。这正是本页的核心区别,也是运行期间来源选择器会被禁用的原因。

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 模式被刻意设为只读。它们属于主机配置,界面上的控件只能谎称自己改动了它。将鼠标悬停在信息栏上会显示真正负责配置它们的命令,例如:

Terminal window
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 由面向目标的编辑器与驱动处理,不在此对话框中。

原始的 ID 和字节本身并不自解释。0x123 加上 DE AD BE EF 在线上只是四个字节,除非有定义说明每一位是什么,否则它没有任何含义。从原始流量里猜测含义就是臆测,而一个看似自信的猜测比坦率承认未知更糟。

只有你给出目标时,页面才会解码。目标的 CAN 定义——以 DBC、ARXML 导入,或属于目标模型的一部分——提供帧名、信号布局、缩放和单位。选定目标后,每一帧都会按该目标的总线查找并解码;没有目标时,Raw 表格显示的就是实际到达的内容。

即使选定了目标,下面两类发现也不是错误,会按原样显示:

  • undocumented——目标在该总线上没有记录这个 ID 对应的帧。流量是真实的,只是目标尚未描述它。
  • decode failed——ID 已知,但字节无法解码,并会显示原因。

解码的可信度取决于目标本身。比特率、采样点以及录制设置都决定了这些字节是否就是发送方本意的字节,而选错总线会得到一个错误却看似合理的解码结果。请把解码值当作待确认的假设,而不是事实。

总线故障与流量分开处理。SocketCAN 套接字会把控制器故障和数据一起送达,而错误帧在数据帧放地址的位置放的是错误类别。页面绝不会把错误帧列为帧,而是显示 Bus fault: <描述> (次数),这正是”总线安静”与”控制器根本读不了总线”之间的区别。

对于目标已定义的帧,编辑按钮会打开另一个编辑器。它基于目标的目录逐信号工作:选择帧、填写每一个活动信号(全部必填),然后预览。预览会解析并编码该帧并返回确切的字节,而不接触硬件——即使主机没有任何 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 或数据的长度/格式不一致
发送提示可能未发出五秒内没有收到确认;检查后端与接口

接收与发送路径已在一台隔离的虚拟总线上复现,全程未涉及车辆或适配器:

  1. 创建并启用 vcan0 接口(sudo modprobe vcan;sudo ip link add dev vcan0 type vcan;sudo ip link set up vcan0)。虚拟总线会把发出的帧回送给其上的每一个套接字,因此一台机器就能同时充当两端。
  2. 后端扫描到该接口为 SocketCAN_vcan0(device_id 为 vcan_001),标记为 virtual、支持 FD、无比特率——正是 CAN 页面会列出的内容。
  3. 接收: 一个独立的对端套接字向总线放入一帧无害报文,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。
  4. 发送: 驱动的 send 命令把 0x123 / DEADBEEF 放回总线,对端套接字成功接收。
  5. 校验: 不带负载的发送被拒绝,提示 send requires data;不带 ID 的发送被拒绝,提示 send requires a CAN id。
  6. 随后驱动状态显示 interface=vcan0、owns_link=false,表明它使用的是一条并非由自己启用的链路,并保持其原状。

这就是应用在任何 SocketCAN 接口上使用的软件路径。验证它并不需要真实的车辆总线,本次也未连接任何车辆。

要了解 CAN 分析如何与 Toolkit 的其他设备工具配合,请阅读目标与硬件驱动。若想了解每个工具运行在何处,请参阅 IoTSploit UI 功能地图与入门路径。