lua插件示意

-- 1. 创建解析器对象
local NAME = "ctc_operator"  --自定义的协议名
ctcopera_protocol = Proto(NAME, "ctc_operator Protocol")


local VALS_DATA_TYPE  = {[0x31] = "排路", [0x32] = "单操"}
local VALS_FORCE_TYPE  = {[0] = "非强制", [1] = "强制"}

local VALS_CMD_TYPE  = {[0x05] = "选路", [0x1a] = "进路取消"}

local VALS_SOUTH_BTN_IDS = {[1] = "D101A",[2] = "D103A",[3] = "D105A"}

local VALS_NOUTH_BTN_IDS = {[1]="SLZ,X道岔定操,S道岔定操,S按钮单封,X按钮单封", [2]="SLZ,X道岔反操,S道岔反操,S按钮解封,X按钮解封", [3]="SLF,S道岔单锁,X道岔单锁"}


-- 定义协议的解析字段
local fields = ctcopera_protocol.fields
fields.msg_bit0 = ProtoField.uint8(NAME .. "bit0", "bit0", base.DEC, nil, 0x01) -- 位域定义
fields.msg_bit1 = ProtoField.uint8(NAME .. "bit1", "bit1", base.DEC, nil, 0x02) -- 位域定义
fields.msg_bit2 = ProtoField.uint8(NAME .. "bit2", "bit2", base.DEC, nil, 0x04) -- 位域定义
fields.msg_bit3 = ProtoField.uint8(NAME .. "bit3", "bit3", base.DEC, nil, 0x08) -- 位域定义
fields.msg_bit4 = ProtoField.uint8(NAME .. "bit4", "bit4", base.DEC, nil, 0x10) -- 位域定义
fields.msg_bit5 = ProtoField.uint8(NAME .. "bit5", "bit5", base.DEC, nil, 0x20) -- 位域定义
fields.msg_bit6 = ProtoField.uint8(NAME .. "bit6", "bit6", base.DEC, nil, 0x40) -- 位域定义
fields.msg_bit7 = ProtoField.uint8(NAME .. "bit7", "bit7", base.DEC, nil, 0x80) -- 位域定义

fields.msg_type = ProtoField.uint8(NAME .. "MSG_TYPE", "类型", base.DEC, VALS_DATA_TYPE)
fields.stn_id = ProtoField.uint16(NAME .. "STN_ID", "站码", base.DEC)
fields.south_btn_bgn_id = ProtoField.uint16(NAME .. "BTN_BGN_ID", "始端按钮", base.DEC, VALS_SOUTH_BTN_IDS, 0x7FFF)
fields.south_btn_end_id = ProtoField.uint16(NAME .. "BTN_END_ID", "终端按钮", base.DEC, VALS_SOUTH_BTN_IDS, 0x7FFF)
fields.south_btn_chg_id = ProtoField.uint16(NAME .. "BTN_CHG_ID", "变更按钮", base.DEC, VALS_SOUTH_BTN_IDS, 0x7FFF)
fields.south_btn_id = ProtoField.uint16(NAME .. "BTN_ID", "按钮", base.DEC, VALS_SOUTH_BTN_IDS, 0x7FFF)

fields.nouth_btn_bgn_id = ProtoField.uint16(NAME .. "BTN_BGN_ID", "始端按钮", base.DEC, VALS_NOUTH_BTN_IDS, 0x7FFF)
fields.nouth_btn_end_id = ProtoField.uint16(NAME .. "BTN_END_ID", "终端按钮", base.DEC, VALS_NOUTH_BTN_IDS, 0x7FFF)
fields.nouth_btn_chg_id = ProtoField.uint16(NAME .. "BTN_CHG_ID", "变更按钮", base.DEC, VALS_NOUTH_BTN_IDS, 0x7FFF)
fields.nouth_btn_id = ProtoField.uint16(NAME .. "BTN_ID", "按钮", base.DEC, VALS_NOUTH_BTN_IDS, 0x7FFF)

fields.cmd_type = ProtoField.uint8(NAME .. "CMD_TYPE", "命令类型", base.DEC, VALS_CMD_TYPE)
fields.btn_num = ProtoField.uint8(NAME .. "BTN_NUM", "按钮数", base.DEC)
fields.force_type = ProtoField.uint8(NAME .. "FORCE", "是否强制排路", base.DEC, VALS_FORCE_TYPE)





-- 2. 解析器函数 dissect packet 
--[[
    下面定义解析器的主函数,这个函数由 wireshark调用
    第一个参数是 buffer 类型,表示的是需要此解析器解析的数据
    第二个参数是 pinfo 类型,是协议解析树上的信息,包括 UI 上的显示
    第三个参数是 tree 类型,表示上一级解析树
--]]
function ctcopera_protocol.dissector(buffer, pinfo, tree)
    length = buffer:len()
    if length == 0 then
        return
    end
    
    -- 分组详情中协议行显示的协议名
    pinfo.cols.protocol = ctcopera_protocol.name
    
    
   --从根树上创建一个子树打印解析的消息数据
    local subtree = tree:add(ctcopera_protocol, buffer(), "单操命令")
    
    offset = 0
    header_len = 4
    tail_len = 4
    data_len = length - header_len - tail_len -- sdi数据长度,去掉包头,包尾

    
    -- 包头
    --local msg_head_tree = subtree:add(ctcopera_protocol, buffer(offset, header_len), "包头")
    offset = offset + header_len
    
    -- 正文
    local msg_data_tree = subtree:add(ctcopera_protocol, buffer(offset, data_len), "正文")
    
    -- 数据类型
    local msg_type  = buffer(offset, 1):uint()
    msg_data_tree:add(fields.msg_type, buffer(offset, 1))
    offset = offset + 3
            
    -- 站码
    local stn_id  = buffer(offset, 2):uint()
    msg_data_tree:add_le(fields.stn_id, buffer(offset, 2))
    offset = offset + 2

    if (0x31 == msg_type) then
        -- 跳过命令号
        offset = offset + 8
        
        -- 是否强制排路
        msg_data_tree:add(fields.force_type, buffer(offset, 1))
        offset = offset + 1
        
        -- 始端按钮
        if (0xae01 == stn_id) then
            msg_data_tree:add_le(fields.nouth_btn_bgn_id, buffer(offset, 2))
        else
            msg_data_tree:add_le(fields.south_btn_bgn_id, buffer(offset, 2))
        end
        offset = offset + 2
        
        -- 终端按钮
        if (0xae01 == stn_id) then
            msg_data_tree:add_le(fields.nouth_btn_end_id, buffer(offset, 2))
        else
            msg_data_tree:add_le(fields.south_btn_end_id, buffer(offset, 2))
        end
        offset = offset + 2
        
        -- 变更按钮
        local chg_btn_num = buffer(offset, 1):uint()
        msg_data_tree:add(fields.btn_num, buffer(offset, 1))
        offset = offset + 1
        
        for i=0, chg_btn_num-1 do
            if (0xae01 == stn_id) then
                msg_data_tree:add_le(fields.nouth_btn_chg_id, buffer(offset, 2))
            else
                msg_data_tree:add_le(fields.south_btn_chg_id, buffer(offset, 2))
            end
            offset = offset + 2
        end
    elseif (0x32 == msg_type) then
        -- 跳过命令号
        offset = offset + 4
        
        -- 命令类型
        msg_data_tree:add_le(fields.cmd_type, buffer(offset, 1))
        offset = offset + 1
        
        -- 是否强制排路
        msg_data_tree:add(fields.force_type, buffer(offset, 1))
        offset = offset + 1
        
        -- 变更按钮
        local btn_num = buffer(offset, 1):uint()
        msg_data_tree:add(fields.btn_num, buffer(offset, 1))
        offset = offset + 1
        
        for i=0, btn_num-1 do
            if (0xae01 == stn_id) then
                msg_data_tree:add_le(fields.nouth_btn_id, buffer(offset, 2))
            else
                msg_data_tree:add_le(fields.south_btn_id, buffer(offset, 2))
            end
            offset = offset + 2
        end
        
    end

        
    -- 包尾
    --local msg_tail_tree = subtree:add(ctcopera_protocol, buffer(offset, tail_len), "包尾")



end

-- 监听集表示数据,端口为8111
local udp_port = DissectorTable.get("udp.port")
udp_port:add(8111, ctcopera_protocol)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容