分步解析pcap包
讀入pcap文件
# -*- coding: UTF-8 -*-
import dpkt
import collections #有序字典需要的模塊
import time
def main(file_path):
f = open(file_path)
try:
pcap = dpkt.pcap.Reader(f) #先按.pcap格式解析,若解析不了,則按pcapng格式解析
except:
# print "it is not pcap ... format, pcapng format..."
pcap = dpkt.pcapng.Reader(f)
#接下來就可以對pcap做進一步解析了,記住在使用結束後最好使用f.close()關掉打開的文件,雖然程序運行結束後,
#系統會自己關掉,但是養成好習慣是必不可少的。當前變量pcap中是按照“間戳:單包”的格式存儲着各個單包
解包
####接着上面代碼########
#將時間戳和包數據分開,一層一層解析,其中ts是時間戳,buf存放對應的包
all_pcap_data=collections.OrderedDict() #有序字典
all_pcap_data_hex=collections.OrderedDict() #有序字典,存十六進制形式
for (ts,buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf) #解包,物理層
if not isinstance(eth.data, dpkt.ip.IP): #解包,網絡層,判斷網絡層是否存在,
continue
ip = eth.data
if not isinstance(ip.data, dpkt.tcp.TCP): #解包,判斷傳輸層協議是否是TCP,即當你只需要TCP時,可用來過濾
continue
# if not isinstance(ip.data, dpkt.udp.UDP):#解包,判斷傳輸層協議是否是UDP
# continue
transf_data = ip.data #傳輸層負載數據,基本上分析流量的人都是分析這部分數據,即應用層負載流量
if not len(transf_data.data): #如果應用層負載長度爲0,即該包爲單純的tcp包,沒有負載,則丟棄
continue
all_pcap_data[ts]=transf_data.data #將時間戳與應用層負載按字典形式有序放入字典中,方便後續分析.
all_pcap_data_hex[ts]=transf_data.data.encode('hex')
except Exception,err:
print "[error] %s" % err
f.close()
#驗證結果,打印保存的數據包的抓包以及對應的包的應用層負載長度
test_ts=0
for ts,app_data in all_pcap_data.iteritems():
print time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(ts)) ,":",len(app_data) #將時間戳轉換成日期
test_ts=ts
#打印最後一個包的十六進制形式,因爲加密數據在命令行打印會出現大量亂碼和錯行,故在此不做演示打印包的字符形式
print "\n最後一個包負載的十六進制******\n%s"%all_pcap_data_hex[test_ts],"\n"
運行測試
if __name__ == '__main__':
file_path="./test.pcap"
main(file_path)
結果如下圖
dpkt官方文檔