5

基于 go 的 wireshark 插件实现方案

 2 years ago
source link: https://forrestsu.github.io/posts/network/wireshark-go-plugin/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

基于 go 的 wireshark 插件实现方案

2020年12月8日
| 字数 1040

在业务服务重构过程中,发现后台一些RPC服务,使用的自定义的应用层协议(七层)。 为了方便验证重构逻辑,想在在海量的请求中,快速找到某一类业务请求包。

一般来说简单的协议使用 lua 实现即可,但是遇到 pb/thrift 等 tlv 类型的协议就比较麻烦了; 比较友好的是,目前有 lua-protobuf 这样的库,可以在lua中解析PB协议, 只需要提供proto即可;

但是对于内部的 tlv 协议,由于本人不太会使用lua去封装c库;

突然萌生了一个想法,能不能用 golang 来开发 wireshark 插件? 是否可以让 lua5.2 直接调用cgo?

3 定制目标(okr)

定位: 本地的报文分析工具

  • 1 当业务遇到一种业务的字节协议时,可快速在 wireshark 中解析,展示;
  • 2 支持使用 go 实现包解析;
  • 3 对解析性能要求(1000条/s即可),准确解析;

4 思考方案

采用lua可快速实现一个简单的 wireshark 插件,快捷高效,官方文档也比较完善。 调试验证脚本也比较方便,重新加载即可生效,无需编译。 但是在工作中,有各种各样的 tlv 类型协议接口(历史原因),lua在tlv类型的协议解析上就显得有点吃力。

4.1 那么怎么解决这类问题呢?

既然 lua 作为胶水语言,我们把 lua 当作入口,然后调用 go 的动态库。 同时业务也有各种协议的编解码包,对接新的协议可谓是顺风顺水呀! 能不能直接复用呢? 经过一番折腾,没有成功 :(

4.2 退一步海阔天空

当然我们不能气馁,不行就退一步,折中一下,能不能把c 也当做一个入口(桥梁);
链路:lua -> c -> go, 因为这两个环节是相当成熟的,初步评估可行,于是写代码验证。

5 代码实现

wireshark_plugin

5.1 插件效果

5.2 Benchmark

整体性能还不错,比预想的高10倍^_^。

记录条数: 96180 条
文件总大小: 44 M
单个报文大小:300 ~ 500 bytes
解析耗时: 9.479s
平均速率: 1 W/s
time tshark -r udp.cap > /dev/null
#  9.479s real      9.05s user      0.94s sys

探索了一种跨语言编程方式,结合多种语言的特性,最终将一个想法落地实现。 在解决问题方面:尝试用已有技能,解决不同问题,能力提升。

解决的一些问题

在编写插件过程中,也遇到和解决了不少问题,系列文章如下:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK