2013-01-07 58 views
1

我有一個關於從特定客戶端嗅探數據包的問題。我運行一個非常簡單的UDP服務器,如下所示:從特定客戶端捕獲數據包UDP(Python)

from socket import * 

IPv4 = "" 
Port = 54345 

ServerSock = socket(AF_INET, SOCK_DGRAM) # UDP 
ServerSock.bind((IPv4, Port)) 
print "Socket is ready to receive data.." 

while True: 
    data, addr = ServerSock.recvfrom(1024) # buffer size is 1024 bytes 
    print data 

我打算抓住每一個涉及到的端口號(54345)數據包,並解析其標頭值。我認爲這是可行的,如果包保存到文件.pcap和可能使用Scapy的處理它們,但它可以處理每一個數據包,一旦它到達使用「socket.recvfrom」?謝謝

+0

你的問題不是很清楚。你在這裏做什麼應該很好。假設沒有其他任何東西綁定到'('',54345)',它將接收發送到該端口的每個數據報並將其打印到'stdout',這樣您就可以將腳本的輸出重定向到一個文件並使用'scapy'或任何其他你要。所以...這是不是你想要做的事? – abarnert

+0

感謝您的快速響應.. recvfrom的輸出形式爲('data',('add',54345))。可以保存爲.pcap文件中的完整數據包嗎? – OiaSam

回答

1

您已經掌握了相關數據。但是,你得到的是UDP數據包和源地址;如果您想要完整的原始數據包,使用IPv4和UDP標頭,則不同。

在某些平臺上,你可以設置一個正常的UDP套接字爲IP_HDRINCL,或者還有其他的等價物。如果你這樣做,每個recvfrom將包括數據的報頭,所以你已經得到了你想要的一切。

在其他平臺上,您可以使用SOCK_RAW而不是SOCK_DGRAM。你可以用原始套接字做什麼變化很大。在許多Unix平臺上,可以使用IPPROTO_UDPSOCK_RAW,然後bind爲正常的UDP地址和端口,雖然可能有限制,並且它們在每個平臺上都不相同。例如,在OS X上,您必須是root用戶才能創建原始套接字,並且您只能將原始套接字綁定到單接口地址(即沒有0​​/INADDR_ANY/'0.0.0.0')。如果谷歌爲「SOCK_RAW的Python」和「SOCK_RAW」你應該能夠找到你所需要的。 (sockets module docs中的最後一個示例顯示瞭如何在Windows上使用原始套接字。)

獲得數據後,將其保存到pcap文件並不困難。該格式在The Wireshark Wiki上的LibpcapFileFormat處有記錄。如果您有與STDLIB struct模塊任何熟悉,它應該很容易找出如何寫這個格式。這裏有一個簡單的例子:

pcap_hdr = struct.pack('=IHHiIII', 
         0xa1b2c3d4, # magic number 
         2, 4,  # pcap 2.4 format 
         0,   # UTC timezone for timestamps 
         0,   # "in practice, all tools set it to 0" 
         65535,  # max packet length 
         228)  # LINKTYPE_IPV4, or maybe you want LINKTYPE_RAW 
pcapfile.write(pcap_hdr) 

如果你不想自己做,我沒有使用圖書館寫PCAP文件的任何經驗,但scapy將是我首先關注的地方,然後python-libpcap綁定爲libpcap/WinPcap。如果沒有這些工作,檢查PyPI。

如果所有這些聽起來超出了你的意思,你可能不想這樣做。只需運行你的UDP服務器,並使用Wireshark捕獲所有發送給它的數據包。

+0

非常感謝您的回答。我所遇到的「SOCK_RAW」,它在我看來,它像一個嗅探器對所有傳入數據包。所有你提到的都是有道理的,但我想知道是否可以捕獲並保存特定客戶端端口號的數據包。 – OiaSam

+0

如果您試圖從特定的客戶端端口(不管是否到特定的本地端口)捕獲所有數據包,那是一個不同的問題。這些細節是高度特定於平臺的,但是'python-libpcap'(鏈接在上面)提供了一些非常好的抽象,這將使它更容易,IIRC其中一個例子幾乎就是你想要的(它嗅探eth0/en0 /等等,並在TCP dst端口80上過濾;適應在UDP src端口54345上的過濾應該很容易)。 – abarnert

+0

謝謝..我會試一試 – OiaSam

0

是的,這是可能的。這就是你的程序實際上已經做到的。

+0

也許我的問題是不是很清楚,如果它確實如此..我怎麼能得到例如從每個接收數據包的IP標識號碼?感謝 – OiaSam

+0

這就是'addr'是在你的代碼。 –