本文主要講述如何使用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的注意實現參考這篇文章。

推薦閱讀:

相關文章