本文主要讲述如何使用Lua以及wireshark提供的API介面,来实现切流的操作。本质是利用wireshark的强大功能快速的实现报文级操作。

在这篇文章中说了如何使用tshark写切流的脚本。总的来说效率低下,主要原因是使用tshark我无法做到报文级操作(如果你知道,请告诉我),只能整个整个数据包的读取,然后根据过滤条件整个报文输出。对于一个pcap文件需要多次遍历,pcap报文中有几条流,就要读取遍历报文几次,时间复杂度高。如遇p2p报文,耗时太长。

使用C语言libpcap解析pcap报文,加上glib实现流管理,也是可以做到只历一遍报文。这里面使用Lua,其一是因为wireshark提供了强大的报文、流管理以及过滤器的功能,可以加以利用;其二是因为使用Lua脚本能够快速的构建和实现特定的小功能。

在这个网站章中说明了wireshark给Lua提供的API介面。本次主要应用到里面的Dumper,Field,Listener三个类。Dumper主要作用是写文件,Field主要作用是获取wireshark提供的各种报文属性,Listenser是一个监听器,监听符合过滤规则的报文。具体的用法参考网站的说明。以下便是完成的Lua脚本:

local getTcpStream =Field.new("tcp.stream")
local getSrcIp =Field.new("ip.src")
local getDstIp =Field.new("ip.dst")
local getSrcPort =Field.new("tcp.srcport")
local getDstPort =Field.new("tcp.dstport")
local getIpVersion =Field.new("ip.version")

local tcpStreamTable = {}--每一条流的索引哈希表
local dataWriterTable = {}--每一条流的dumper

do
local function packet_listener()
local tap =Listener.new("frame", "tcp.port == 443")
--frame是监听器的名称,tcp是wireshark过滤器规则

function tap.reset()
print("tap reset")
end

function tap.packet(pinfo,tvb)
--回调函数,每收到一个包执行一次。
local tcpStream = getTcpStream()
local srcIp = getSrcIp()
local dstIp = getDstIp()
local srcPort = getSrcPort()
local dstPort = getDstPort()
local ipVersion = getIpVersion()
local tcpStreamNumber =tonumber(tostring(tcpStream))

if(tcpStreamTable[tcpStreamNumber])
then
dataWriterTable[tcpStreamNumber]:dump_current()
else
local packetTuple4 =tostring(tcpStream).."_"..tostring(srcIp).."_"..tostring(srcPort).."_"..tostring(dstIp).."_"..tostring(dstPort).."_"..tostring(ipVersion)..".pcap"
tcpStreamTable[tcpStreamNumber] =tcpStream
dataWriterTable[tcpStreamNumber] =Dumper.new(packetTuple4)
dataWriterTable[tcpStreamNumber]:dump_current()
--print(type(tcpStreamTable[tcpStreamNumber]),type(tcpStreamNumber),type(dataWriterTable[tcpStreamNumber]),type(tcpStreamTable))
end
end

function tap.draw()
--结束执行
print("tap.draw")
end
end
--监听报文
packet_listener()
--tcpStreamTable =nil
end

我是在windows上面执行上述写好的lua脚本的,将lua脚本放到C:ProgramFilesWireshark目录下面,然后cmd到该目录下面,执行命令tshark-X lua_script:cut_flow.lua -r file_name.pcap,Linux上面的话是需要安装lua,重新编译wireshark的。最终切出的pcap报文名称是以流号+四元组+IP版本号命名的。关于在linux上面安装wireshark的注意实现参考这篇文章。

推荐阅读:

相关文章