Lua和Wireshark配合,调试通信程序

对于网络通信程序的调试,我们一般是这样进行的:


                     客户端                                                                       服务器端

               打印发送数据
                          |
          使用socket发送数据                 -------------->                使用socket接受数据
                          |                                                                                   |
               打印发送结果(发送的字节数)                                打印接收到的数据


    上面的测试方法,需要对程序添加打印代码,并且每次改动调试信息时,都需要重新编译程序,较为繁琐,效率低。为了查看数据包的内容,我们需要做很多的打印操作,并且还要在log中通过关键字来查找打印的内容。


    Wireshark是网络抓包,并对包进行分析的软件。通过调用pcap库,它可按照我们的需求,抓取各种数据包。
    默认情况下,Wireshark可对各种流行的通信协议进行解包,能够在窗口中清晰的看到通信协议中每个段的值。但是当我们使用自己的通信协议时,wireshark只能识别到TCP/UDP协议,我们的数据内容无法识别,只能在窗口中的Data段中显示原始数据,我以前都是能通过偏移,来与自己程序中的数值进行一一比较,以检测自己的程序所发送的数据是否正确。
    由于受不了数偏移,比对结构体的繁琐,前阵子准备好好看看wireshark的使用,总感觉这么成熟的软件,不会只能�胀ǖ耐ㄐ判榻薪獍2榭词褂檬植幔唬诘谑隆盠ua Support in Wireshark“中有对此功能的描述。只要用lua写一个脚本,并在程序启动时调用即可(这些,在手册中都有说明)。
    举个例子,假如我们使用结构体进行通信,众多消息结构体中,有如下一个:

复制代码
  1. struct student{    char name[16];    uint32_t     age;    uint32_t     grade;};

   写一个lua脚本来解析包中的这部分内容(假设我们使用UDP协议,12000端口):
复制代码
  1. do        local p_student = Proto("student","student message");
  2. --  创建三个字段,其中,第一个参数为解析时使用的,第二个参数为在窗口中显示的名称,第三个参数(如果有的话)为数据类型。        local f_name = ProtoField.string("student.name", "Name")        local f_age = ProtoField.uint32("student.age", "Age", base.DEC)        local f_grade = ProtoField.uint32("student.grade", "Grade", base.DEC)
  3.         p_student.fields = {                     f_name,                     f_age,                     f_grade        }
  4.         local data_dis = Dissector.get("data")
  5. --   解析数据包时的函数,类似C语言中的回调函数        function p_student.dissector(buf, pkt, root)                local t = root:add(p_iplb, buf(0, 24))   --  udp数据部分的前24个字节,使用student协议解析                t:add(f_name,        buf(0,16))               --  0-16是student.name字段                t:add(f_age,            buf(16, 4))              --  16-20是student.age字段                t:add(f_grade,         buf(20, 4))             --  20-24是student.grade字段
  6.                 data_dis:call(buf(40):tvb(), pkt, root)   --  如果还有剩余数据,作为一般的Data段进行解析        end
  7. --  添加协议及端口号的关联,当遇到符合条件的数据包,wireshark将自动按照此协议进行解析        local udp_encap_table = DissectorTable.get("udp.port")        udp_encap_table:add(12000, p_iplb)     --  12000为我们所使用的端口号
  8. end





    示例脚本中用到了wireshark所提供的API函数,更多信息和函数说明,可参考wireshark自带的使用说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值