You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua编写Wireshark dissector:UDP隧道内Ethernet帧解析失败求助

问题描述

我是一名新手,借助ChatGPT编写了一个用于自定义UDP隧道协议的Lua Wireshark dissector。该协议包含两个固定长度字段:24字节的ID、8字节的时间戳,后续为隧道化的Ethernet帧。运行脚本后,预期隧道内的Ethernet帧能被正确解析,但实际它被显示为二进制blob。

原脚本代码

-- Define the protocol
my_proto = Proto("my_proto", "Custom UDP Tunneling Protocol")

-- Define the fields for the protocol
local f_id = ProtoField.string("my_proto.id", "ID", base.ASCII)
local f_timestamp = ProtoField.uint64("my_proto.timestamp", "Timestamp", base.DEC)
local f_tunneled_eth = ProtoField.bytes("my_proto.tunneled_eth", "Tunneled Ethernet Frame")

-- Assign fields to the protocol
my_proto.fields = { f_id, f_timestamp, f_tunneled_eth }

-- Dissector function
function my_proto.dissector(buffer, pinfo, tree)
    -- Set the protocol column to "Custom Proto"
    pinfo.cols.protocol = "MY_PROTO"

    -- Check if the packet is large enough for minimum fields
    if buffer:len() < 32 then
        return -- Not enough data for ID + Timestamp
    end

    -- Add protocol to the dissection tree
    local subtree = tree:add(my_proto, buffer(), "Custom UDP Tunneling Protocol")

    -- Extract the ID field (24 bytes)
    subtree:add(f_id, buffer(0, 24))

    -- Extract the Timestamp field (8 bytes)
    subtree:add(f_timestamp, buffer(24, 8))

    -- Extract the Tunneled Ethernet frame (starting from byte 32)
    local eth_buffer = buffer(32):tvb()
    local eth_dissector = Dissector.get("eth") -- Get the Ethernet dissector

    if eth_dissector then
        -- Call the Ethernet dissector to parse the tunneled frame properly, adding it directly to the tree
        eth_dissector:call(eth_buffer, pinfo, tree)
    else
        -- Fallback if Ethernet dissector is unavailable
        subtree:add(f_tunneled_eth, buffer(32), "Ethernet Frame (unrecognized)")
    end
end
解决方案

问题出在两个核心点:

  • 子 dissector 挂载位置错误:原代码将Ethernet dissector直接调用到根协议树(tree),导致Wireshark无法正确关联隧道帧与自定义协议,解析上下文混乱。
  • 缺少帧长度校验:未验证剩余数据是否满足Ethernet帧的最小长度要求,可能触发解析失败。

修改后的脚本如下:

-- Define the protocol
my_proto = Proto("my_proto", "Custom UDP Tunneling Protocol")

-- Define the fields for the protocol
local f_id = ProtoField.string("my_proto.id", "ID", base.ASCII)
local f_timestamp = ProtoField.uint64("my_proto.timestamp", "Timestamp", base.DEC)
local f_tunneled_eth = ProtoField.bytes("my_proto.tunneled_eth", "Tunneled Ethernet Frame")

-- Assign fields to the protocol
my_proto.fields = { f_id, f_timestamp, f_tunneled_eth }

-- Dissector function
function my_proto.dissector(buffer, pinfo, tree)
    -- Set the protocol column to "Custom Proto"
    pinfo.cols.protocol = "MY_PROTO"

    -- 最小长度校验:24字节ID +8字节时间戳 +64字节最小以太网帧 =96字节
    local min_total_len = 32 + 64
    if buffer:len() < min_total_len then
        local subtree = tree:add(my_proto, buffer(), "Custom UDP Tunneling Protocol")
        subtree:add_expert_info(PI_MALFORMED, PI_WARN, "数据长度不足,无法解析隧道内以太网帧")
        return
    end

    -- 添加自定义协议到解析树
    local subtree = tree:add(my_proto, buffer(), "Custom UDP Tunneling Protocol")

    -- 提取ID字段(24字节)
    subtree:add(f_id, buffer(0, 24))

    -- 提取时间戳字段(8字节)
    subtree:add(f_timestamp, buffer(24, 8))

    -- 提取隧道内以太网帧(从第32字节开始)
    local eth_buffer = buffer(32):tvb()
    local eth_dissector = Dissector.get("eth")

    if eth_dissector then
        -- 创建以太网帧子项,将dissector挂载到该子项的解析树中
        local eth_subtree = subtree:add(f_tunneled_eth, eth_buffer, "Tunneled Ethernet Frame")
        eth_dissector:call(eth_buffer, pinfo, eth_subtree)
    else
        -- 以太网dissector不可用时的降级处理
        subtree:add(f_tunneled_eth, buffer(32), "Ethernet Frame (unrecognized)")
    end
end

-- 注册到UDP端口(替换为你的隧道实际使用的UDP端口)
local udp_table = DissectorTable.get("udp.port")
udp_table:add(12345, my_proto)

关键修改说明

  1. 调整dissector挂载层级:将Ethernet dissector的调用目标改为自定义协议子树的子项,确保解析结果嵌套在自定义协议下,符合Wireshark的解析树结构逻辑。
  2. 完善长度校验:增加了包含以太网帧最小长度的总长度校验,并添加专家警告提示数据异常情况。
  3. 补充端口注册:添加了UDP端口绑定代码(需替换为实际使用的隧道端口),确保Wireshark能将对应流量交给自定义dissector处理。

内容的提问来源于stack exchange,提问作者Rod D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:31:06