⑴ python怎樣讀取pcap文件
程序如下:
#!/usr/bin/env python
#coding=utf-8
#讀取pcap文件,解析相應的信息,為了在記事本中顯示的方便,把二進制的信息
import struct
fpcap = open('test.pcap','rb')
ftxt = open('result.txt','w')
string_data = fpcap.read()
#pcap文件包頭解析
pcap_header = {}
pcap_header['magic_number'] = string_data[0:4]
pcap_header['version_major'] = string_data[4:6]
pcap_header['version_minor'] = string_data[6:8]
pcap_header['thiszone'] = string_data[8:12]
pcap_header['sigfigs'] = string_data[12:16]
pcap_header['snaplen'] = string_data[16:20]
pcap_header['linktype'] = string_data[20:24]
#把pacp文件頭信息寫入result.txt
ftxt.write("Pcap文件的包頭內容如下: \n")
for key in ['magic_number','version_major','version_minor','thiszone',
'sigfigs','snaplen','linktype']:
ftxt.write(key+ " : " + repr(pcap_header[key])+'\n')
#pcap文件的數據包解析
step = 0
packet_num = 0
packet_data = []
pcap_packet_header = {}
i =24
while(i<len(string_data)):
#數據包頭各個欄位
pcap_packet_header['GMTtime'] = string_data[i:i+4]
pcap_packet_header['MicroTime'] = string_data[i+4:i+8]
pcap_packet_header['caplen'] = string_data[i+8:i+12]
pcap_packet_header['len'] = string_data[i+12:i+16]
#求出此包的包長len
packet_len = struct.unpack('I',pcap_packet_header['len'])[0]
#寫入此包數據
packet_data.append(string_data[i+16:i+16+packet_len])
i = i+ packet_len+16
packet_num+=1
#把pacp文件里的數據包信息寫入result.txt
for i in range(packet_num):
#先寫每一包的包頭
ftxt.write("這是第"+str(i)+"包數據的包頭和數據:"+'\n')
for key in ['GMTtime','MicroTime','caplen','len']:
ftxt.write(key+' : '+repr(pcap_packet_header[key])+'\n')
#再寫數據部分
ftxt.write('此包的數據內容'+repr(packet_data[i])+'\n')
ftxt.write('一共有'+str(packet_num)+"包數據"+'\n')
ftxt.close()
fpcap.close()
最終得到的result文件如下所示:欄位顯示的都是十六進制,其中的數據部分和wireshark打開,顯示的十六進制窗口一樣。
⑵ 求助python pcap模塊問題
這個東西可能是兩個原因。一個就是少安裝了pcap對應的驅動程序,第二個可能是操作系統版本問題。 你可以在一個xp操作系統上試驗。 另外pcap應該有新版本。支持python2.7的。如果沒有自己下源碼編譯一下。 不過,還是建議你用linux來做試驗。這樣
⑶ winpcap在python3中的使用,求助
from ctypes import *
from winpcapy import *
import time
import sys
import string
import platform
if platform.python_version()[0] == "3":
raw_input=input
#/* prototype of the packet handler */
#void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
PHAND=CFUNCTYPE(None,POINTER(c_ubyte),POINTER(pcap_pkthdr),POINTER(c_ubyte))
## Callback function invoked by libpcap for every incoming packet
def _packet_handler(param,header,pkt_data):
## convert the timestamp to readable format
local_tv_sec = header.contents.ts.tv_sec
ltime=time.localtime(local_tv_sec);
timestr=time.strftime("%H:%M:%S", ltime)
print
print("%s,%.6d len:%d" % (timestr, header.contents.ts.tv_usec, header.contents.len))
packet_handler=PHAND(_packet_handler)
alldevs=POINTER(pcap_if_t)()
errbuf= create_string_buffer(PCAP_ERRBUF_SIZE)
## Retrieve the device list
if (pcap_findalldevs(byref(alldevs), errbuf) == -1):
print ("Error in pcap_findalldevs: %s\n" % errbuf.value)
sys.exit(1)
## Print the list
i=0
try:
d=alldevs.contents
except:
print ("Error in pcap_findalldevs: %s" % errbuf.value)
print ("Maybe you need admin privilege?\n")
sys.exit(1)
while d:
i=i+1
print("%d. %s" % (i, d.name))
if (d.description):
print (" (%s)\n" % (d.description))
else:
print (" (No description available)\n")
if d.next:
d=d.next.contents
else:
d=False
if (i==0):
print ("\nNo interfaces found! Make sure WinPcap is installed.\n")
sys.exit(-1)
print ("Enter the interface number (1-%d):" % (i))
inum= raw_input('--> ')
if inum in string.digits:
inum=int(inum)
else:
inum=0
if ((inum < 1) | (inum > i)):
print ("\nInterface number out of range.\n")
## Free the device list
pcap_freealldevs(alldevs)
sys.exit(-1)
## Jump to the selected adapter
d=alldevs
for i in range(0,inum-1):
d=d.contents.next
## Open the device
## Open the adapter
d=d.contents
adhandle = pcap_open_live(d.name,65536,1,1000,errbuf)
if (adhandle == None):
print("\nUnable to open the adapter. %s is not supported by Pcap-WinPcap\n" % d.contents.name)
## Free the device list
pcap_freealldevs(alldevs)
sys.exit(-1)
print("\nlistening on %s...\n" % (d.description))
## At this point, we don't need any more the device list. Free it
pcap_freealldevs(alldevs)
## start the capture (we take only 15 packets)
pcap_loop(adhandle, 15, packet_handler, None)
pcap_close(adhandle)
這是WINPCAPY自帶的例子。
⑷ python pcap 導入之後第一行程序就有問題!急求解決辦法!!
這個東西可能是兩個原因。一個就是少安裝了pcap對應的驅動程序,第二個可能是操作系統版本問題。 你可以在一個xp操作系統上試驗。
另外pcap應該有新版本。支持python2.7的。如果沒有自己下源碼編譯一下。
不過,還是建議你用linux來做試驗。這樣全都變得簡單了。
⑸ 在網頁上怎麼能夠調用本地的應用打開一個pcap包
本地是指瀏覽器客戶端的話,可以在瀏覽器的文件打開方式里設置(比如Firefox就就可以設置某種類型的文件怎樣打開,是直接下載還是用某個程序打開等)。如果你是指點擊Web伺服器端的pcap文件,然後在伺服器端就解析這種文件格式,再以圖形表格等數據顯示出來傳回瀏覽器端的話,那需要自己用Web伺服器端的開發技術(PHP、Python等)寫pcap的解析器(基本的解析估計Wireshark會有C語言的API)和繪圖代碼
⑹ pcap文件怎麼解 python
欄位顯示的都是十六進制,其中的數據部分和wireshark打開,顯示的十六進制窗口一樣。
其實如果程序想到得到某一個或某幾個位元組的十進制數,用struct還是很容易轉換的!
⑺ 如何利用libpcap和Python嗅探數據包
一提到Python獲取數據包的方式,相信很多Python愛好者會利用Linux的libpcap軟體包或利用Windows下的WinPcap可移植版的方式進行抓取數據包,然後再利用dpkt軟體包進行協議分析,我們這里想換一個角度去思考:
1. Python版本的pcap存儲內存數據過小,也就是說緩存不夠,在高並發下容易發生丟包現象,其實C版本的也同樣存在這樣的問題,只不過Python版本的緩存實在是過低,讓人很郁悶。
2. dpkt協議分析並非必須,如果你對RFC 791和RFC 793等協議熟悉的話,完全可以使用struct.unpack的方式進行分析。
如果你平常習慣使用tcpmp抓取數據包的話,完全可以使用它來代替pcap軟體包,只不過我們需要利用tcpmp將抓取的數據以pcap格式進行保存,說道這里大家一定會想到Wireshark工具,具體命令如下:
tcpmp dst 10.13.202.116 and tcp dst port 80 -s 0 -i eth1 -w ../pcap/tcpmp.pcap -C 1k -W 5
我們首先需要對pcap文件格式有所了解,具體信息大家可以參考其他資料文檔,我這里只說其重要的結構體組成,如下:
sturct pcap_file_header
{
DWORD magic;
WORD version_major;
WORD version_minor;
DWORD thiszone;
DWORD sigfigs;
DWORD snaplen;
DWORD linktype;
}
struct pcap_pkthdr
{
struct timeval ts;
DWORD caplen;
DWORD len;
}
struct timeval
{
DWORD GMTtime;
DWORD microTime;
}
這里需要說明的一點是,因為在Python的世界裡一切都是對象,所以往往Python在處理數據包的時候感覺讓人比較麻煩。Python提供了幾個libpcapbind,http://monkey.org/~gsong/pypcap/這里有 一個最簡單的。在windows平台上,你需要先安裝winpcap,如果你已經安裝了Ethereal非常好用。一個規范的抓包過程:
import pcap
import dpkt
pc=pcap.pcap() #注,參數可為網卡名,如eth0
pc.setfilter('tcp port 80') #設置監聽過濾器
for ptime,pdata in pc: #ptime為收到時間,pdata為收到數據
print ptime,pdata #...
對抓到的乙太網V2數據包(raw packet)進行解包:
p=dpkt.ethernet.Ethernet(pdata)
if p.data.__class__.__name__=='IP':
ip='%d.%d.%d.%d'%tuple(map(ord,list(p.data.dst)))
if p.data.data.__class__.__name__=='TCP':
if data.dport==80:
print p.data.data.data
一些顯示參數nrecv,ndrop,nifdrop=pc.stats()返回的元組中,第一個參數為接收到的數據包,第二個參數為被核心丟棄的數據包。
至於對於如何監控tcpmp生成的pcap文件數據,大家可以通過pyinotify軟體包來實現,如下:
class Packer(pyinotify.ProcessEvent):
def __init__(self, proct):
self.proct = proct
self.process = None
def process_IN_CREATE(self, event):
logger.debug("create file: %s in queue" % self.process_IF_START_THREAD(event))
def process_IN_MODIFY(self, event):
self.process_IF_START_THREAD(event)
logger.debug("modify file: %s in queue" % self.process_IF_START_THREAD(event))
def process_IN_DELETE(self, event):
filename = os.path.join(event.path, event.name)
logger.debug("delete file: %s" % filename)
def process_IF_START_THREAD(self, event):
filename = os.path.join(event.path, event.name)
if filename != self.process:
self.process = filename
self.proct.put(filename)
if self.proct.qsize() > 1:
try:
logger.debug("create consumer proct.qsize: %s" % self.proct.qsize())
consumer = Consumer(self.proct)
consumer.start()
except Exception, errmsg:
logger.error("create consumer failed: %s" % errmsg)
return filename
class Factory(object):
def __init__(self, proct):
self.proct = proct
self.manager = pyinotify.WatchManager()
self.mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY
def work(self):
try:
try:
notifier = pyinotify.ThreadedNotifier(self.manager, Packer(self.proct))
notifier.start()
self.manager.add_watch("../pcap", self.mask, rec = True)
notifier.join()
except Exception, errmsg:
logger.error("create notifier failed: %s" % errmsg)
except KeyboardInterrupt, errmsg:
logger.error("factory has been terminated: %s" % errmsg)
在獲得要分析的pcap文件數據之後,就要對其分析了,只要你足夠了解pcap文件格式就可以了,對於我們來講只需要獲得TCP數據段的數據即可,如下:
class Writer(threading.Thread):
def __init__(self, proct, stack):
threading.Thread.__init__(self)
self.proct = proct
self.stack = stack
self.pcap_pkthdr = {}
def run(self):
while True:
filename = self.proct.get()
try:
f = open(filename, "rb")
readlines = f.read()
f.close()
offset = 24
while len(readlines) > offset:
self.pcap_pkthdr["len"] = readlines[offset+12:offset+16]
try:
length = struct.unpack("I", self.pcap_pkthdr["len"])[0]
self.stack.put(readlines[offset+16:offset+16+length])
offset += length + 16
except Exception, errmsg:
logger.error("unpack pcap_pkthdr failed: %s" % errmsg)
except IOError, errmsg:
logger.error("open file failed: %s" % errmsg)
在獲得TCP數據段的數據包之後,問題就簡單多了,根據大家的具體需求就可以進行相應的分析了,我這里是想分析其HTTP協議數據,同樣也藉助了dpkt軟體包進行分析,如下:
def worker(memcache, packet, local_address, remote_address):
try:
p = dpkt.ethernet.Ethernet(packet)
if p.data.__class__.__name__ == "IP":
srcip = "%d.%d.%d.%d" % tuple(map(ord, list(p.data.src)))
dstip = "%d.%d.%d.%d" % tuple(map(ord, list(p.data.dst)))
if p.data.data.__class__.__name__ == "TCP":
tcpacket = p.data.data
if tcpacket.dport == 80 and dstip == local_address:
srcport = tcpacket.sport
key = srcip + ":" + str(srcport)
if tcpacket.data:
if not memcache.has_key(key):
memcache[key] = {}
if not memcache[key].has_key("response"):
memcache[key]["response"] = None
if memcache[key].has_key("data"):
memcache[key]["data"] += tcpacket.data
else:
memcache[key]["data"] = tcpacket.data
else:
if memcache.has_key(key):
memcache[key]["response"] = dpkt.http.Request(memcache[key]["data"])
try:
stackless.tasklet(connection)(memcache[key]["response"], local_address, remote_address)
stackless.run()
except Exception, errmsg:
logger.error("connect remote remote_address failed: %s", errmsg)
logger.debug("old headers(none content-length): %s", memcache[key]["response"])
memcache.pop(key)
except Exception, errmsg:
logger.error("dpkt.ethernet.Ethernet failed in worker: %s", errmsg)
如果大家只是想單純的獲取IP地址、埠、流量信息,那麼問題就更簡單了,這里只是拋磚引玉。另外再提供一段代碼供參考:
import pcap, dpkt, struct
import binascii
def main():
a = pcap.pcap()
a.setfilter('udp portrange 4000-4050')
try:
for i,pdata in a:
p=dpkt.ethernet.Ethernet(pdata)
src='%d.%d.%d.%d' % tuple(map(ord,list(p.data.src)))
dst='%d.%d.%d.%d' % tuple(map(ord,list(p.data.dst)))
sport = p.data.data.sport
dport = p.data.data.dport
qq = int( binascii.hexlify(p.data.data.data[7:11]) , 16 )
print 'QQ: %d, From: %s:%d , To: %s:%d' % (qq,src,sport,dst,dport)
except Exception,e:
print '%s' % e
n = raw_input()
if __name__ == '__main__':
main()
⑻ python中pypcap的參數問題
win10系統。使用pcap創建對象時候,無法給定網卡名。比如:mem1=pcap.pcap()這樣的話可以創建對象,對應的網卡就是無線網卡,程序可以運行想指定網卡的時候:mem1=pcap.pcap('MYPC')#MYPC是網卡名就無法運行所以我是網卡名弄錯了嘛==如果是的話去哪找網卡名==...展開
實際上就是pcap的網卡參數應該填什麼