zoukankan      html  css  js  c++  java
  • pcap文件格式和wireshark解析

    pcap文件头

    pcap文件头参见官方说明 http://www.winpcap.org/docs/docs_412/html/structpcap__file__header.html

    用python代码表达结构如下,I是32位无符号数,下面的定义均采用32位方式

    # bpf_u_int32 magic;  固定为0xA1B2C3D4,表示pcap包文件
    # u_short version_major; 主版本号
    # u_short version_minor; 分支版本号
    # bpf_int32 thiszone; 时区
    # bpf_u_int32 sigfigs;
    # bpf_u_int32 snaplen; 每个包的最大长度
    # bpf_u_int32 linktype; 链路层协议族
    self.struct_pcap_file_header = '!I2H4I'
     

    pcap每个包的头

    参见  http://www.winpcap.org/docs/docs_412/html/structpcap__pkthdr.html
    # struct timeval ts;
    # bpf_u_int32 caplen;
    # bpf_u_int32 len;
    self.struct_pcap_pkthdr = '!4I'
    timeval是c的时间戳结构体,前面一个整型数是秒数偏置,后面一个整型数是微秒偏置,详情可以查阅相关文档
     

    生成pcap文件

    使用python简单生成,写入到test.pcap文件,写入了两个包到该文件,linktype设置为162,在wireshark源码中表示保留给用户的USER15 类型

    # -*-coding:utf-8-*- 
    """
    Author:yinshunyao
    Date:2017/3/24 0024上午 10:47
    """
    import unittest
    import struct


    class PacpTest(unittest.TestCase):
    def setUp(self):
    # pcap文件头格式
    # http://www.winpcap.org/docs/docs_412/html/structpcap__file__header.html
    # bpf_u_int32 magic; 固定为0xA1B2C3D4,表示pcap包文件
    # u_short version_major; 主版本号
    # u_short version_minor; 分支版本号
    # bpf_int32 thiszone; 时区
    # bpf_u_int32 sigfigs;
    # bpf_u_int32 snaplen; 每个包的最大长度
    # bpf_u_int32 linktype; 链路层协议族
    self.struct_pcap_file_header = '!I2H4I'
    # pcap包头格式
    # http://www.winpcap.org/docs/docs_412/html/structpcap__pkthdr.html
    # struct timeval ts;
    # bpf_u_int32 caplen;
    # bpf_u_int32 len;
    self.struct_pcap_pkthdr = '!4I'

    # 文件头
    self.file_header = struct.pack(
    self.struct_pcap_file_header,
    0xA1B2C3D4, 4, 1, 0, 0, 0xFFFF, 162 # USER15
    )

    def test_generate_pcap(self):
    # 消息体内容
    pkg_content1 = struct.pack('!2I', 100, 101)
    pkg_content2 = struct.pack('!2I', 101, 100)
    #
    pkg_header = struct.pack(
    self.struct_pcap_pkthdr, 0x4A5B1784, 0x00081C6D,
    len(pkg_content1), len(pkg_content1)
    )
    with open('test.pcap', 'wb') as test:
    test.write(self.file_header+pkg_header+pkg_content1+pkg_header+pkg_content2)

    wireshark解析效果

    用自定义的wireshark插件协议解析整体效果如下,后面具体介绍插件内容,可以看到Encapsulation type字段值是60,协议是USER15

    这个值跟前面文件头里面的link162的映射关系,在wireshark中完成,具体处理可以查看wireshark的C源码。

    协议名称和消息体解析,需要捕获这个数据流在自定义的协议插件中处理,下一章会提到。

    两个包的时间戳一样,是因为前面写入文件的包头是一样的。

    image

    wireshark lu解析脚本

        local serial_encap_table = DissectorTable.get("wtap_encap")
        --截取所有的bsap协议
        --USER0~USER15是45到60,可以自定义解析,参见源码wtap.h
        serial_encap_table:add(60, p_bsap)

    上面两行代码,截取type为60的文件和包进行解析。p_bsap是自定义的解析插件,详细的使用方法和语言基础参见wireshark的官方文档lu部分

    do
        --协议名称是BSAP, 在Packet Details窗格显示为
        local p_bsap = Proto("bsap2","Bristol Standard Asynchronous Protocol")
       
       
        --头协议各个字段含义,需要放到此处注册
        local f_src = ProtoField.uint32("bsap2.src","Source", base.DEC)
        local f_des = ProtoField.uint32("bsap2.des","Destination", base.DEC)
        p_bsap.fields = {f_src, f_des}   
       
        --指纹信息协议
        local p_finger = Proto("BSAP_FR", "BSAP Device Information")
       
        --获取数据
        local data = Dissector.get("data")
       
        local device = {}
       
        local offset = 0
       
        --数据分析函数
        local function bsap_dissector(buf,pkg,root)
            local buf_len = buf:len()
            -- 协议信息展示a
            pkg.cols.protocol = "BSAP2"
            --添加头
            local header = root:add(p_bsap, buf)   
            header:add(f_src, buf(0,4))
            header:add(f_des, buf(4,4))
            device = {['Source']=buf(0,4):uint()}
            pkg.cols.info = "Message: src is "..tostring(device['Source'])
            offset = buf_len
            return true
        end   
       
        --解析函数,注意,该function前面不能添加local
        function p_bsap.dissector(buf,pkg,root)
            --如果解析符合本协议
            if bsap_dissector(buf,pkg,root) then
                --有效的协议,未处理完的字段调用其他协议继续解析
                local buf_len = buf:len()
                if offset + 1 < buf_len then
                    data:call(buf(offset, buf_len-offset), pkg, root)
                end
               
            --如果解析不符合本协议,返回给主程序继续遍历其他协议
            else
                data:call(buf,pkg,root)
            end
        end
       
        local serial_encap_table = DissectorTable.get("wtap_encap")
        --截取所有的bsap协议
        --USER0~USER15是45到60,可以自定义解析,参见源码wtap.h
        serial_encap_table:add(60, p_bsap)
    end

     
     
     
     
     
     
     
    好记性不如烂笔头
  • 相关阅读:
    java基础 ——String类型
    WinSCP密钥登录,实现文件上传
    linux 文件压缩,以及解压
    win10的资源管理器,边框不见了
    在360浏览器中打开表单,回显错误数据
    java返回数据工具类
    WEB工具类
    JSON 的几种转换
    二维码生成工具类
    XML的几种转换
  • 原文地址:https://www.cnblogs.com/inns/p/6611136.html
Copyright © 2011-2022 走看看