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

Lua脚本无法在Wireshark控制台输出443端口TCP分析结果排查

Wireshark Lua脚本无法处理443端口TCP包的问题分析与修复

问题描述

我为工作编写了以下Lua脚本,但针对443端口的TCP数据包,它无法在Wireshark控制台显示任何输出。已尝试修复多日却毫无成效,请问问题出在哪里?

用户提供的脚本:

local plugin = {}

function plugin.init()  --I have initialized the plugins in the function
 
  plugin.rtt = {}
  plugin.window_sizes = {}
  plugin.congestion_window_size = 0
  plugin.slow_start_threshold = 0
  plugin.retransmit_threshold = 0     
  plugin.packet_drops = 0
  plugin.throughput = 0
end

function plugin.process_packet(packet)
 --This is processing every TCP packet

  local rtt = packet:get_tcp_option("tcp_rtt")
  if rtt ~= nil then
    plugin.rtt[#plugin.rtt + 1] = rtt
  end

  local window_size = packet:get_tcp_option("tcp_window_size")
  if window_size ~= nil then
    plugin.window_sizes[#plugin.window_sizes + 1] = window_size
  end

  if packet.tcp.flags.syn then
    
    plugin.congestion_window_size = 2
  else
    
    plugin.congestion_window_size = math.min(plugin.congestion_window_size * 2, math.max(plugin.window_sizes[#plugin.window_sizes - 1], 1))
  end

  if packet.tcp.flags.ack then
    
    plugin.slow_start_threshold = plugin.congestion_window_size + 1
    plugin.retransmit_threshold = plugin.congestion_window_size / 2
  end

  if packet.tcp.flags.rst then
    
    plugin.congestion_window_size = 0
    plugin.packet_drops = 0
  end

  if packet.tcp.flags.fin then
    
    plugin.throughput = plugin.congestion_window_size / plugin.rtt[#plugin.rtt]
  end

  
  print("Results for packet:")
  print("RTT:", rtt)
  print("Congestion Window Size:", plugin.congestion_window_size)
  print("Slow Start Threshold:", plugin.slow_start_threshold)
  print("Retransmit Threshold:", plugin.retransmit_threshold)
  print("Packet Drops:", plugin.packet_drops)
  print("Throughput:", plugin.throughput)
end

function plugin.get_results()
  
  return {
    rtt = plugin.rtt,
    window_sizes = plugin.window_sizes,
    congestion_window_size = plugin.congestion_window_size,
    slow_start_threshold = plugin.slow_start_threshold,
    retransmit_threshold = plugin.retransmit_threshold,
    packet_drops = plugin.packet_drops,
    throughput = plugin.throughput
  }
end

return plugin

核心问题与修复方案

1. 未针对443端口过滤数据包

脚本当前会处理所有TCP数据包,但你只关注443端口流量,若没有添加端口过滤逻辑,要么脚本处理了非443包导致你没看到对应输出,要么全局过滤后脚本没被触发。

修复:在process_packet开头添加端口判断,只处理源或目的为443的TCP包:

-- 仅处理443端口的TCP数据包
if not (packet.tcp.srcport == 443 or packet.tcp.dstport == 443) then
    return
end

2. TCP选项与字段获取方式错误

Wireshark Lua API中没有get_tcp_option方法,且RTT不是TCP头部选项,是Wireshark分析出的tcp.analysis.rtt字段;TCP窗口大小直接通过packet.tcp.window_size获取即可。

修复:

-- 获取Wireshark分析的RTT值
local rtt = packet.tcp.analysis and packet.tcp.analysis.rtt
if rtt ~= nil then
    plugin.rtt[#plugin.rtt + 1] = rtt
end

-- 获取TCP窗口大小
local window_size = packet.tcp.window_size
if window_size ~= nil then
    plugin.window_sizes[#plugin.window_sizes + 1] = window_size
end

3. 数组索引越界导致脚本中断

当脚本刚启动或还未收集到窗口大小数据时,plugin.window_sizes[#plugin.window_sizes - 1]会访问无效索引,触发报错导致脚本停止执行,控制台无输出。

修复:添加数组非空判断:

if packet.tcp.flags.syn then
    plugin.congestion_window_size = 2
else
    -- 确保window_sizes数组有数据才访问
    local last_window_size = #plugin.window_sizes > 0 and plugin.window_sizes[#plugin.window_sizes] or 1
    plugin.congestion_window_size = math.min(plugin.congestion_window_size * 2, math.max(last_window_size, 1))
end

4. 吞吐量计算时的空数组访问

当RTT数组为空时,plugin.rtt[#plugin.rtt]为nil,执行除法会报错中断脚本。

修复:添加非空判断:

if packet.tcp.flags.fin then
    if #plugin.rtt > 0 then
        plugin.throughput = plugin.congestion_window_size / plugin.rtt[#plugin.rtt]
    else
        plugin.throughput = 0
    end
end

5. 未正确注册Wireshark Tap

你的脚本定义了插件结构,但没有注册到Wireshark的TCP Tap上,导致process_packet函数根本不会被调用。

修复:在脚本末尾添加Tap注册逻辑:

-- 注册TCP Tap
local tap = Listener.new(nil, "tcp")

function tap.packet(pinfo, tvb, tcp)
    -- 将pinfo和tcp数据包装为兼容现有代码的packet对象
    local packet = {
        tcp = {
            srcport = pinfo.src_port,
            dstport = pinfo.dst_port,
            flags = {
                syn = tcp.syn,
                ack = tcp.ack,
                rst = tcp.rst,
                fin = tcp.fin
            },
            window_size = tcp.window_size,
            analysis = {
                rtt = pinfo.rtt
            }
        }
    }
    plugin.process_packet(packet)
end

function tap.reset()
    plugin.init()
end

-- 初始化插件
plugin.init()

完整修复后的脚本

local plugin = {}

function plugin.init()
    plugin.rtt = {}
    plugin.window_sizes = {}
    plugin.congestion_window_size = 0
    plugin.slow_start_threshold = 0
    plugin.retransmit_threshold = 0     
    plugin.packet_drops = 0
    plugin.throughput = 0
end

function plugin.process_packet(packet)
    -- 仅处理443端口的TCP数据包
    if not (packet.tcp.srcport == 443 or packet.tcp.dstport == 443) then
        return
    end

    -- 获取Wireshark分析的RTT值
    local rtt = packet.tcp.analysis and packet.tcp.analysis.rtt
    if rtt ~= nil then
        plugin.rtt[#plugin.rtt + 1] = rtt
    end

    -- 获取TCP窗口大小
    local window_size = packet.tcp.window_size
    if window_size ~= nil then
        plugin.window_sizes[#plugin.window_sizes + 1] = window_size
    end

    if packet.tcp.flags.syn then
        plugin.congestion_window_size = 2
    else
        -- 确保window_sizes数组有数据才访问
        local last_window_size = #plugin.window_sizes > 0 and plugin.window_sizes[#plugin.window_sizes] or 1
        plugin.congestion_window_size = math.min(plugin.congestion_window_size * 2, math.max(last_window_size, 1))
    end

    if packet.tcp.flags.ack then
        plugin.slow_start_threshold = plugin.congestion_window_size + 1
        plugin.retransmit_threshold = plugin.congestion_window_size / 2
    end

    if packet.tcp.flags.rst then
        plugin.congestion_window_size = 0
        plugin.packet_drops = 0
    end

    if packet.tcp.flags.fin then
        if #plugin.rtt > 0 then
            plugin.throughput = plugin.congestion_window_size / plugin.rtt[#plugin.rtt]
        else
            plugin.throughput = 0
        end
    end

    -- 输出结果到控制台
    print("Results for 443 port packet:")
    print("RTT:", rtt or "N/A")
    print("Congestion Window Size:", plugin.congestion_window_size)
    print("Slow Start Threshold:", plugin.slow_start_threshold)
    print("Retransmit Threshold:", plugin.retransmit_threshold)
    print("Packet Drops:", plugin.packet_drops)
    print("Throughput:", plugin.throughput)
end

function plugin.get_results()
    return {
        rtt = plugin.rtt,
        window_sizes = plugin.window_sizes,
        congestion_window_size = plugin.congestion_window_size,
        slow_start_threshold = plugin.slow_start_threshold,
        retransmit_threshold = plugin.retransmit_threshold,
        packet_drops = plugin.packet_drops,
        throughput = plugin.throughput
    }
end

-- 注册TCP Tap
local tap = Listener.new(nil, "tcp")

function tap.packet(pinfo, tvb, tcp)
    -- 将pinfo和tcp数据包装为兼容现有代码的packet对象
    local packet = {
        tcp = {
            srcport = pinfo.src_port,
            dstport = pinfo.dst_port,
            flags = {
                syn = tcp.syn,
                ack = tcp.ack,
                rst = tcp.rst,
                fin = tcp.fin
            },
            window_size = tcp.window_size,
            analysis = {
                rtt = pinfo.rtt
            }
        }
    }
    plugin.process_packet(packet)
end

function tap.reset()
    plugin.init()
end

-- 初始化插件
plugin.init()

return plugin

内容的提问来源于stack exchange,提问作者Dark Vedar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:54:53