wpa_supplicant架构
WPA 即 Wi-Fi Protected Access ,简称Wi-Fi安全访问。
wpa_supplicant是一个开源的项目代码,后来被google修改后集成到了android源码,其主要用来支持WEP、WPA、WPA2、WPA3、WPAI加密协议和加密认证;其在android源码中主要的作用就是为用户操作芯片起到一个中间件的作用,既可以独立运行操作Wi-Fi,也可以为开发人员提供调用接口,在芯片驱动和用户界面之间传递数据,不管其与用户层通信还是与芯片层通信,采用的都是netlink-socket,其大体的架构图如下

wpa_supplicant源码目录介绍
android14/external/wpa_supplicant_8/src
kotlin
android14/external/wpa_supplicant_8/
/src
├── ap // hostapd 相关功能(AP/热点模式)
├── common // 通用函数和数据结构
├── crypto // 加密算法:AES、TKIP、RC4、SHA、MD5 等
├── drivers // 底层驱动接口:nl80211(主流)、wext(已淘汰)
├── eap_common // EAP 通用框架,所有 EAP 方法共享的基础代码
├── eapol_auth // EAPOL 认证端状态机(AP/服务器端使用)
├── eapol_supp // EAPOL 客户端状态机(wpa_supplicant 核心, 手机/电脑/平板连接 Wi-Fi)
├── eap_peer // EAP 对等端实现:EAP-TLS、PEAP、TTLS、SIM 等
├── eap_server // EAP 服务器端实现(hostapd 使用)
├── fst // Fast Session Transfer,802.11ad 多频段快速切换
├── l2_packet // 二层数据包封装收发(以太网帧)
├── p2p // Wi-Fi Direct(P2P)协议,设备间直连
├── pae // Port Access Entity,802.1X 端口访问实体(实现 IEEE 802.1X 端口认证控制,管理端口的授权/未授权状态)
├── pasn // Pre-Authentication SAE/NS,WPA3 快速漫游预认证(WPA3 中用于快速漫游的预认证机制,与 SAE(WPA3-Personal)配合使用,实现快速 BSS 切换)
├── radius // RADIUS 协议,企业认证服务器通信
├── rsn_supp // RSN(Robust Security Network):WPA2/WPA3 安全协议
├── tls // TLS/SSL 协议栈,用于 EAP 隧道加密
├── utils // 工具函数:eloop事件循环、链表、UUID、debug等
└── wps // Wi-Fi Protected Setup,一键配对功能 (Wi‑Fi Protected Setup = Wi-Fi 保护设置)
目录关系图:
scss
src/
├── 驱动层:drivers, l2_packet
├── 核心认证:eapol_supp, eapol_auth, eap_common, eap_peer, eap_server, pae
├── 安全协议:rsn_supp, crypto, tls
├── 网络模式:ap (热点), p2p (直连), wps (配对)
├── 企业认证:radius
├── 高级功能:fst (多频段), pasn (WPA3预认证)
└── 基础设施:common, utils
TLS组件(tls目录)
1.了解TLS
TLS(传输层安全性协议,Transport Layer Security)是互联网上最常用的安全协议之一。它的前身是 SSL(安全套接层) ,现在TLS已经取代了SSL。简单来说,TLS就是给网络通信加上的一个 "安全防护罩",确保你发送和接收的数据是私密、完整且来源可信的。
| 项目 | 说明 |
|---|---|
| 全称 | T ransport L ayer Security(传输层安全协议) |
| 前身 | SSL(Secure Sockets Layer,安全套接层) |
| 作用 | 在两个通信应用程序之间提供加密、认证、完整性保护 |
| 位置 | 位于传输层(TCP/UDP)之上,应用层之下 |

作用:在不安全的网络上,建一条 "加密、防窃听、防篡改、可认证" 的安全通道。
markdown
# TLS 到底解决什么问题?
1. **加密**:别人抓包也看不懂内容
2. **认证**:确认对方是谁(防冒充)
3. **完整性**:数据没被篡改
4. **防重放**:别人不能复制包重发
diff
# TLS 在 wpa_supplicant_8 / Wi‑Fi 里到底干嘛?
你现在看的是 wpa_supplicant 内部自带的轻量 TLS(不是 OpenSSL),它主要用于:
### 1. 企业 Wi‑Fi 802.1X 认证
EAP-TLS、PEAP、TTLS 这些企业加密方式 底层全靠 TLS。
流程:
- 手机 / 车机 → 连公司 Wi‑Fi
- 先和服务器 **建 TLS 安全通道**
- 再在通道里输账号密码 / 证书
- 防止密码被抓包偷走
### 2. 证书认证
TLS 负责:
- 解析 X.509 证书
- 验证证书是否合法
- 验证服务器是不是真的
### 3. 密钥协商
通信双方用 TLS 协商出**加密密钥**,后面 Wi‑Fi 数据传输就用这个密钥加密。
2.为什么需要TLS?
想象一下,你在网上购物,输入信用卡号、密码等敏感信息。如果没有TLS,这些数据就像在公共场所大声喊出来,任何人都可以听到(窃听)、修改(篡改)或者冒充对方(伪造)。TLS通过加密和身份验证解决了这三个核心问题:
- 机密性:数据被加密,只有真正的接收方才能解密,中间人看到的只是一堆乱码。
- 完整性:数据在传输过程中如果被篡改,接收方能够检测到。
- 身份验证:你能够确认对方就是它声称的那个服务器(比如,你访问的银行网站确实是银行,而不是钓鱼网站)。
3.TLS是如何工作的?
TLS的工作流程可以简化为两个阶段:握手阶段和记录阶段。
-
握手阶段(相当于见面互相确认身份并商量暗号):
- 客户端(比如浏览器)向服务器发起连接请求,并告诉服务器它支持的加密算法列表。
- 服务器选择一个双方都支持的加密算法,并发送自己的数字证书(证明自己是合法的服务器)给客户端。
- 客户端验证证书的合法性(是否由可信机构签发,是否在有效期内等)。如果证书没问题,客户端生成一个用于后续通信的对称密钥,用服务器的公钥加密后发送给服务器。
- 服务器用自己的私钥解密,得到对称密钥。此时双方都有了同一个对称密钥。
- 双方互相发送一条确认消息,握手完成。
-
记录阶段(用商量好的暗号加密通信):
- 之后所有的应用数据(如网页内容、表单提交等)都使用握手阶段协商好的对称密钥进行加密传输。接收方收到后解密,确保数据没有被偷看或篡改。
diff
# TLS 的结构
TLS 分两层:
### 1. 记录层(Record Protocol)
- 把数据分片
- 加密 / 解密
- 校验完整性对应文件:tlsv1_record.c
### 2. 握手层(Handshake Protocol)
- 协商用什么加密算法
- 交换证书
- 验证身份
- 生成会话密钥对应文件:tlsv1_client*.c tlsv1_server*.c
4.日常生活中的TLS
- HTTPS:你在浏览器地址栏看到的小锁图标,就代表当前网页使用了TLS。HTTP加上TLS就是HTTPS。
- 安全邮件:某些邮件协议(如SMTPS、IMAPS)也用TLS加密邮件传输。
- Wi-Fi安全:在企业级Wi-Fi认证中(如EAP-TLS),TLS被用来在客户端和认证服务器之间建立安全隧道,保护用户名和密码。
- VPN:很多VPN协议也依赖TLS来建立安全连接。
5.打个比方(生活类比)
- 没有TLS的通信就像寄明信片:内容完全公开,邮递员甚至路人都能看见。
- 有了TLS的通信就像寄一个带锁的保险箱:你(客户端)和收件人(服务器)先互相确认身份,然后商量好用什么锁[钥匙锁、密码锁](加密算法),接着你把要发送的东西放进保险箱,用收件人给你的锁锁上(用公钥加密),只有收件人自己的钥匙(私钥)能打开。之后你们就用一把共同的锁(对称密钥)来交换更多信息,高效又安全。
总之,TLS是现代互联网安全的基石,它默默守护着你的每一次网上冲浪、在线购物和敏感信息传输。
ASN.1(Abstract Syntax Notation One)是数据序列化标准,
DER(Distinguished Encoding Rules)是其二进制编码规则,用于解析 X.509 证书等
bash
android14/external/wpa_supplicant_8/src/tls$ ls -l
TLS组件:
【基础编码与数学】
asn1.c/h ASN.1 DER 解析:证书、密钥等数据的序列化/反序列化
bignum.c/h 大数运算:RSA/ECC 的基础数学运算
libtommath.c LibTomMath 库:完整的大数运算库
【公钥基础设施】
rsa.c/h RSA 算法:非对称加密、数字签名
pkcs1.c/h PKCS #1:RSA 填充和签名方案
pkcs5.c/h PKCS #5:基于密码的密钥派生(PBKDF)
pkcs8.c/h PKCS #8:私钥编码格式(支持加密保护)
x509v3.c/h X.509 v3 证书:解析证书链、验证证书
【TLS 客户端】
tlsv1_client.c/h TLS 客户端主逻辑:状态机、握手流程
tlsv1_client_i.h 客户端内部数据结构
tlsv1_client_read.c 记录层接收:解析 TLS 记录(握手/数据/警报)
tlsv1_client_write.c 记录层发送:构建 TLS 记录
tlsv1_client_ocsp.c OCSP 支持:在线证书状态查询
【TLS 服务器端】
tlsv1_server.c/h TLS 服务器主逻辑(hostapd 使用)
tlsv1_server_i.h 服务器内部结构
tlsv1_server_read.c 服务器接收处理
tlsv1_server_write.c 服务器发送处理
【TLS 通用组件】
tlsv1_common.c/h TLS 通用函数:密码套件、PRF、密钥派生
tlsv1_cred.c/h 凭证管理:证书/私钥/CA 链的配置加载
tlsv1_record.c/h 记录层协议:分段、压缩、加密、MAC
这些文件共同构建了一个轻量级的 TLS 协议栈,专为 wpa_supplicant 的 EAP-TLS、EAP-PEAP、EAP-TTLS 等需要 TLS 隧道的方法设计。
TLS 就是一个负责:加密 + 认证 + 防篡改 + 建安全通道 的底层安全协议。在 wpa_supplicant 里,它是企业 Wi‑Fi(802.1X/EAP)的安全基石。
6.一个疑问?
那么个人,家庭 wifi就用不到TLS了吗?
简单来说:在你连接家庭Wi-Fi的过程中,确实没有直接用到TLS,但在你连上Wi-Fi之后上网的过程中,天天都在用。
这里需要区分两个层面:一个是连接Wi-Fi本身 (链路层安全),另一个是上网浏览数据(应用层安全)。
markdown
1. 连接Wi-Fi:用WPA2/WPA3,不用TLS
当你把手机拿出来,输入家里的Wi-Fi密码并点击连接时,手机和路由器之间进行的是一次**WPA2或WPA3的握手**。
- 用的什么:这个环节使用的是 **WPA2(Wi-Fi保护访问2)** 或 **WPA3** 协议,而不是TLS。它主要靠"预共享密钥"(就是你设置的那个Wi-Fi密码)来进行认证和加密。
- 为什么不用TLS:因为TLS通常需要证书和复杂的公钥基础设施(PKI,即管理公钥加密的系统),适合"客户端验证服务器是否可信"的场景。而在家里,路由器是你自己买的,你只需要输入正确的密码即可,不需要路由器出示CA(证书颁发机构)签发的证书来证明自己是"真路由器"。
- 结论:你在家里的路由器上设置"WPA2-PSK(预共享密钥)"或"WPA3-SAE(同时认证对等体)"模式,这就属于WPA协议的工作范畴,而不是TLS的工作范畴
### 2. 上网过程:天天在用TLS
当你成功连上家里的Wi-Fi,开始浏览网页、购物、刷朋友圈时,情况就变了。
- **场景**:你打开淘宝App或者访问网上银行。
- **发生了什么**:这时候,你的手机和淘宝的服务器之间会建立一条**TLS隧道**。你会看到浏览器地址栏有个小锁标志。
- **为什么需要TLS**:因为数据要在公共互联网上穿行,需要保护你的支付密码、个人信息不被泄露。
- **结论**:你家里的Wi-Fi只是把你送到了互联网的门口,而TLS是在互联网这个大马路上保护你的数据。
总结:
-
在家庭网络:
- 连接阶段 :用的是 WPA2/WPA3(就像用钥匙开门)。
- 上网阶段 :用的是 TLS(就像进了门之后,把重要文件放进保险箱寄出去)。
-
为什么感觉不到TLS:因为你的浏览器和App帮你自动完成了TLS的协商,你只需要看到那个小绿锁图标就行。所以,TLS依然守护着你在家庭网络中的每一次网购和隐私浏览。
加密组件(crypto目录)
MD4、MD5、SHA-1、SHA-256、SHA-384、SHA-512 这些哈希算法的简要介绍和对比表格。
哈希函数(散列函数)是一种将任意长度的数据映射为固定长度输出(哈希值)的数学函数。它主要用于数据完整性校验、数字签名、密码存储等场景。
1.各算法对比表
| 算法名称 | 输出长度(位) | 输出长度(字节) | 设计时间 | 安全状态 | 主要用途 | 说明 |
|---|---|---|---|---|---|---|
| MD4 | 128 位 | 16 字节 | 1990 年 | 极不安全,已破解 | 早期文件完整性校验(现已废弃) | 碰撞攻击极易实现,不应再使用。 |
| MD5 | 128 位 | 16 字节 | 1992 年 | 不安全,已破解 | 曾广泛用于文件校验、密码哈希(现已淘汰) | 可快速生成碰撞,不适用于安全敏感场景。 |
| SHA-1 | 160 位 | 20 字节 | 1995 年 | 不安全,已破解 | 过去用于数字证书、Git版本控制等 | 理论碰撞攻击已实现,主流浏览器已拒绝SHA-1证书。 |
| SHA-256 | 256 位 | 32 字节 | 2001 年 | 安全(截至2025年) | 数字证书、区块链、TLS、WPA3等 | SHA-2系列成员,目前广泛使用。 |
| SHA-384 | 384 位 | 48 字节 | 2001 年 | 安全 | 更高安全需求场景(如TLS 1.2/1.3) | SHA-2系列,输出更长,安全性更高。 |
| SHA-512 | 512 位 | 64 字节 | 2001 年 | 安全 | 极高安全需求(如密码哈希、数字签名) | SHA-2系列,在64位系统上性能较好。 |
2.补充说明
- MD(Message Digest)系列:由Ronald Rivest设计,MD4和MD5因设计缺陷和计算能力提升已被彻底攻破,存在有效的碰撞攻击(即能构造两个不同文件产生相同哈希)。
- SHA(Secure Hash Algorithm)系列 :由美国国家标准与技术研究院(NIST)发布。
- SHA-1:理论攻击已证明,实际碰撞也已实现(如Google的SHAttered攻击),目前被普遍弃用。
- SHA-2:包括SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/256等,至今未被攻破,是当前的主流哈希算法。
- SHA-3(未在表中):下一代哈希标准,但SHA-2仍足够安全。
在 wpa_supplicant 中,这些算法用于各种安全协议:
- MD5:用于旧版PEAP/MSCHAPv2等(现已很少使用)。
- SHA-1:用于WPA2的密钥派生(但WPA3已改用SHA-256)。
- SHA-256:用于WPA3、TLS 1.2/1.3、EAP-TLS等。
- SHA-384/512:用于更高安全级别的TLS连接或特定政府应用。
3. AES 的各种模式都是什么?
可以把 AES 想象成一个功能强大的"加密锁",而模式就是使用这把锁的不同方法,有的侧重保密,有的侧重完整性校验,有的两者兼顾。
| 模式 | 主要功能 | 通俗解释 | 典型应用 |
|---|---|---|---|
| CBC | 保密性 | 像一个链条,每个密文块都依赖前一个块,能隐藏数据模式,但无法防篡改 。 | 老式文件加密、SSL/TLS(早期版本) |
| CTR | 保密性 | 像一个计数器,把 AES 当流密码用,支持并行计算,性能高,但同样不提供完整性校验 。 | 需要高速加密的场合。 |
| CCM | 认证加密 (AE) 保密 + 完整性 | CTR + CBC-MAC 的组合。先算校验值,再加密,兼顾了 CTR 的性能和消息认证 。 | WPA2 的强制标准(即 CCMP) 。 |
| GCM | 认证加密 (AE) 保密 + 完整性 | CTR + GMAC 的组合。比 CCM 更适合并行计算,性能更好,是当前的主流 。 | WPA3 的强制标准(即 GCMP) 、TLS 1.2/1.3 |
| EAX | 认证加密 (AE) | 也是 CTR + OMAC 的组合,设计上比 CCM 更简洁、更安全 。 | 某些对安全性要求较高的专用协议 |
| SIV | 合成初始化向量模式 | 如果重复使用随机数,CCM/GCM 会直接崩溃(安全失效),而 SIV 只是泄露信息,不会崩溃,适用于密钥包装等场景 。 | 密钥包装、磁盘加密 |
| OMAC1 | 消息认证码 (MAC) | 专门用来计算消息的完整性(校验值),本身不加密数据 。 | 验证数据是否被篡改 |
| Wrap | 密钥包装 | 专门用于加密和保护其他密钥(如组密钥),RFC 3394 标准 。 | WiFi 中组密钥的分发 |
总结:
- CCMP / GCMP :它们分别对应代码
aes-ccm.c和aes-gcm.c。 - 模式的意义 :这些模式解决了 AES 不能直接加密任意长度数据、无法校验数据是否被篡改的问题。例如,WPA2 的安全核心就是 AES 加密算法 + CCM 工作模式 ,两者结合成为 CCMP 协议 。
diff
android14/external/wpa_supplicant_8/src/crypto
【基础哈希与消息认证码】
- md5.c / md5.h:提供 MD5 哈希和 HMAC-MD5(若编译时使用外部加密库如 OpenSSL,则这些内部实现可能被替换)。
- sha1.c / sha1.h:提供 SHA-1 哈希和 HMAC-SHA-1(同样可被外部库替换)。衍生文件:
- `sha1-prf.c`:PRF-SHA-1 伪随机函数(用于密钥/随机数生成)。
- `sha1-pbkdf2.c`:PBKDF2-SHA-1(从口令派生密钥,用于 WPA-PSK)。
- `sha1-tprf.c`:T-PRF(用于 EAP-FAST)。
- `sha1-tlsprf.c`:TLS-PRF(RFC 2246,用于 TLS 密钥派生)。
- sha256.c / sha256.h:SHA-256 哈希及 HMAC-SHA-256。相关文件:
- `sha256-prf.c`、`sha256-tlsprf.c`、`sha256-kdf.c`(密钥派生函数)。
- sha384.c / sha384.h、sha512.c / sha512.h:SHA-384 和 SHA-512 哈希,及其 PRF/KDF 实现。
- md4-internal.c:MD4 哈希(用于 MSCHAPv2 等旧协议)。
- ms_funcs.c / ms_funcs.h:MSCHAPv2 和 LEAP 的相关函数。
【对称加密】
- rc4.c / rc4.h:RC4 流密码(用于 TKIP 和某些 EAP 方法)。
- aes-***:AES 算法实现,支持多种模式(若使用外部库可替换):
- `aes-internal.c`:AES 基础(密钥扩展、加解密)。
- `aes-cbc.c`:CBC 模式。
- `aes-ctr.c`:CTR 模式。
- `aes-ccm.c`:CCM 模式(计数器与 CBC-MAC 组合)。
- `aes-gcm.c`:GCM 模式(伽罗瓦/计数器模式)。
- `aes-eax.c`:EAX 模式。
- `aes-siv.c`:SIV 模式(合成初始化向量)。
- `aes-omac1.c`:CMAC/OMAC1 消息认证码。
- `aes-wrap.c` / `aes-unwrap.c`:AES 密钥包装算法(RFC 3394),用于加密组密钥(常称"广播/默认密钥加密")。
- des-internal.c:DES 算法(用于某些旧协议,如 LEAP)。
【公钥加密与密钥交换】
- dh_groups.c / dh_groups.h:Diffie-Hellman 群组参数(用于 WPS 和 TLS)。
- dh_group5.c:特定的 DH 群组 5(1536 位素数)。
- crypto_internal-rsa.c、crypto_internal-modexp.c:内部实现的 RSA 和模幂运算(当未使用外部库时)。
【随机数生成】
- random.c / random.h:伪随机数生成器(用于生成密钥、Nonce 等),支持从系统获取熵。
【3GPP 认证】
- milenage.c / milenage.h:MILENAGE 算法(用于 3GPP 认证,如 EAP-SIM/AKA)。
【加密库封装层】
- crypto.h:定义统一的加密 API,屏蔽底层实现。
- crypto_openssl.c:封装 OpenSSL 的 libcrypto 函数。
- crypto_gnutls.c:封装 GnuTLS 使用的 libgcrypt 函数。
- crypto_internal.c:内部加密实现的封装(与 crypto_internal-*.c 配合)。
- crypto_wolfssl.c:封装 WolfSSL 库。
- crypto_libtomcrypt.c、crypto_nettle.c、crypto_linux.c:其他可选加密库的封装。
- crypto_none.c:空实现,用于无加密需求时。
【TLS 库封装层】
- tls.h:定义统一的 TLS API。
- tls_openssl.c:封装 OpenSSL 的 TLS 功能(含 `tls_openssl_ocsp.c` 处理 OCSP)。
- tls_gnutls.c:封装 GnuTLS 的 TLS 功能。
- tls_wolfssl.c:封装 WolfSSL 的 TLS 功能。
- tls_internal.c:内部实现的 TLS 协议栈(基于 src/tls 目录下的代码)。
- tls_none.c:虚拟实现,用于禁用 TLS 功能时。
【测试与杂项】
- fips_prf_*.c:FIPS 标准的伪随机函数实现(分别对应不同后端)。
- crypto_module_tests.c:加密模块的自测试代码。
配置组件
bash
android14/external/wpa_supplicant_8/
./wpa_supplicant/config_ssid.h #该文件定义了 `struct wpa_ssid`,用于表示一个无线网络的所有配置参数(SSID、密码、安全协议等)。
./wpa_supplicant/config.h #该文件定义了 `struct wpa_config`(全局配置)以及相关函数原型。
./src/utils/config.h
./wpa_supplicant/config.c #该文件实现了 wpa_supplicant 的配置解析函数(如从文本文件读取配置、写入配置等),以及操作 `struct wpa_config` 的辅助函数。
./src/utils/config.c
./hostapd/config_file.c #hostapd 的配置文件后端,功能类似,但解析的是 hostapd 的配置文件。
./wpa_supplicant/config_file.c #该文件实现了从文本文件(如 `wpa_supplicant.conf`)读取和写入配置的具体操作,是配置的"文件后端"。
./wpa_supplicant/config_winreg.c#该文件实现了在 Windows 系统上从注册表读取配置的功能,作为配置的另一种后端。
控制组件
bash
android14/external/wpa_supplicant_8/
./hostapd/ctrl_iface.h #这是 hostapd(AP 模式守护进程)的控制接口实现,与 wpa_supplicant 的控制接口设计类似,但用于管理 AP 功能(如设置 SSID、添加黑名单等)。在 Android 中,当设备开启热点时,会通过这个接口与 hostapd 交互
./hostapd/ctrl_iface.c
./wpa_supplicant/ctrl_iface.h #这是 wpa_supplicant #控制接口的**核心实现**,负责处理来自外部的命令(如扫描、连接、配置)和事件通知(如连接状态变化),是所有后端(UNIX、UDP、named pipe)的统一入口
./wpa_supplicant/ctrl_iface.c
【简单说:"后端" 就是控制接口的**具体通信实现方式**】
./wpa_supplicant/ctrl_iface_unix.c #基于 UNIX 域套接字的控制接口后端(在 Linux/Android 等系统中,这是最常用的后端,通过本地 UNIX socket(如 `/var/run/wpa_supplicant/wlan0`)与 wpa_cli、wpa_gui 等工具通信,安全性高、性能好)
./wpa_supplicant/ctrl_iface_udp.c #基于 UDP 套接字的控制接口后端(用于通过网络(UDP 端口)远程控制 wpa_supplicant,主要用于调试或特殊场景,Android 上默认不启用)
./wpa_supplicant/ctrl_iface_named_pipe.c #Windows 基于管道的控制接口后端(这是 Windows 平台特有的后端,通过命名管道实现控制接口,在 Android 上不会编译和使用)
./wpa_supplicant/wpa_cli.c
./src/common/wpa_ctrl.h #库函数为外部程序提供对 wpa_supplicant 控制接口的访问(这是**客户端库**,封装了控制接口的协议细节(如命令格式、事件解析),外部程序(如 wpa_cli、Android framework)通过调用这些 API 来与 wpa_supplicant 交互,而不需要直接操作 socket)
./src/common/wpa_ctrl.c
总结
- "后端" = 控制接口的具体通信方式(解决 "怎么传命令" 的问题);
- UNIX 域套接字后端是 Android 上的默认 / 唯一实际使用的方式,基于本地文件套接字实现进程间通信;
- 核心逻辑(
ctrl_iface.c)定义 "传什么",后端(ctrl_iface_unix.c)定义 "怎么传"。
markdown
wpa_supplicant 的控制接口核心逻辑(`ctrl_iface.c`)只定义了 "要处理什么命令"(比如 `SCAN`、`CONNECT`),但**不管 "怎么接收 / 发送命令"** ------ 这部分 "怎么传" 的工作,就交给不同的 "后端":
- `ctrl_iface_unix.c`:用 UNIX 域套接字来传命令 / 结果;
- `ctrl_iface_udp.c`:用 UDP 网络套接字来传(比如远程调试);
- `ctrl_iface_named_pipe.c`:用 Windows 命名管道来传(Android 不用)
通用组件
bash
android14/external/wpa_supplicant_8/
./src/utils/eloop.h:#事件循环(select()循环与注册超时,套接字读取回调,和信号回调);这是 wpa_supplicant 的核心事件驱动框架,基于 select() 或 poll() 实现跨平台的事件处理。它支持注册三类事件:文件描述符可读/可写回调、定时器超时回调、信号处理回调。所有主要的 I/O 和定时任务都依赖它
./src/utils/eloop.c
./src/utils/common.h:#公共功能;提供常用工具函数和宏,例如内存操作(os_* 系列)、字节序转换、字符串处理、错误打印(wpa_printf 底层)、时间函数、位操作等。这些函数屏蔽了平台差异,是其他模块的基础依赖。
./src/utils/common.c
./src/utils/pcsc_funcs.h #PC/SC lite SIM和智能卡读卡器的封装;这是对 PC/SC Lite API 的封装,用于通过读卡器访问 SIM 卡或智能卡,主要服务于 EAP-SIM/AKA 认证方法。它实现了与 PC/SC 服务交互的底层细节。
./src/utils/pcsc_funcs.c
./src/common/defs.h #定义由多个文件共享;该文件定义了一系列全局常量、枚举和宏,例如加密套件(WPA_CIPHER_*)、认证算法(WPA_KEY_MGMT_*)、协议版本、状态码等,被 wpa_supplicant 和 hostapd 共同使用。
./src/common/version.h:#版本号定义;
./src/l2_packet/l2_packet.h
./src/l2_packet/l2_packet_linux.c
./src/l2_packet/l2_packet_pcap.c #第2层(链路层)访问包装(包括本地Linux实现和libdnet/libpcap的包装).当移植一个新操作系统不支持libdnet/libpcap时,需要添加新的l2_packet实现.Makefile可以选择包含哪个l2_packet实现,l2_packet_linux.c使用Linux数据包套接字和l2_packet_pcap.c有一个更精简的版本使用libpcap和libdnet;
./src/drivers/priv_netlink.h #Linux内核头文件中的netlink定义的私有版本,一旦合适的版本变得可用,可以用C库头文件替换;该文件是从 Linux 内核头文件复制而来的 netlink 相关定义(如 struct nlmsghdr、genlmsghdr 等),目的是避免直接依赖系统头文件版本差异,确保 wpa_supplicant 在内核头文件不完整或版本过旧的系统上也能编译通过。
核心组件
bash
android14/external/wpa_supplicant_8/
./wpa_supplicant/wpa_supplicant.c #daemon(守护进程)程序主文件,负责wpa_supplicant的初始化。该文件包含 wpa_supplicant 的核心逻辑,如 wpa_supplicant_init()、wpa_supplicant_run() 等,负责初始化全局结构、注册事件处理、启动主事件循环,但不包含 main 函数。程序入口在 main.c
./wpa_supplicant/main.c #deamon(守护进程)启动文件,wpa_supplicant兼容于UNIX和Windows操作系统,通过命令参数来配置wpa_supplicant
./hostapd/main.c
./wpa_supplicant/events.c #负责驱动事件处理,wpa_supplicant_event()对应的处理逻辑。该文件实现了 wpa_supplicant_event(),用于处理来自驱动的事件(如扫描完成、连接成功、断开连接等),并根据事件类型调用对应的处理函数
./wpa_supplicant/wpa_supplicant_i.h #wpa_supplicant核心接口定义以及关键数据结构的定义。该头文件定义了 wpa_supplicant 的内部数据结构(如 struct wpa_supplicant)以及核心函数的原型,供 wpa_supplicant.c 及其他内部模块使用