监控模式下从802.11帧获取MAC地址及修复recvfrom问题
802.11监控模式下数据包捕获与解析指南
一、recvfrom()无法获取802.11 MAC地址的原因
recvfrom()的struct sockaddr是为IP层通信设计的,而监控模式下捕获的是原始802.11二层帧,完全绕开了IP协议栈,因此用它提取MAC地址必然报错,且本身无法获取目的地址(DA)。正确做法是直接解析捕获到的原始帧数据,从帧头中提取SA和DA。
二、配置网卡为监控模式
确保网卡支持监控模式,执行以下命令:
# 关闭网卡 ip link set wlan1 down # 设置为监控模式 iw dev wlan1 set type monitor # 重启网卡 ip link set wlan1 up # 验证模式 iw dev wlan1 info
输出中出现type monitor即表示配置成功。
三、解析802.11帧的SA和DA
802.11帧头的地址字段布局由帧类型和To DS/From DS位决定,核心地址字段如下(每个MAC地址占6字节):
addr1: 目的地址(DA)addr2: 源地址(SA)addr3: 视帧类型而定(管理帧中为BSSID,数据帧中可能为RA/TA)
以下是C语言解析示例:
#include <stdint.h> #include <stdio.h> #include <arpa/inet.h> // 简化的802.11帧头结构 typedef struct { uint16_t frame_control; uint16_t duration_id; uint8_t addr1[6]; // DA uint8_t addr2[6]; // SA uint8_t addr3[6]; // BSSID/RA/TA uint16_t seq_control; } ieee80211_hdr; // MAC地址转字符串 void mac_to_str(uint8_t *mac, char *buf) { snprintf(buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } void parse_mac_addrs(uint8_t *frame_buf, int frame_len) { if (frame_len < sizeof(ieee80211_hdr)) return; ieee80211_hdr *hdr = (ieee80211_hdr*)frame_buf; char da[18], sa[18]; mac_to_str(hdr->addr1, da); mac_to_str(hdr->addr2, sa); printf("DA: %s | SA: %s\n", da, sa); }
四、识别802.11帧类型(信标、关联请求等)
帧类型由帧头的帧控制字段(前2字节)决定:
- 帧类型(bit 2-3):
- 00: 管理帧
- 01: 控制帧
- 10: 数据帧
- 子类型(bit 4-7):区分具体帧类型(如信标、关联请求)
以下是解析示例:
void parse_frame_type(uint8_t *frame_buf) { ieee80211_hdr *hdr = (ieee80211_hdr*)frame_buf; uint16_t fc = ntohs(hdr->frame_control); uint8_t type = (fc >> 2) & 0x03; uint8_t subtype = (fc >> 4) & 0x0F; switch (type) { case 0: // 管理帧 switch(subtype) { case 0x00: puts("关联请求帧 (Association Request)"); break; case 0x08: puts("信标帧 (Beacon)"); break; case 0x04: puts("探测请求帧 (Probe Request)"); break; case 0x05: puts("探测响应帧 (Probe Response)"); break; // 其他子类型可参考802.11标准补充 } break; case 1: // 控制帧 switch(subtype) { case 0x00: puts("RTS帧"); break; case 0x01: puts("CTS帧"); break; case 0x02: puts("ACK帧"); break; } break; case 2: // 数据帧 puts("数据帧"); break; } }
五、Wireshark的二层数据包分类逻辑
Wireshark按以下逻辑分类802.11数据包:
- 首先识别链路层类型(Linux监控模式下为
IEEE 802.11),确定采用802.11帧格式解析 - 解析帧控制字段,先区分帧类型(管理/控制/数据)
- 对管理帧:根据子类型细分(信标、关联请求等),同时解析BSSID、SSID等附加信息
- 对数据帧:检查
To DS/From DS位判断地址含义,识别是否为QoS数据、是否加密(如WPA2),加密帧会标注为802.11 Encrypted Data,解密后才能查看上层内容 - 对控制帧:直接按子类型归类(RTS/CTS/ACK等)
内容的提问来源于stack exchange,提问作者umarkaa
相关产品推荐
相关产品推荐

