参考:wpa_supplicant 终端连接 wifi — Linux latest 文档 (gnu-linux.readthedocs.io)
为了管理无线网卡驱动,并且能正常连接到无线网络,你需要一个无线连接管理工具。
如何选择一个最佳的管理方法,将依赖于下面几个因素:
是否使用加密及使用加密的类型
是否经常切换不同网络(如笔记本电脑)
下表按照加密和管理方式分类,列出了管理无线网络的工具。 虽然还有其他办法,但这些是最常用的。
iwconfig是啥?
参考:WIFI实践入门--基本命令--iwconfig-CSDN博客
Iwconfig类似于ifconfig,但专门用于无线接口。它用于设置特定于无线操作的网络接口的参数(例如:频率)。还可以使用Iwconfig来显示这些参数和无线统计信息(从/proc/net/wireless中提取)。所有这些参数和统计数据都依赖于设备。每个驱动程序根据硬件支持只提供其中的一部分,值的范围可能会改变。
现在大部分无线网络使用 WPA/WPA2 加密,最少需要配置 wpa_supplicant 才能连接网络。另外,wpa_supplicant 目前只能连接到已经配置好 ESSID 的无线网络。
wpa_supplicant简介
官网:Linux WPA Supplicant (IEEE 802.1X, WPA, WPA2, WPA3, RSN, IEEE 802.11i) (w1.fi)
wpa_supplicant is a WPA Supplicant for Linux, BSD, Mac OS X, and Windows with support for WPA, WPA2 (IEEE 802.11i / RSN), and WPA3. It is suitable for both desktop/laptop computers and embedded systems. Supplicant is the IEEE 802.1X/WPA component that is used in the client stations. It implements key negotiation with a WPA Authenticator and it controls the roaming and IEEE 802.11 authentication/association of the wlan driver.
wpa_supplicant is designed to be a "daemon" program that runs in the background and acts as the backend component controlling the wireless connection. wpa_supplicant supports separate frontend programs and a text-based frontend (wpa_cli) and a GUI (wpa_gui) are included with wpa_supplicant.
wpa_supplicant是Linux BSD, Mac OSX和Windows的WPA的服务,支持WPA和WPA2(IEEE 802.11i/RSN),它适用于台式机/笔记本和嵌入式系统,Supplicant是在客户端站中使用的IEEE 802.1X/WPA组件,它使用WPA身份验证器实现秘钥协商,并控制漫游和IEEEE802.11认证/关联的WLAN驱动程序。 wpa_supplicant被设计成一个在后台运行的"守护进程"程序,并作为控制无线连接的后端组件,wpa_supplicant支持单独的前端程序,包含基于文本的前端(wpa_cli)和GUI(wpa_gui)。
本文基于的下载安装等信息如下所示:
Installation Environment : Ubuntu 16.04 Download (HTTP): https://w1.fi/releases/wpa_supplicant-2.6.tar.gz Download MD5 sum: 091569eb4440b7d7f2b4276dbfc03c3c Download size: 2.6 MB Estimated disk space required: 36 MB Estimated build time: 0.4 SBU (includes optional gui)
由于wpa_supplicant 已经许久不更新,配置的方式和通用的开源库不一样。
更多参考:玩转「Wi-Fi」系列之wpa_supplicant 介绍(七)-腾讯云开发者社区-腾讯云 (tencent.com)
如图所示wpa_supplicant的迭代版本 ,最新的版本为2016年10月的2.6版本
绿色背景 = 稳定版本
白色背景 = 开发版本
版本后的字母(发布中包含的内容)
d = Host AP driver
u = Host AP driver utilities
h = hostapd
w = wpa_supplicant
第三方依赖
wpa_supplicant 依赖于 openssl , libnl , 需要提前进行安装。安装方法自行百度
配置
由于wpa_supplicant 已经许久不更新,配置的方式和通用的开源库不一样。
wpa_supplicant目录中cp defconfig .config 拷贝生成编译配置
配置文件中可以针对功能进行裁剪,适应更多的平台, 如指定openssl 库的路径, 配置libnl的版本
# Uncomment following two lines and fix the paths if you have installed OpenSSL # or GnuTLS in non-default location #CFLAGS += -I/usr/local/openssl/include #LIBS += -L/usr/local/openssl/lib # Use libnl v2.0 (or 3.0) libraries. #CONFIG_LIBNL20=y # Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) #CONFIG_LIBNL32=y
指定编译器,默认的编译器为GCC,如需要交叉编译需要修改Makefile
CC=arm-linux-gnueabihf-gcc
指定安装路径,默认的安装路径为/usr/local/目录下,交叉编译的时候需要指定路径来存放,方便打包制作文件系统,同时也不会影响系统,指定路径需要修改Makefile中
20 export LIBDIR ?= /usr/local/lib/ 21 export INCDIR ?= /usr/local/include/ 22 export BINDIR ?= /usr/local/sbin/
安装
前面的配置完成之后,执行make编译,make install 进行安装 最终生成的二进制可执行文件: wpa_supplicant 和wpa_cli 。
启动wpa_supplicant应用
wpa_supplicant是一个连接、配置WiFi的工具,它主要包含wpa_supplicant与wpa_cli两个程序。 可以通过wpa_cli来进行WiFi的配置与连接,前提要保证wpa_supplicant正常启动。
相当于wpa_supplicant 是服务端,wpa_cli 是客户端。
启动wpa_supplicant应用
wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B
-D 驱动程序名称(可以是多个驱动程序:nl80211,wext)
-i 接口名称
-c 指定启动配置文件,配置文件的模板路径为
wpa_supplicant/wpa_supplicant.conf
-B 在后台运行守护进程
配置文件 /etc/wpa_supplicant.conf文件里,添加下面代码:
ctrl_interface=/var/run/wpa_supplicant // update_config=1 // 强制更新覆盖配置
ctrl_interface指向的是一个目录,在这个目录中默认会生成一个文件/var/run/wpa_supplicant/wlan0,这是local socket address,相当于UNIX Domain Socket,程序和后台程序wpa_supplicant进行通信(其实是wpa_supplicant作为后台服务程序是通过本地socket和客户端进行通信的)
update_config = 1时会在(客户端发送SAVE_CONFIG命令)更新这个配置文件。
其他还有:
priority 网络连接优先级
ap_scan=1 AP扫描/选择,默认情况下,wpa_supplicant请求驱动程序执行AP扫描,然后 使用扫描结果选择合适的AP。 ap_scan = 1是使用nl80211进行优化的工作。 为了找到使用隐藏SSID的网络,网络块中的scan_ssid = 1可以 与nl80211一起使用。
network 选项, 配网成功之后,配置文件中会有一个network选项, 包括SSID,PSK,KEY 等信息
network={ ssid="simple" psk="very secret passphrase" priority=5 }
更多待补充
启动wpa_cli应用
wpa_cli 有命令和界面交互的方式进行操作
本文讲述的是命令的方式
一些常用的命令示例
wpa_cli -i wlan0 scan //搜索附件wifi热点 wpa_cli -i wlan0 scan_result //显示搜索wifi热点 wpa_cli -i wlan0 status //当前WPA/EAPOL/EAP通讯状态 wpa_cli -i wlan0 ping //pings wpa_supplicant
添加新的连接
wpa_cli -i wlan0 add_network //添加一个网络连接,会返回<network id> wpa_cli set_network <network id> ssid '"name"' //ssid名称 wpa_cli set_network <network id> psk '“psk”' //密码 wpa_cli set_network <network id> scan_ssid 1 wpa_cli set_network <network id> priority 1 //优先级
添加无密码的连接
//连接无密码的ssid 字段,需要添加key_mgmt=NONE去连接这个网络 network={ key_mgmt=NONE ssid="wifi-name"} set_network num ssid "wifi-name" set_network num key_mgmt NONE
保存连接
wpa_cli -i wlan0 save_config //信息保存到默认的配置文件中,前面提到的/etc/wpa_supplicant.conf
断开连接
wpa_cli -i wlan0 disable_network <network id>
连接已有连接
wpa_cli -i wlan0 list_network //列举保存过得连接 wpa_cli -i wlan0 select_network <network id> //连接指定的ssid wpa_cli -i wlan0 enable_network <network id> //使能制定的ssid
网络连接成功的配置文件示例
ctrl_interface=/var/run/wpa_supplicant/ ap_scan=1 network={ scan_ssid=1 ssid="xxxx" psk="xxxx" bssid= priority=2}
更多待补充。
wpa_supplicant目录结构简介
参考:
玩转「Wi-Fi」系列之wpa_supplicant 目录介绍(八)-腾讯云开发者社区-腾讯云 (tencent.com)
源码可以到官网进行下载
wpa_supplicant 一个庞大的开源项目, 最新版本的为2016-10-V2.6。据目前来开,WiFi相关应用层的操作基本都是wpa_supplicant 的封装,包括Android 。初步统计一下,wpa_supplicant 源文件个数 552个, 20万行代码。 分析起来工作量巨大,这条路非常难走,请读者做好准备。
wpa_supplicant 的源码目录介绍
├── ap // hostapd 相关功能 ├── common // 通用函数 ├── crypto // 各种加密功能 ├── drivers // 对接底层驱动,包括 wext 和nl80211 ├── eap_common // eap 相关 ├── eapol_auth ├── eapol_supp ├── eap_peer ├── eap_server ├── fst // fst 模块 ├── l2_packet // 链路层的访问封装 ├── p2p // WiFi P2P协议, ├── pae // ieeee802 协议 ├── radius // RADIUS:Remote Authentication Dial In User Service 消息处理 ├── rsn_supp // RSN协议, Robust Secure Network,强健安全网络),即通常所说的WPA2安全模式,是WPA 的第二个版本 ├── tls // tls 协议 ├── utils // 包括 RFC1341编解码, 通用的辅助函数, 双链表, UUID, debug, epool └── wps // wps 功能的实现
主要文件详解
核心功能
wpa_supplicant.c 程序初始化,主控制回路
wpa_supplicant/main.c main()适用于UNIX和Windows操作系统,使用命令参数来配置wpa_supplicant
events.c 驱动事件处理 wpa_supplicant_event() 相关功能
wpa_supplicant_i.h wpa_supplicant核心接口定义,不应该包含在独立模块中
通用功能
wpa_supplicant 使用通用的帮助函数,其中一些与hostapd共享,文件如下:
eloop.c和eloop.h 事件循环(select()循环与注册超时,套接字读取回调,和信号回调)
common.c和common.h 公共功能
defs.h 定义由多个文件共享
l2_packet.h,l2_packet_linux.c和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
pcsc_funcs.c pcsc_funcs.h PC/SC lite SIM和智能卡读卡器的封装
priv_netlink.h Linux内核头文件中的netlink定义的私有版本,一旦合适的版本变得可用,可以用C库头文件替换
version.h版本号定义
加密功能
md5.c和md5.h MD5(如果包含TLS的支持则用加密库替换)HMAC-MD5(用于消息真实性验证的密钥校验和)
rc4.c和rc4.h RC4(广播/默认密钥加密)
sha1.c 和sh1.h SHA-1(如果包含TLS的支持则用加密库替换) HMAC-SHA-1(用于消息真实性验证的密钥校验和) PRF-SHA-1(伪随机(密钥/随机数生成)函数) PBKDF2-SHA-1(ASCII共享密码)T-PRF (for EAP-FAST) TLS-PRF (RFC 2246)
sha256.c 和sha256.h SHA-256(如果包含TLS的支持则用加密库替换)
aes-wrap.c, aes_wrap.h aes.c AES(如果包含TLS的支持则用加密库替换)采用128位KEY的AES密钥包装算法 RFC3394(广播/默认密钥加密) One-Key CBC MAC (OMAC1)哈希AES-128,AES-128 CTR模式加密, AES-128 EAX模式加密/解密,AES-128 CBC
crypto.h加密库封装的定义
crypto_openssl.clibcrypto的封装函数 (OpenSSL)
crypto_internal.c 内部加密实现的封装函数
crypto_gnutls.c libgcrypt的封装函数(used by GnuTLS)
ms_funcs.c 和ms_funcs.h MSCHAPV2 和 LEAP 参考函数
tls.h TLS库封装的定义
tls_none.c不包括TLS功能的情况下,TLS库封装的虚拟实现
tls_openssl.c 用于openssl的TLS库封装器
tls_internal.c 用于内部TLS实现的TLS库
tls_gnutls.c 用于GnuTLS的TLS库封装器
TLS 库
asn1.c 和 asn1.hASN.1 DER解析
bignum.c 和 bignum.h Big number math
rsa.c 和 rsa.hrsa.h RSA
x509v3.c 和x509v3.hX.509v3证书解析和处理
tlsv1_client.c和tlsv1_client.hTLSv1客户端(RFC 2246)
tlsv1_client_i.h TLSv1客户端内部结构
tlsv1_client_read.cTLSv1 client:读取握手消息
tlsv1_client_write.c TLSv1 client:写握手消息
tlsv1_common.c和 tlsv1_common.h常见的TLSv1例程和定义
tlsv1_cred.c和tlsv1_cred.hTLSv1 证书
tlsv1_record.c和tlsv1_record.hTLSv1记录协议
配置
config_ssid.h 每个网络配置项目的定义
config.h wpa_supplicant配置的定义
config.c 配置解析器和常用功能
wpa_supplicant/config_file.c配置文本文件的后端(例如:wpa_supplicant.conf)
config_winreg.c Windows注册表的后端配置
控制界面
wpa_supplicant有一个控制界面可以用来获取状态信息和管理来自外部程序的操作.一个命令行界面的例子(wpa_cli)和GUI(wpa_gui)的接口包含在wpa_supplicant分发中
wpa_supplicant/ctrl_iface.c和wpa_supplicant/ctrl_iface.h控制界面的 wpa_supplicant-side
ctrl_iface_unix.c基于UNIX域套接字的控制接口后端
ctrl_iface_udp.c基于UDP套接字的控制接口后端
ctrl_iface_named_pipe.c Windows基于管道的控制接口后端
wpa_ctrl.c和wpa_ctrl.h库函数为外部程序提供对wpa_supplicant控制接口的访问
wpa_cli.c 使用wpa_supplicant控制界面的示例程序
EAP peer
EAP peer implementation是一个单独的模块,可以被其它程序使用,而不仅仅是wpa_supplicant
eap.c和eap.hEAP状态机和模式界面
eap_defs.h 通用EAP定义
eap_i.h内部定义的EAP状态机和模式,不包含在其他模块中
eap_sim_common.c 和eap_sim_common.hEAP-SIM and EAP-AKA通用代码
eap_tls_common.c 和eap_tls_common.h EAP-PEAP, EAP-TTLS, and EAP-FAST通用代码
eap_ttls.c和eap_ttls.hEAP-TTLS
eap_pax.c eap_pax_common.h eap_pax_common.c EAP-PAX
eap_psk.c eap_psk_common.h eap_psk_common.c EAP-PSK (note: this is not needed for WPA-PSK)
eap_sake.c eap_sake_common.h eap_sake_common.c EAP-SAKE
eap_gpsk.c eap_gpsk_common.h eap_gpsk_common.c EAP-GPSK
eap_aka.c eap_fast.c eap_gtc.c eap_leap.c eap_md5.c eap_mschapv2.c eap_otp.c eap_peap.c eap_sim.c eap_tls.c 其他 EAP模式实现
EAPOL supplicant
eapol_supp_sm.c和eapol_supp_sm.h EAPOL supplicant 状态机和 IEEE 802.1X处理
Windows 端口
ndis_events.c 接收NdisMIndicateStatus()事件的代码,传递它们给 wpa_supplicant driver_ndis.c,使用起来更加方便
win_if_list.c 列出当前网络接口的外部程序
测试程序
radius_client.c radius_client.h和 radius_client.h 无线电认证客户端实现eapol_test
radius.c和radius.h无线电消息处理为eapol_test
eapol_test.c独立的EPA测试工具并集成RADIUS认证客户端
preauth_test.c独立的RSN pre-authentication工具
wpa_passphrase.c WPA ASCII密码到PSK转换
wpa_supplicant 源码简介
直接参考:
玩转「Wi-Fi」系列之wpa_supplicant - main分析(九)-腾讯云开发者社区-腾讯云 (tencent.com)
玩转「Wi-Fi」系列之wpa_supplicant - main分析(十)-腾讯云开发者社区-腾讯云 (tencent.com)
main函数
int main(int argc, char *argv[]) { int c, i; // 重要的数据结构1 struct wpa_interface *ifaces, *iface; int iface_count, exitcode = -1; struct wpa_params params; // 重要的数据结构2 struct wpa_global *global; if (os_program_init()) return -1; os_memset(¶ms, 0, sizeof(params)); // 打印调试等级 params.wpa_debug_level = MSG_INFO; iface = ifaces = os_zalloc(sizeof(struct wpa_interface)); if (ifaces == NULL) return -1; iface_count = 1; //输入输出重定向到/dev/null wpa_supplicant_fd_workaround(1); //参数解析 for (;;) { c = getopt(argc, argv, "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); if (c < 0) break; switch (c) { ... // -c 指定的配置文件wpa_supplicant.conf case 'c': iface->confname = optarg; break; ... // -D 驱动名称 case 'D': iface->driver = optarg; break; // 打印等级 case 'd': #ifdef CONFIG_NO_STDOUT_DEBUG printf("Debugging disabled with " "CONFIG_NO_STDOUT_DEBUG=y build time " "option.\n"); goto out; #else /* CONFIG_NO_STDOUT_DEBUG */ params.wpa_debug_level--; break; #endif /* CONFIG_NO_STDOUT_DEBUG */ ... case 'e': params.entropy_file = optarg; break; ... //网络接口名称 case 'i': iface->ifname = optarg; break; default: usage(); exitcode = 0; goto out; } } exitcode = 0; //主要函数1 : 创建并初始化一个global global = wpa_supplicant_init(¶ms); // fst 初始化 fst_global_init() #if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE) if (!fst_global_add_ctrl(fst_ctrl_cli)) wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl"); #endif for (i = 0; exitcode == 0 && i < iface_count; i++) { struct wpa_supplicant *wpa_s; // 主要函数2 : 支持多个无线网络设备, wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL); } #ifdef CONFIG_MATCH_IFACE if (exitcode == 0) exitcode = wpa_supplicant_init_match(global); #endif /* CONFIG_MATCH_IFACE */ // 启动, wpa_supplicant 通过epoll 方式实现多路I/O复用 if (exitcode == 0) exitcode = wpa_supplicant_run(global); // 释放相关资源 wpa_supplicant_deinit(global); fst_global_deinit(); out: wpa_supplicant_fd_workaround(0); os_free(ifaces); #ifdef CONFIG_MATCH_IFACE os_free(params.match_ifaces); #endif /* CONFIG_MATCH_IFACE */ os_free(params.pid_file); os_program_deinit(); return exitcode; }
main 函数中出现的几个重要的数据接口和主要函数做进一步分析 :
首先看下wpa_interface数据接口,每个变量名有相应的注释,比较好明白意思
数据结构 wpa_interface
/** * struct wpa_interface - Parameters for wpa_supplicant_add_iface() */ struct wpa_interface { /** * confname - Configuration name (file or profile) name * * This can also be %NULL when a configuration file is not used. In * that case, ctrl_interface must be set to allow the interface to be * configured. */ // 配置文件名,也就是-c 指定的wpa_supplicant.conf const char *confname; /** * confanother - Additional configuration name (file or profile) name * * This can also be %NULL when the additional configuration file is not * used. */ const char *confanother; /** * ctrl_interface - Control interface parameter * * If a configuration file is not used, this variable can be used to * set the ctrl_interface parameter that would have otherwise been read * from the configuration file. If both confname and ctrl_interface are * set, ctrl_interface is used to override the value from configuration * file. */ // 控制接口unix socket 地址,配置文件中ctrl_interface指定的 const char *ctrl_interface; /** * driver - Driver interface name, or %NULL to use the default driver */ //驱动接口,代表nl80211 const char *driver; /** * driver_param - Driver interface parameters * * If a configuration file is not used, this variable can be used to * set the driver_param parameters that would have otherwise been read * from the configuration file. If both confname and driver_param are * set, driver_param is used to override the value from configuration * file. */ const char *driver_param; /** * ifname - Interface name */ //网络接口设备,代表wlan0 const char *ifname; /** * bridge_ifname - Optional bridge interface name * * If the driver interface (ifname) is included in a Linux bridge * device, the bridge interface may need to be used for receiving EAPOL * frames. This can be enabled by setting this variable to enable * receiving of EAPOL frames from an additional interface. */ const char *bridge_ifname; /** * p2p_mgmt - Interface used for P2P management (P2P Device operations) * * Indicates whether wpas_p2p_init() must be called for this interface. * This is used only when the driver supports a dedicated P2P Device * interface that is not a network interface. */ int p2p_mgmt; };
数据结构 wpa_global
/** * struct wpa_global - Internal, global data for all %wpa_supplicant interfaces * * This structure is initialized by calling wpa_supplicant_init() when starting * %wpa_supplicant. */ struct wpa_global { //核心数据结构 struct wpa_supplicant *ifaces; //运行时参数 struct wpa_params params; //全局控制接口 struct ctrl_iface_global_priv *ctrl_iface; //dbug通信, 暂时用不到 struct wpas_dbus_priv *dbus; struct wpas_binder_priv *binder; //driver wrapper上下文信息 void **drv_priv; //driver wrapper个数 size_t drv_count; struct os_time suspend_time; struct p2p_data *p2p; struct wpa_supplicant *p2p_init_wpa_s; struct wpa_supplicant *p2p_group_formation; struct wpa_supplicant *p2p_invite_group; u8 p2p_dev_addr[ETH_ALEN]; struct os_reltime p2p_go_wait_client; struct dl_list p2p_srv_bonjour; /* struct p2p_srv_bonjour */ struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */ int p2p_disabled; int cross_connection; struct wpa_freq_range_list p2p_disallow_freq; struct wpa_freq_range_list p2p_go_avoid_freq; enum wpa_conc_pref { WPA_CONC_PREF_NOT_SET, WPA_CONC_PREF_STA, WPA_CONC_PREF_P2P } conc_pref; unsigned int p2p_per_sta_psk:1; unsigned int p2p_fail_on_wps_complete:1; unsigned int p2p_24ghz_social_channels:1; unsigned int pending_p2ps_group:1; unsigned int pending_group_iface_for_p2ps:1; unsigned int pending_p2ps_group_freq; #ifdef CONFIG_WIFI_DISPLAY int wifi_display; #define MAX_WFD_SUBELEMS 10 struct wpabuf *wfd_subelem[MAX_WFD_SUBELEMS]; #endif /* CONFIG_WIFI_DISPLAY */ struct psk_list_entry *add_psk; /* From group formation */ };
wpa_global 的一个全局性质的上下文信息,它通过iface变量指向一个wpa_supplicant对象。
drv_priv 包含driver wrapper 所需要全局上下文信息。其中drv_conut 代表当前编译到系统中driver wrapper的个数
wpa_supplciant属于核心数据结构,一个interface 对应有一个wpa_supplicant 对象,系统中所有wpa_supplicant对象都通过next变量链接在一起, 内部还有很多的成员变量,后续有需要再补充。
相关补充
hostpad
wpa_supplicant 这个应用主要实现网卡的sta功能,其实,我们也可以将网卡设置为ap模式,只不过,这时候需要使用另外一个应用进程,即hostpad
参考:Linux系统将WiFi配置为AP模式 --- hostapd 和 udhcpd的使用说明-CSDN博客
hostapd是Linux系统上的一个带加密功能的无线接入点(access point : AP)程序。hostapd能够使得无线网卡切换为master模式,模拟AP(路由器)功能,作为AP的认证服务器,负责控制管理stations的接入和认证。hostapd 是用于接入点和身份验证服务器的用户空间守护进程。它实现了IEEE 802.11接入点管理,当前版本支持Linux(Host AP、madwifi、mac80211-based驱动)和FreeBSD(net80211)。
hostapd 被设计为一个“守护进程”程序,在后台运行并充当控制身份验证的后端组件。hostapd 支持单独的前端程序,hostapd 中包含一个基于文本的使用工具hostapd_cli。(wpa_supplicant对应的是对station模式的管理,前端程序为wpa_cli)
由于hostapd的良好特性,现在已经被广泛使用,可以说是通用的AP管理工具了。