mavlink 是广泛应用于无人机,无人汽车等设备之间通讯协议,可以运行在串口,网络以及电传设备之上。相信无人机行业小伙伴相当熟悉。
但是在无人机开发时,虽然可以通过各种各样的日志事后查看,往往缺少一个实时监控和查看mavlink协议的工具。而网络抓包软件Wireshark可以通过lua插件的形式增加对Mavlink的包的解析,这样就可以变成一个实时调试工具了。

如果你是用于sitl仿真,各个软件用tcp或udp来分析,或者是地面站用udp接收mavlink数据就可以直接用wireshark抓包。
如果是采用象采用PX4的usb串口线,可以用wireshark的usb抓包功能进行分析。
因此这个方案的应用场景还是很广泛的。
lua是一种可以嵌入在C/C++动态脚本,常用于游戏脚本,这里wireshark采用它作为自己的插件语言。
一. 生成mavlink插件
在mavlink官方有一个文档详细介绍如何让wireshark与mavlink配合建议先读一下

生成插件需要安装mavlink官方软件,步骤如下
下载源码
git clone https://github.com/mavlink/mavlink.git –recursive
下载依赖的python包
cd mavlink
python3 -m pip install -r pymavlink/requirements.txt
生成你的无人机mavlink协议的lua版
在mavlink 目录下
cd mavlink
python3 -m pymavlink.tools.mavgen –lang=WLua –wire-protocol=2.0 –output=<lua文件名> <使用的mavlink头文件中的common.xml的路径>
假设我的mavlink的定义文件是
/home/vagrant/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/common.xml生成文件是 mavlink_2_common.lua ,这个语句将如下编写
python3 -m pymavlink.tools.mavgen –lang=WLua –wire-protocol=2.0 –output=mavlink_2_common /home/vagrant/PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/common.xml
成功后在当前目录会生成 mavlink_2_common.lua
增加mavlink端口
这一步是把你用mavlink通讯端口加入mavlink的协议解析,这样所有在这个端口上的包会自动解析成mavlink包。
打开mavlink_2_common.lua 的后面,
可以看到,现在默认把所有udp 14550,14580 ,18570 均作为mavlink端口
— bind protocol dissector to ports: 14550, 14580, 18570 local udp_dissector_table = DissectorTable.get(“udp.port”) udp_dissector_table:add(14550, mavlink_proto) udp_dissector_table:add(14580, mavlink_proto) udp_dissector_table:add(18570, mavlink_proto)现在我们把自己常用的sitl的tcp端口加入mavlink,在最后增加如下两句
local tcp_dissector_table = DissectorTable.get(“tcp.port”) tcp_dissector_table:add(4560, mavlink_proto) tcp_dissector_table:add(5760, mavlink_proto)二. 安装插件
Linux 把lua文件拷贝到
~/.local/lib/wireshark/plugins/mkdir -p /root/.local/lib/wireshark/plugins
cp mavlink_2_common.lua ~/.local/lib/wireshark/plugins/
windows拷入 wireshark安装目录的plugins 目录下
验证插件是否安装成功,可以打 help–>about 中的plugins 页看是不是有 mavlink_2_common.lua

在Linux 下有一个重要权限问题,如果要对某个硬件进行捕获,必须有root权限,但用sudo 运行可以捕获数据,但是无法看到mavlink_2_common插件。
所以解决办法是把当前用户加入wireshark组。步骤如下:
添加wireshark用户组sudo groupadd wireshark
将dumpcap更改为wireshark用户组sudo chgrp wireshark /usr/bin/dumpcap
让wireshark用户组有root权限使用dumpcapsudo chmod 4755 /usr/bin/dumpcap
将需要使用的用户名加入wireshark用户组,我的用户名是vagrantsudo gpasswd -a vagrant wireshark
这样在当前用户就能捕获硬件数据也能使用插件。
三. 使用Wireshark分析
首先选择要捕获的网卡,如果是本机通讯则使用本地回环网卡 Loopback:lo.
在捕获包时,可以加入过滤条件,比如在 tcp的4560端口捕获并按mavlink解析
tcp.port == 4560 && mavlink_proto
可以看到能认识的mavlink都解析出来


还有一个常用的几个过滤条件,只显示 253 消息
tcp.port == 4560 && mavlink_proto.msgid == 253
四.扩展应用
带宽分析
可以打开Statistics –> I/O Graphs 可以进行mavlink的带宽分析

使用tcpdump 捕获文件后给wireshark分析
sudo apt update sudo apt install tcpdump sudo tcpdump -i eth0 -w mavlink-capture.pcap上述语句就是从eth0抓包保存在mavlink-capture.pcap
远程抓包
在就远端采用tcpdump抓包,然后建立ssh通道转发到本地用wireshark实时分析
mkfifo /tmp/mavlink; wireshark -k -i /tmp/mavlink & ssh root@10.41.1.1 -p 33333 “tcpdump -s 0 -U -n -w – -i lo not port 33333” > /tmp/mavlink; mkfifo /tmp/mavlink创建用于流式传输数据的命名管道。wireshark -k -i /tmp/mavlink &启动 Wireshark,打开命名管道作为输入并立即开始捕获。在远程计算机上启动数据流,并将其通过管道传输到本地计算机上的命名管道中。-s 0将快照长度设置为默认值-U流数据包输出数据包缓冲,无需等待已满缓冲区-n不要将地址(即主机地址、端口号等)转换为名称-w -将原始数据写入标准输出(通过管道传输到本地计算机)-i lo定义要侦听的接口。这将侦听环回接口,您可以将其更改为以太网、USB 或调制解调器接口。not port 33333不要捕获 SSH 会话创建的数据。您可以向 tcpdump 添加更多筛选器以减少流数据。