[英]Raw socket packet sniffer in Python 3.6 on Windows
我正在尝试嗅探数据包,但输出却很奇怪,我不明白原因。
这就是我的代码, 请帮帮我
(我在Windows 8.1上使用Python 3.6)
import socket
import struct
import binascii
import textwrap
def main():
# Get host
host = socket.gethostbyname(socket.gethostname())
print('IP: {}'.format(host))
# Create a raw socket and bind it
conn = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
conn.bind((host, 0))
# Include IP headers
conn.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# Enable promiscuous mode
conn.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
while True:
# Recive data
raw_data, addr = conn.recvfrom(65536)
# Unpack data
dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data)
print('\nEthernet Frame:')
print("Destination MAC: {}".format(dest_mac))
print("Source MAC: {}".format(src_mac))
print("Protocol: {}".format(eth_proto))
# Unpack ethernet frame
def ethernet_frame(data):
dest_mac, src_mac, proto = struct.unpack('!6s6s2s', data[:14])
return get_mac_addr(dest_mac), get_mac_addr(src_mac), get_protocol(proto), data[14:]
# Return formatted MAC address AA:BB:CC:DD:EE:FF
def get_mac_addr(bytes_addr):
bytes_str = map('{:02x}'.format, bytes_addr)
mac_address = ':'.join(bytes_str).upper()
return mac_address
# Return formatted protocol ABCD
def get_protocol(bytes_proto):
bytes_str = map('{:02x}'.format, bytes_proto)
protocol = ''.join(bytes_str).upper()
return protocol
main()
IP:192.168.1.12
以太网帧:
目标MAC: 45:00:00:43:00:00
源MAC: 40:00:2C:11:48:D3
协议: 4266
以太网帧:
目标MAC: 45:00:00:42:11:E7
源MAC: 00:00:80:11:00:00
通讯协定: C0A8
以太网帧:
目标MAC: 45:00:00:33:04:D6
源MAC: 00:00:80:11:00:00
通讯协定: C0A8
。
。
。
根据EtherType列表,此协议不存在,并且使用Wireshark分析我的流量,我确定此MAC在我的LAN中不存在
所以我肯定做错了,但是我不明白
提前致谢
好的,感谢塞尔比,我了解这个问题,非常感谢
但是要在Windows中使用Python捕获以太网头,您必须使用:
要安装dpkt,只需以管理员身份打开cmd并输入:
py -2 -m pip安装dpkt
这里是Python Docs的参考
但是您需要安装Python 3.4>才能获得pip
#!/usr/bin/env python
import getopt, sys
import dpkt, pcap
import socket
import struct
import binascii
import textwrap
def main():
# Get host
host = socket.gethostbyname(socket.gethostname())
print('IP: {}'.format(host))
name = None
pc = pcap.pcap(name)
decode = { pcap.DLT_LOOP:dpkt.loopback.Loopback,
pcap.DLT_NULL:dpkt.loopback.Loopback,
pcap.DLT_EN10MB:dpkt.ethernet.Ethernet }[pc.datalink()]
try:
print 'listening on %s: %s' % (pc.name, pc.filter)
for ts, pkt in pc:
pkt = str(decode(pkt))
dest_mac, src_mac, eth_proto, data = ethernet_frame(pkt)
print '\nEthernet Frame:'
print "Destination MAC: {}".format(dest_mac)
print "Source: {}".format(src_mac)
print "Protocol: {}".format(eth_proto)
except KeyboardInterrupt:
nrecv, ndrop, nifdrop = pc.stats()
print '\n%d packets received by filter' % nrecv
print '%d packets dropped by kernel' % ndrop
# Unpack ethernet frame
def ethernet_frame(data):
dest_mac, src_mac, proto = struct.unpack('!6s6s2s', data[:14])
return binascii.hexlify(dest_mac), binascii.hexlify(src_mac), binascii.hexlify(proto), data[14:]
if __name__ == '__main__':
main()
以太网帧:
目标MAC: 5404a6f2740c <-我的网卡MAC
资料来源: 6459f81dc690
通讯协定: 0800 <-正确的通讯协定
以太网帧:
目标MAC: 6459f81dc690
资料来源: 5404a6f2740c
协议: 0800
以太网帧:
目标MAC: 5404a6f2740c
资料来源: 6459f81dc690
协议: 0800
希望您再次感谢selbie
(对不起,由于我的声誉,我无法放置更多链接)
提示您所有的目标Mac地址都以0x45
。 那是IP标头的第一个字节。 因此,您的代码将获取所有IP数据包,而不是那些帧的MAC标头。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.