wpa_suplicant 详解 文章收集

wpa_suplicant 详解 文章收集

参考资料

https://w1.fi/wpa_supplicant/devel/index.html
https://zhuanlan.zhihu.com/p/24246712
https://www.cnblogs.com/lidabo/p/5062204.html
https://blog.csdn.net/jy1075518049/article/details/51015141
https://blog.csdn.net/zm19930923zm/article/details/88743533
http://blog.chinaunix.net/uid-29181887-id-4826168.html
牛人
http://blog.chinaunix.net/uid/29181887/abstract/1.html
https://blog.csdn.net/jy1075518049?type=blog
邓凡平
https://blog.csdn.net/Innost


深入理解Android:WiFi模块 NFC和GPS卷
https://itbox.cc/book/detail/9787111456834/

1. 什么是 wpa suplicant

  1. wpa_supplicant是一个开源软件项目,它实现了Station对无线网络进行管理和控制的功能。
  2. wpa_supplicant是wifi客户端(client)加密认证工具,和iwconfig不同,wpa_supplicant支持wep、wpa、wpa2等完整的加密认证,而iwconfig只能支持wep。
  3. wpa_supplicant运行于后台,它需要借助控制台工具wpa_cli来进行手动操作。
  4. wpa_supplocant相对应的,ap端的加密认证工具为hostapd。

2. wpa suplicant 的构成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tHyvZnA0-1622390012542)(https://w1.fi/wpa_supplicant/devel/_wpa_supplicant.png)]

2.1 wpa_cli 客户端程序

通过 unix 本地 socket与wpa_supplicant daemon 服务通信,发送命令 并 接收结果

2.2 wpa_suplicant daemon

对应上述中间部分,功能是 “上传下达”。所有客户端通过它 控制硬件网卡,通过发送字符串命令 控制 是否扫描 AP,提取扫描结果和是否关联 AP 等操作,同时将驱动的执行状态发送给用户。

该服务是设计支持多种无线网卡芯片,因此各个厂商共同提供了一个通用接口给 wpa_supplicant 调用

2.3 网卡驱动

对应上图的底层

3. Wpa_supplicant 作用

1、读取配置文件
2、初始化配置参数,驱动函数
3、让驱动 scan 当前所有的 bssid
4、检查扫描的参数是否和用户设置的相符
5、如果相符,通知驱动进行权限 认证操作
6、连上 AP

4. 运行 wpa supplicant 程序

在init.rc里执行

wpa_supplicant /system/bin/wpa_supplicant-Dwext 
-ieth0 -c/data/wifi/wpa_supplicant.conf 
-f /data/wifi/wpa_log.txt

两个数据结构 wpa_params, wpa_interface 用来保存 启动命令wpa_supplicant 带的参数

wpa_supplicant是可以同时支持多个网络接口的。
wpa_params 记录 与网络接口无关 的参数。
每个wpa_interface 对应一个网络接口。

在启动命令行中,可以用-N来指定将要描述一个新的网络接口。对于一个新的网络接口,可以用下面几个参数描述:
-i : 网络接口名称
-c: 配置文件名称
-C: 控制接口名称
-D: 驱动类型名称
-p: 驱动参数
-b: 桥接口名称
-d: 增加调试信息

5. wpa_supplicant 初始化流程

5.1 main()函数:

在这个函数中,主要做了四件事。
1.解析命令行传进的参数。
2.调用wpa_supplicant_init()函数,做wpa_supplicant的初始化工作。
3.调用wpa_supplicant_add_iface()函数,增加网络接口。
4.调用wpa_supplicant_run()函数,让wpa_supplicant真正的run起来。

5.2 wpa_supplicant_init()函数

  1. 打开debug 文件。
  2. 注册EAP peer方法。
  3. 申请wpa_global内存,该数据结构作为统领其他数据结构的一个核心, 主要包括四个部分:
wpa_supplicant *ifaces
/*每个 网络接口 都有一个 对应的wpa_supplicant数据结构,该指针指向最近加入的一个,在wpa_supplicant数据结构中有指针指向next*/

wpa_params params
/*启动命令行中带的通用的参数*/
ctrl_iface_global_priv *ctrl_iface 
/*global 的控制接口*/
ctrl_iface_dbus_priv *dbus_ctrl_iface
/*dbus 的控制接口*/
  1. 设置wpa_global中的wpa_params中的参数。
  2. 调用eloop_init函数 将全局变量eloop中的user_data指针指向wpa_global。
  3. 调用wpa_supplicant_global_ctrl_iface_init函数初始化global 控制接口。
  4. 调用wpa_supplicant_dbus_ctrl_iface_init函数初始化dbus 控制接口。
  5. 将该daemon的pid写入pid_file中。

5.3 wpa_supplicant_add_iface()函数

该函数根据启动命令行中带有的参数增加网络接口, 有几个就增加几个。

  1. 首先分配一个 wpa_supplicant数据结构 的内存。( wpa_supplicant 是与网络接口对应的重要的数据结构)
  2. 调用 wpa_supplicant_init_iface() 函数来做网络接口的初始工作,主要包括:
    1. 设置驱动类型,默认是wext;
    2. 读取配置文件,并将其中的信息设置到wpa_supplicant数据结构中的 conf指针 指向的数据结构(一个wpa_config类型);注: 命令行设置的 ctrl_interface 和 driver_param 覆盖 配置文件里设置(命令行中的优先);
      拷贝网络接口名称和桥接口名称到 wpa_config 数据结构;
      对于网络配置块有两个链表描述它,一个是 config->ssid,它按照配置文件中的顺序依次挂载在这个链表上,还有一个是pssid,它是一个二级指针,指向一个指针数组,该指针数组 按照优先级从高到底的顺序依次保存wpa_ssid指针,相同优先级的在同一链表中挂载。
  3. 调用 wpa_supplicant_init_iface2() 函数,主要包括:
    调用wpa_supplicant_init_eapol()函数来初始化eapol;
    调用相应类型的driver的init()函数;
    设置driver的param参数;
    调用wpa_drv_get_ifname()函数获得网络接口的名称,对于wext类型的driver,没有这个接口函数;
    调用wpa_supplicant_init_wpa()函数来初始化wpa,并做相应的初始化工作;
    调用wpa_supplicant_driver_init()函数,来初始化driver接口参数;在该函数的最后
//调用
wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
wpa_supplicant_req_scan(wpa_s, interface_count, 100000);
//来主动发起scan

//调用
wpa_supplicant_ctrl_iface_init()
//初始化控制接口

对于UNIX SOCKET这种方式,其本地socket文件是由配置文件里的ctrl_interface参数指定的路径加上网络接口名称;

5.4 wpa_supplicant_run() 函数

  1. 初始化完成之后,让 wpa_supplicant 的 main event loop run 起来。

  2. 在 wpa_supplicant 中,有许多与外界通信的 socket,它们都是需要注册到 eloop event 模块中的。
    具体地说,就是在 eloop_sock_table 中增加一项记录,其中包括了 sock_fd, handle, eloop_data, user_data。

  3. eloop event 模块就是将这些 socket 组织起来,统一管理,然后在 eloop_run 中利用 select 机制来管理 socket 的通信。

6. wpa_supplicant 的 对外 接口 分析

从通信层次上划分,wpa_supplicant 提供 向上的 control interface,用于与其他模块(如 UI)进行通信,其他模块可以通过 control interface 来获取信息或下发命令。
Wpa_supplicant 通过 socket 通信机制实现 下行接口,与内核进行通信,获取信息或下发命令。

6.1 上行接口

Wpa_supplicant 提供两种方式的上行接口。

  1. 基于传统 dbus 机制实现与其他进程间的 IPC 通信
  2. 另一种通过 Unix domain socket 机制 实现 进程间的 IPC 通信。

6.2 下行接口

Wpa_supplicant 下行接口主要包括三种:

  1. PF_INET socket 接口,
    主要用于向 kernel 发送 ioctl 命令,控制并获取相应信息。
  2. PF_NETLINK socket 接口,
    主要用于 接收 kernel 发送上来的 event 事件。
  3. PF_PACKET socket 接口,
    主要用于向 driver 传递 802.1X 报文。
    (用于接收基于链路层上的裸数据的,该协议主要用来做鉴权的,诸如wpa,wpa2,wapi)

7. wpa_supplicant用法

1 扫出可使用的ap

iwlist wlan0 scanning 

2 产生密码的加密conf文件

wpa_passphrase TP-LINK_8CEA 11111111 > /etc/wpa_supplicant.conf 


3 再根据examples的例子修改配置文件

4 连接网络

wpa_supplicant -i wlan0 -B -Dwext -c /etc/wpa_supplicant.conf
options:

-b = optional bridge interface name
-B = run daemon in the background
-c = Configuration file
-C = ctrl_interface parameter (only used if -c is not)
-i = interface name
-d = increase debugging verbosity (-dd even more)
-D = driver name (can be multiple drivers: nl80211,wext)
-e = entropy file
-g = global ctrl_interface
-K = include keys (passwords, etc.) in debug output
-t = include timestamp in debug messages
-h = show this help text
-L = show license (GPL and BSD)
-o = override driver parameter for new interfaces
-O = override ctrl_interface parameter for new interfaces
-p = driver parameters
-P = PID file
-q = decrease debugging verbosity (-qq even less)
-v = show version
-W = wait for a control interface monitor before starting
-N = start describing new interface

8. wps_cli

8.1 两种模式

  1. 交互模式
    交互模式就是直接执行wpa_cli,然后输入各种命令即可
root@am335x:~# wpa_cli
wpa_cli v0.6.9
Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors

This program is free software. You can distribute it and/or modify it
under the terms of the GNU General Public License version 2.

Alternatively, this software may be distributed under the terms of the
BSD license. See README and COPYING for more details.


Selected interface 'wlan0'

Interactive mode

> status
bssid=74:1f:4a:b2:e5:b3
ssid=QK-2
id=2
pairwise_cipher=WEP-104
group_cipher=WEP-104
key_mgmt=NONE
wpa_state=COMPLETED
ip_address=192.168.100.13
> 
  1. 命令行模式
root@am335x:~# wpa_cli status
Selected interface 'wlan0'
bssid=74:1f:4a:b2:e5:b3
ssid=QK-2
id=2
pairwise_cipher=WEP-104
group_cipher=WEP-104
key_mgmt=NONE
wpa_state=COMPLETED
ip_address=192.168.100.13
root@am335x:~# 

8.1 命令分析

8.1.1. 扫描ap

使用scan命令扫描网络,结束后使用scan_results命令查看网络。

> scan
OK

> driver_atheros_event_wireless: scan result event - SIOCGIWSCAN
<3>CTRL-EVENT-SCAN-RESULTS
<3>WPS-AP-AVAILABLE

 

> > scan_results
bssid / frequency / signal level / flags / ssid
00:23:68:26:40:c8 2412 36 [ESS] CMCC
00:26:5a:26:33:ac 2437 38 [WPA-PSK-TKIP][WPA2-PSK-TKIP][WPS][ESS] LZ205
>
8.1.2. 状态查看

status 命令是用来得到当前WPAS的状态,比如是扫描状态还是连接状态等等。
使用quit退出CLI后,可以使用iwconfig命令查看ath0连接状态。

> status

bssid=00:26:5a:26:33:ac
ssid=LZ205
id=0
mode=station
pairwise_cipher=TKIP
group_cipher=TKIP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
address=20:13:08:15:16:13
8.1.3. list_networks / list

列出所有保存的AP信息,这个要注意,执行此命令得到的配置信息并非配置文件中的AP列表,可以理解为当前内存中保存的配置列表。首先启动WPAS后,WPAS会从配置文件读取已经有的配置信息进行初始化,

比如笔者现在配置文件如下:

root@am335x:~# vi /etc/wpa_supplicant.conf 

ctrl_interface=/var/run/wpa_supplicant
update_config=1

network={
        ssid="coff_tes"
        psk="1234567890"
        disabled=1
}

network={
        ssid="QK-1"
        psk="1234567890"
        disabled=1
}

那么此时用list得到信息如下:

> list
network id / ssid / bssid / flags
0       coff_tes        any     [DISABLED]
1       QK-1    any     [DISABLED]
> 

这是初始化状态,如果后面我们用了连接命令,这个时候再list会发现配置项增多,而配置文件在执行save_config之前是不会改变的。后边笔者会再列出来。

8.1.4. 增加网络

add_network
增加一个配置项,这个命令只会增加一个配置项ID,但是配置还并没有任何内容,相当于占位。

> list
network id / ssid / bssid / flags
0       coff_tes        any     [DISABLED]
1       QK-1    any     [DISABLED]
> add_network
2

> list
network id / ssid / bssid / flags
0       coff_tes        any     [DISABLED]
1       QK-1    any     [DISABLED]
2               any     [DISABLED]
> 

此时就多了一个2号配置项,但是还没有任何内容

8.1.5. 设定网络连接的ssid和密码

set_network
这个命令非常重要,使用了设置配置的ssid、密码等信息,假如2号我们想设置成一个名为“test2”,加密方式为WPA方式的AP,密码为“1234567890”。那么可以这么写:

set_network 2 ssid "test2"
set_network 2 psk "1234567890"

此时再执行list发现有了ssid配置

> list
network id / ssid / bssid / flags
0       coff_tes        any     [DISABLED]
1       QK-1    any     [DISABLED]
2       test2   any     [DISABLED]

NONE方式

set_network 2 ssid “coffee”
set_network 2 key_mgmt NONE

WPA(WPA2)方式

set_network 2 ssid “coffee” #设置ssid
set_network 2 psk “1234567890” #设置密码

WEP方式

set_network 2 ssid “coffee” #设置ssid
set_network 2 key_mgmt NONE
set_network 2 wep_key0 “1234567890” #设置密码
set_network 2 wep_tx_keyidx 0
8.1.6. 使能网络连接

enable_network 0
select_network 2

8.1.7 config保存

save_config / save

使用save命令可以保存当前的连接设置到wpa_supplicant.conf

8.1.8 自动连接

若希望wifi启动后自动连接到预先设置的ap,只需按如下设置脚本即可以,如果预先设置里多个ap则每个网络需要设置优先级参数priority。

ctrl_interface=/var/run/wpa_supplicant
update_config=1

network={
ssid="LZ205"
psk="20100208"
priority=2
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值