hostapd状态机解析

文章目录

      • **STA 连接 AP 的全流程状态机**
      • **状态机详细解析**
        • **1. 初始状态:DISCONNECTED**
        • **2. 认证阶段:AUTHENTICATING → AUTHENTICATED**
        • **3. 关联阶段:ASSOCIATING → ASSOCIATED**
        • **4. 密钥协商阶段 (4次握手)**
        • **5. 授权阶段:AUTHORIZED**
      • **安全机制状态转换**
      • **超时与错误处理机制**
        • **1. 认证超时**
        • **2. 握手失败处理**
      • **关键数据结构**
      • **实际调试分析**
      • **状态机设计特点**
      • **企业级部署特殊流程**
      • **性能优化设计**
      • **总结**

STA 连接 AP 的全流程状态机

STA发送Probe Request AP验证成功
(设置WLAN_STA_AUTH) STA发送Association Request AP接受关联
(设置WLAN_STA_ASSOC) 启动4次握手
(EAPOL状态机) 握手成功
(安装PTK/GTK) 设置WLAN_STA_AUTHORIZED 开启数据传输 认证失败 关联失败 握手失败 收到Deauth帧 DISCONNECTED AUTHENTICATING AUTHENTICATED ASSOCIATING ASSOCIATED KEY_HANDSHAKE KEY_VALID AUTHORIZED DATA_TRANSMISSION


状态机详细解析

1. 初始状态:DISCONNECTED
  • 触发条件:STA未连接

  • AP行为

    • 周期性发送 Beacon 帧(包含 SSID/安全策略)
    • 监听 Probe Request
  • 关键数据结构

    c 复制代码
    struct hostapd_data {
        struct sta_info *sta_list;  // 空列表
    };
2. 认证阶段:AUTHENTICATING → AUTHENTICATED
  • 触发事件 :STA发送 Probe Request + Authentication Request

  • AP处理流程

    c 复制代码
    // ieee802_11.c
    static void handle_auth(struct hostapd_data *hapd, const u8 *buf, size_t len)
    {
        // 1. 检查MAC黑名单
        if (hostapd_maclist_found(hapd->conf->deny_mac, src, 0))
            goto fail;
        
        // 2. 创建STA状态结构
        sta = ap_get_sta(hapd, src);
        if (!sta) {
            sta = ap_sta_add(hapd, src);  // 分配sta_info
        }
        
        // 3. 验证认证算法
        if (alg != WLAN_AUTH_OPEN && alg != WLAN_AUTH_SHARED_KEY)
            goto fail;
        
        // 4. 设置认证状态
        sta->flags |= WLAN_STA_AUTH;
        
        // 5. 发送Authentication Response(成功)
        hostapd_send_auth_reply(hapd, sta, WLAN_STATUS_SUCCESS);
    }
  • 状态标志sta->flags |= WLAN_STA_AUTH

3. 关联阶段:ASSOCIATING → ASSOCIATED
  • 触发事件 :STA发送 Association Request

  • AP关键处理

    c 复制代码
    // ieee802_11.c
    static void handle_assoc(struct hostapd_data *hapd, const u8 *buf, size_t len)
    {
        // 1. 验证认证状态
        if (!(sta->flags & WLAN_STA_AUTH))
            goto fail;
        
        // 2. 检查能力匹配
        if (check_ht_capab(hapd, sta, capab_info, ht_capab))
            goto fail;
        
        // 3. 分配AID
        sta->aid = ap_get_aid(hapd);
        
        // 4. 设置关联状态
        sta->flags |= WLAN_STA_ASSOC;
        
        // 5. 发送Association Response
        hostapd_send_assoc_resp(hapd, sta, WLAN_STATUS_SUCCESS);
    }
  • 状态标志sta->flags |= WLAN_STA_ASSOC

4. 密钥协商阶段 (4次握手)

AP STA Msg1(ANonce) Msg2(SNonce, MIC) Msg3(GTK, MIC) Msg4(确认) AP STA

  • AP端状态机 (在 wpa_auth.c 中实现):

    c 复制代码
    enum {
        WPA_PTK_INITIALIZE,   // 0
        WPA_PTK_START,        // 1
        WPA_PTK_PTKINITNEGOTIATING, // 2
        WPA_PTK_PTKCALCNEGOTIATING, // 3
        WPA_PTK_UPDATEKEYS,   // 4
        WPA_PTK_DONE          // 5
    };
  • 关键验证点

    • MIC 校验:wpa_verify_mic()
    • PTK 生成:wpa_pmk_to_ptk()
    • GTK 分发:wpa_send_group_msg1()
5. 授权阶段:AUTHORIZED
  • 触发条件:4次握手成功

  • AP行为

    c 复制代码
    // wpa_auth.c
    void wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
    {
        case WPA_PTK_DONE:
            sm->flags |= WPA_STA_AUTHORIZED;
            hostapd_set_sta_authorized(hapd, sta, 1);
            ieee80211_set_authorized(hapd, sta); // 激活端口
            break;
    }
  • 网络层激活

    c 复制代码
    // driver_nl80211.c
    void ieee80211_set_authorized(struct hostapd_data *hapd, struct sta_info *sta)
    {
        nl80211_set_sta_authorized(hapd, sta->addr, 1);
        // 内核解除端口阻塞
    }

安全机制状态转换

无加密 配置PSK 配置RADIUS 启用SAE OPEN WPA_PSK PTK_INIT PTK_START:收到Msg1 PTK_START PTK_DONE:完成握手 WPA_EAP EAP_IDLE EAP_AUTH:开始认证 EAP_AUTH EAP_SUCCESS:认证通过 WPA3_SAE


超时与错误处理机制

1. 认证超时
c 复制代码
// ap_drv_ops.c
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
{
    if (sta->timeout_next == STA_AUTH && 
        (os_get_time() - sta->last_auth > AUTH_TIMEOUT)) {
        ap_free_sta(hapd, sta); // 清除状态
    }
}
2. 握手失败处理
c 复制代码
// wpa_auth.c
static void wpa_sm_step(struct wpa_state_machine *sm)
{
    if (sm->PTKRequest && sm->PTKRequest_retry++ > MAX_RETRY) {
        wpa_sta_disconnect(hapd, sta); // 发送Deauth
        ap_free_sta(hapd, sta);
    }
}

关键数据结构

c 复制代码
// hostapd核心状态结构
struct sta_info {
    u8 addr[6];               // STA MAC地址
    u16 flags;                // 状态标志位
    enum wpa_states wpa_sm_state; // WPA状态机
    struct wpa_state_machine *wpa_sm;
    
    // 时间戳
    os_time_t last_auth;      // 最后认证时间
    os_time_t last_assoc;     // 最后关联时间
    
    // 安全密钥
    u8 ptk[64];              // Pairwise Transient Key
    u8 gtk[32];              // Group Temporal Key
};

// 状态标志位定义
#define WLAN_STA_AUTH        0x0001
#define WLAN_STA_ASSOC       0x0002
#define WLAN_STA_AUTHORIZED  0x0004
#define WLAN_STA_PENDING_POLL 0x0008

实际调试分析

查看状态机日志(启用 debug 模式):

bash 复制代码
hostapd -dd /etc/hostapd.conf

典型日志序列

复制代码
STA aa:bb:cc:dd:ee:ff status: AUTH -> ASSOC
WPA: PTK START for aa:bb:cc:dd:ee:ff
WPA: PTK DONE for aa:bb:cc:dd:ee:ff
AP-STA-CONNECTED aa:bb:cc:dd:ee:ff  # 最终状态

抓包分析关键帧

  1. Authentication (Seq: 0x0001)
  2. Association Request (Seq: 0x0002)
  3. EAPOL Msg1/2/3/4
  4. Data Frame (加密数据)

状态机设计特点

  1. 分层状态管理

    • MAC层:AUTH/ASSOC
    • 安全层:WPA状态机
    • 驱动层:端口授权
  2. 超时重试机制

    • 认证超时:10秒
    • 握手超时:3次重试
    • 空闲超时:5分钟(发送Null帧检测)
  3. 安全状态分离

    • PSK模式:4次握手
    • EAP模式:RADIUS状态机
    • SAE模式:Dragonfly握手
  4. 驱动交互点

    c 复制代码
    struct hostapd_driver_ops {
        int (*set_sta_authorized)(void *priv, const u8 *addr, int authorized);
        int (*send_eapol)(void *priv, const u8 *addr, const u8 *data, size_t data_len);
    };

企业级部署特殊流程

EAP-TLS 状态扩展
ASSOCIATED EAP_IDLE EAP_IDENTITY:发送Identity Request EAP_IDENTITY EAP_TLS_START:收到Identity Response EAP_TLS_START EAP_TLS_HANDSHAKE:交换证书 EAP_TLS_HANDSHAKE EAP_SUCCESS:验证成功 EAP_SUCCESS KEY_HANDSHAKE:生成MSK

  • RADIUS 集成hostapd 作为 Authenticator 与 RADIUS 服务器交互
  • 密钥派生:MSK → PMK → PTK/GTK

性能优化设计

  1. 状态缓存

    • Fast Transition:缓存 PMK-R1 避免重新认证
    c 复制代码
    struct rsn_pmksa_cache_entry {
        u8 pmk[PMK_LEN];
        u32 expiration;
    };
  2. 批量状态处理

    c 复制代码
    void ap_handle_assoc_batch(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len)
    {
        // 单次处理多个关联请求
    }
  3. 异步事件驱动

    c 复制代码
    eloop_register_timeout(0, 100000, ap_handle_timer, hapd, NULL);

总结

hostapd 的 STA 连接状态机是 WiFi 接入控制的核心,其设计特点包括:

  1. 严格分层:MAC连接 → 安全认证 → 网络授权
  2. 状态驱动:基于 IEEE 802.11 标准的帧序列触发
  3. 安全优先:所有数据通信前必须完成密钥协商
  4. 超时容错:自动清理异常状态防止资源泄漏
  5. 驱动抽象:统一接口适配不同网卡芯片

该状态机的高效实现保证了:

  • 单AP支持200+ STA并发连接
  • 漫游切换时间 < 50ms(FT优化)
  • 企业级安全策略实施
  • 多场景兼容性(家庭/企业/运营商)
相关推荐
依然易冷1 小时前
【APR-自动代码修复】论文分享:PyTy
算法
教练、我想打篮球1 小时前
63 网络交互的过程中目标设备的选择
linux·net·eth0
ggdpzhk1 小时前
输入两个正整数,计算最大公约数和最小公倍数
java·算法
Little-Hu1 小时前
linux线程同步
linux·线程·条件变量·互斥锁·信号量·线程同步·读写锁
qq_386322691 小时前
华为网路设备学习-25(路由器OSPF - 特性专题 二)
网络·学习·华为
楼台的春风2 小时前
【Linux驱动开发 ---- 4.1_sysfs 详解】
linux·运维·c语言·数据库·人工智能·驱动开发·嵌入式硬件
月光技术杂谈2 小时前
linux下MQTT订阅发布验证-mosquitto安装测试流程
linux·mqtt·订阅·mosquitto·发布·mosquitto_pub·mqtt-clients
涟涟涟涟2 小时前
UE5错误 Linux离线状态下错误 请求失败libcurl错误:6无法解析主机名
linux·ue5
听风lighting2 小时前
WebServer实现:muduo库的主丛Reactor架构
linux·运维·网络·c++·socket·webserver
Insist7533 小时前
linux操作系统---小白玩转shell脚本
linux·运维·服务器