[英]Why when sniffing wifi frames using sockets in python I get ethernet frames (not 802.11)
I am trying to write a program that will display all wifi networks and their clients.我正在尝试编写一个程序来显示所有 wifi 网络及其客户端。 The code looks as follows:
代码如下所示:
import os
import socket
import struct
def unpack_ethernet_frame(data):
dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) # Big-endian, 6bytes, 6bytes, 1 short
return format_mac(dest_mac), format_mac(src_mac), socket.htons(proto), data[14:]
def format_mac(bytes_addr):
bytes_s = map('{:02x}'.format, bytes_addr)
return ":".join(bytes_s).upper()
def format_ip(bytes_addr):
return ".".join(map(str, bytes_addr))
def unpack_ipv4_frame(data):
header_len = (data[0] & 15) * 4 # last 4 bits of first byte * 4
ttl, prot, src, dst = struct.unpack("! 8x B B 2x 4s 4s", data[:20])
return format_ip(src), format_ip(dst), prot, data[header_len:]
def unpack_tcp(data):
src_port, dst_port = struct.unpack("! H H", data[:4])
return src_port, dst_port
def unpack_udp(data):
src_port, dst_port, size = struct.unpack("! H H 2x H", data[:8])
return src_port, dst_port, size, data[8:]
if __name__ == '__main__':
conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
while True:
raw_data, addr = conn.recvfrom(65536)
dest, src, prot, data = unpack_ethernet_frame(raw_data)
if prot == 8: # IP
print("Dest {0}, Src {1}, prot {2}".format(dest, src, prot))
src_id, dst_ip, prot, data = unpack_ipv4_frame(data)
print("From {0} to {1}".format(src_id, dst_ip))
if prot == 6: # TCP
src_port, dst_port = unpack_tcp(data)
print("src_port {0} dst_port {1}".format(src_port, dst_port))
if prot == 17: # UdP
src_port, dst_port, size, data = unpack_udp(data)
print("src_port {0} dst_port {1} size {2}".format(src_port, dst_port, size))
I do not know why, but "unpack_ethernet_frame" function receives Ethernet frames, not MAC frames.我不知道为什么,但是“unpack_ethernet_frame”函数接收以太网帧,而不是 MAC 帧。 If I receive wireless frames then I should rather get MAC frames?
如果我收到无线帧,那么我应该获得 MAC 帧吗? Mostly what I am trying to do is to find out which frames are beacon frames and get their SSID.
大多数情况下,我想要做的是找出哪些帧是信标帧并获取它们的 SSID。
EDIT : I am trying this code with Monitor mode enabled编辑:我正在尝试启用监控模式的代码
When you are getting your data from a socket
, the IEEE802
-frame has already been unpacked and the Ethernet
-frame within it is what you see.当您从
socket
获取数据时, IEEE802
帧已经解包,其中的Ethernet
帧就是您所看到的。 There are historical reasons why this is done and the whole IEEE802
-layer is usually not visible even to the OS.这样做是有历史原因的,整个
IEEE802
层通常甚至对操作系统都不可见。 In order to receive unmodified IEEE802
-frames, you need to为了接收未修改的
IEEE802
帧,您需要
socket
but directly from the device, eg via libpcap .socket
而是直接从设备接收数据,例如通过libpcap 。 Also see this answer and this link regarding scapy .另请参阅此答案和有关scapy 的链接。
You've connected to the wrong interface.您连接到了错误的接口。 You shall specify which network interface you want to connect.
您应指定要连接的网络接口。
if __name__ == '__main__':
conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
conn.bind(("wlan0mon", 0x0003))
while True:
raw_data, addr = conn.recvfrom(65536)
This worked for me这对我有用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.