可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
What is the best way to sniff network packets using Python?
I've heard from several places that the best module for this is a module called Scapy, unfortunately, it makes python.exe crash on my system. I would assume that it's just a problem with how I installed it, except that many other people have told me that it doesn't work particularly well on Windows. (If anyone is interested, I'm running Windows Vista, which might affect things).
Does anyone know of a better solution?
UPD:
After reading the answer telling me to install PyPcap, I messed around with it a bit and found out that Scapy, which I had tried using, was telling me to install PyPcap as well, except that it's a modified version for it's use. It was this modified PyPcap that was causing the problem, apparently, since the example in the answer also caused a hang.
I installed the original version of PyPcap (from Google's site), and Scapy started working fine (I didn't try many things, but at least it didn't crash as soon as I started sniffing). I sent a new defect ticket to the Scapy developers: http://trac.secdev.org/scapy/ticket/166, hope they can do something with it.
Anyways, just thought I'd let y'all know.
回答1:
Using pypcap:
import dpkt, pcap
pc = pcap.pcap() # construct pcap object
pc.setfilter('icmp') # filter out unwanted packets
for timestamp, packet in pc:
print dpkt.ethernet.Ethernet(packet)
output sample:
Ethernet(src='\x00\x03G\xb2M\xe4', dst='\x00\x03G\x06h\x18', data=IP(src='\n\x00\x01\x1c',
dst='\n\x00\x01\x10', sum=39799, len=60, p=1, ttl=128, id=35102, data=ICMP(sum=24667,
type=8, data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))
Ethernet(src='\x00\x03G\x06h\x18', dst='\x00\x03G\xb2M\xe4', data=IP(src='\n\x00\x01\x10',
dst='\n\x00\x01\x1c', sum=43697, len=60, p=1, ttl=255, id=64227, data=ICMP(sum=26715,
data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))
回答2:
The hard way
You can sniff all of the IP packets using a raw socket.
Raw socket is a socket the sends and receives data in binary.
Binary in python is represented in a string which looks like this \x00\xff
... every \x..
is a byte.
To read an IP packet you need to analyze the received packet in binary according to the IP protocol.
This is and image of the format of the IP protocol with the sized in bits of every header.
IP protocol format http://cfs13.blog.daum.net/image/6/blog/2008/04/26/19/15/481300a2a7674&filename=IP_Header.png
This tutorial might help you understand the proccess of understanding a raw packet and splitting it to headers: http://www.binarytides.com/python-packet-sniffer-code-linux/
The easy way
Another method to sniff IP packets very easily is to use the scapy module.
from scapy.all import *
sniff(filter="ip", prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}")
This code will print for you the source IP and the destination IP for every IP packet.
You can do much more with scapy by reading it's documentation here: http://www.secdev.org/projects/scapy/doc/usage.html
It depends on the goal you are trying to achieve but if you need to build a project the one it's features is sniffing IP packets then I recommend to use scapy for more stable scripts.
回答3:
Use python-libpcap.
import pcap
p = pcap.pcapObject()
dev = pcap.lookupdev()
p.open_live(dev, 1600, 0, 100)
#p.setnonblock(1)
try:
for pktlen, data, timestamp in p:
print "[%s] Got data: %s" % (time.strftime('%H:%M',
time.localtime(timestamp)),
data)
except KeyboardInterrupt:
print '%s' % sys.exc_type
print 'shutting down'
print ('%d packets received, %d packets dropped'
' %d packets dropped by interface') % p.stats()
回答4:
you can use raw sockets, with your interface ip address (in admin mode),
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_IP)
s.bind(("YOUR_INTERFACE_IP",0))
s.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
s.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
while True:
data = s.recvfrom(10000)
print data
回答5:
Another option is pypcap.
To parse the results, Construct is very slick.
回答6:
If scapy, pleae try the following method. (It works on Windows 10)
# -*- coding: utf-8 -*-
# pip install scapy
"""
[{'name': 'Intel(R) 82574L Gigabit Network Connection',
'win_index': '4',
'description': 'Ethernet0',
'guid': '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}',
'mac': '00:0C:29:5C:EE:6D',
'netid': 'Ethernet0'}]
"""
from pprint import pprint
from scapy.arch.windows import get_windows_if_list
from scapy.all import *
# disable verbose mode
conf.verb = 0
def parse_packet(packet):
"""sniff callback function.
"""
if packet and packet.haslayer('UDP'):
udp = packet.getlayer('UDP')
udp.show()
def udp_sniffer():
"""start a sniffer.
"""
interfaces = get_windows_if_list()
pprint(interfaces)
print('\n[*] start udp sniffer')
sniff(
filter="udp port 53",
iface=r'Intel(R) 82574L Gigabit Network Connection', prn=parse_packet
)
if __name__ == '__main__':
udp_sniffer()