You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

监控模式下从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字节)决定:

  1. 帧类型(bit 2-3):
    • 00: 管理帧
    • 01: 控制帧
    • 10: 数据帧
  2. 子类型(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数据包:

  1. 首先识别链路层类型(Linux监控模式下为IEEE 802.11),确定采用802.11帧格式解析
  2. 解析帧控制字段,先区分帧类型(管理/控制/数据)
  3. 对管理帧:根据子类型细分(信标、关联请求等),同时解析BSSID、SSID等附加信息
  4. 对数据帧:检查To DS/From DS位判断地址含义,识别是否为QoS数据、是否加密(如WPA2),加密帧会标注为802.11 Encrypted Data,解密后才能查看上层内容
  5. 对控制帧:直接按子类型归类(RTS/CTS/ACK等)

内容的提问来源于stack exchange,提问作者umarkaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:47:42