wpa_suplicant 详解 文章收集

2023-05-16

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
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

wpa_suplicant 详解 文章收集 的相关文章

  • Cmakelists配置多级目录的gtest项目(项目代码和测试代码分离)

    cmake一些语法定义 之前的博客主要写了怎么配置gtest项目 xff0c 但是一般项目代码和测试代码并不在一起 xff0c 所以尝试将代码分离 主要分成三个部分 xff0c 下面给出demo的分级目录 gtest demo CMakel
  • WGS-84 ECEF ENU 坐标系学习记录

    地球坐标系固定在地球上而随地球一起在空间做公转和自转运动 xff0c 因此地球上任一固定点在地球坐标系的坐标就不会由于地球旋转而变化 地心地固直角坐标系和大地坐标系都属于这种坐标系 一 几种坐标系 地心地固直角坐标系 xff08 ECEF
  • 关于大学生计算机未来发展的个人规划

    本人今年大二 xff0c 计算机专业 xff0c 和很多大学生一样 xff0c 在大一期间仍保持着高中的习惯 xff0c 每天只是上课听讲 xff0c 课后写作业 xff0c 复习与预习 可以说 xff0c 除了课堂上老师讲的知识和书本上有
  • 关于scanf的一些注意事项

    第一点 xff0c 设定的接受变量应以地址的方式出现在scanf内 xff0c 这是因为scanf本身是一个函数 xff0c 若不加地址相当于值传递 xff0c 无法改变对应变量的值 如 xff1a 规定输入类型是整形 xff08 d xf
  • 关于长度未知,输入几组数据之后如何终止输入

    首先 xff0c 应确定结束标准 xff0c 一般题目中会给出以输入 xffe5 或者负数之类的结束 xff0c 若题中没给 xff0c 正常情况下我们自己编码是习惯以回车作为结束符号 故可以用getchar xff08 xff09 接受一
  • 关于TortoiseGit的个人见解

    首先先放一个下载链接 xff1a Download TortoiseGit Windows Shell Interface to Git TortoiseGit是一个用于用户本身和gitee之间进行文件传输的中介 xff0c 本质上是用来简
  • c语言实现扫雷

    实现在9乘9的格子内实现扫雷游戏 xff0c 可修改格子的大小和雷的个数 思路 xff1a 初始利用随机数种子生成10个雷的位置 xff0c 通过输入x xff0c y坐标来显示当前格子是否是雷 xff0c 若是雷游戏结束 xff0c 显示
  • 使用Gstreamer拉取rtsp流,使用jeston硬件加速解码,并保存buffer为图片。

    编译 xff1a g 43 43 demo666 cc o demo666 span class token variable span class token variable 96 span pkg config cflags libs
  • 矩阵键盘驱动代码

    此代码仅提供了代码思路 xff0c 具体移植应用可以私信博主 key c include 34 stm32f10x h 34 include 34 key h 34 include 34 led h 34 include 34 sys h
  • 对于vs份文件编写代码的一些个人见解

    先说明一下为何要将代码写在不同的文件中 xff0c 这对于初学者来说可能是多此一举的 xff0c 因为明明在一个文件中就能完成的事 xff0c 为何要在多个文件中分别写 xff0c 繁琐还容易出错 先让我们明确一个观点 xff0c 就是一个

随机推荐

  • 不产生新变量的情况下交换整数

    思路 xff1a 利用其中一个变量同时存储两个变量的信息 xff0c 而后利用某些运算使得可以在知道其中一个的情况下求出另外一个 具体代码如下 xff1a void exchange1 int ex1 int ex2 ex1 61 ex2
  • 如何求一个数二进制1的个数

    思路 xff1a 方法1 xff1a 可以先求二进制的样式 xff0c 再计算其中1的个数 求二进制就是不断对2除和取余 xff0c 余数组成二进制 xff0c 除的结果做下次对2除和取余 xff0c 直到数字为0 方法2 xff1a 可以
  • BLE5.0蓝牙通信原理及TI BLE协议栈在CC2642上的应用

    蓝牙可以分为经典蓝牙和低功耗蓝牙 xff0c 本文重点介绍低功耗蓝牙 xff08 BLE 一 BLE协议栈结构 以TI的CC26XX芯片为例 xff0c BLE协议栈可以由如下图所示部分组成 xff1a 1 物理层 xff1a 物理层是BL
  • RS232/RS485/CAN_BUS 通信原理总结与通信波形分析

    分析一 xff1a 232串口信号 要点 xff1a RS232 xff0c 全双工 xff0c 采用三线制传输分别为TXD RXD GND xff0c 其中TXD为发送信号 xff0c RXD为接收信号 在RS232中任何一条信号线的电压
  • SVN 拉取分支(Branch/tag)和SVN合并(Merge)

    合并 xff08 Merge xff09 例子 xff1a 把对feature branch project name v3 3 7 branch的修改合并到develop 步骤1 xff1a 如图 xff0c 右键目标文件夹 xff0c
  • 宏#define的三种基本定义方式:固定值,表达式,运算符。

    define xff1a define是C语言中的预处理命令 xff0c 预处理命令以 开头 xff0c 比如我们经常写的代码 include lt stdio h gt 也是预处理命令 define用于宏定义 xff0c 作用是方便程序段
  • 四旋翼飞行器的姿态解算小知识点

    1 惯性测量单元IMU InertialMeasurement Unit 姿态航向参考系统AHRS Attitude and Heading Reference System 地磁角速度重力MARG Magnetic Angular Rat
  • 四元数姿态解算中的地磁计融合解读

    笔者最近在做四轴 xff0c 涉及到地磁计的融合算法 xff0c 网上大多数是x IMU的融合代码 xff0c 但是这段代码对于地磁计的融合说明没有做过多的解释 xff0c 网上没有相关讨论 xff0c 仅在阿莫论坛看到一篇相关的代码解释
  • C++封装静态链接库及使用

    一 为什么要把程序封装成库 有时我们需要把自己的程序交给第三方调用 xff0c 但是又不想被别人看到自己的具体实现代码 xff0c 就封装成库给别人使用 库有动态链接库和静态链接库 xff0c 区别是动态链接库可以在程序运行时动态链接 xf
  • 四元数姿态的梯度下降法推导和解读

    笔者前面几篇文章讨论的是基于四元数的互补滤波算法 xff0c 并单独对地磁计融合部分做了详细的讨论和解释 而本文讨论的姿态融合算法叫做梯度下降法 xff0c 这部分代码可以参见Sebastian O H Madgwick在2010年4月发表
  • 四轴加速度计滤波

    加速度计滤波实验参数 xff1a 采样频率Fs 61 250Hz 截止频率Cutoff Frequency 未开电机静止 开电机悬停 未开电机转动飞控 原始输出 Raw 260 Hz 260Hz 260Hz MPU6050内部 LPF 94
  • Kalman论文笔记

    笔者前段时间阅读了一些关于Kalman的姿态论文 xff0c 本想把Kalman的知识点也整理出来发布 xff0c 无奈这编辑器不给力 xff0c 太多的公式无法复制粘贴 xff0c 图片格式上传的太复杂 xff0c 就放弃了 因此笔者只发
  • uCOS-III学习笔记

    前一段时间笔者学习uCOS III xff0c 第一次接触OS这个概念吧 下面把个人的学习笔记分享出来 xff0c 仅供参考 1 前后台系统 xff1a 后台程序是一个死循环 xff0c 也称为 任务级 xff0c 前台程序则是中断服务程序
  • 3.17 开发一个插件

    打开动态链接库 void dlopen const char filename int flag 返回一个操作句柄void Handle 61 dlopen libct so RTLD LAZY RTLD LAZY xff1a 解析动态库遇
  • 5.7 属性声明

    5 7 属性声明 主要用途 使用 attribute 来声明变量 函数的特殊属性 指导编译器来进行特定方面的优化或代码检查 使用方法 在声明后面添加 xff1a attribute ATTRIBUTE 例 xff1a int global
  • 8.18 模块设计原则:高内聚低耦合

    8 18 模块设计原则 xff1a 高内聚低耦合 模块内聚 定义 xff08 软考 xff09 块内联系 xff1a 模块内各元素的关联 交互程度 从功能角度 xff1a 自己的功能自己实现 xff0c 不麻烦其它模块 如何实现高内聚 功能
  • 9.12 中断(下):中断函数的编写

    9 12 中断 下 xff1a 中断函数的编写 中断特性 可随时打断正在执行的任务 可在任何地方打断正在执行的任务 中断返回后 xff0c CPU不一定重新执行被打断的任务 中断函数 调用时间不固定 xff1a 中断要自己保护现场 调用地点
  • 9.16 内存、外存与外设

    9 16 内存 外存与外设 按速度排列 寄存 缓存 内存 外存 存储分类 内存 又称主存 xff1a CPU能直接寻址的存储空间 存取速度快 包括 xff1a RAM ROM cache等 外存 又称辅存 xff1a 除CPU缓存和内存以外
  • 载波相位测量原理

    1 重建载波 定义 xff1a 载波调制了电文之后变成了非连续的波 xff0c 将非连续的载波信号恢复成连续的载波信号 码相关法 xff1a 方法 将所接收到的调制信号 xff08 卫星信号 xff09 与接收机产生的复制码相乘 技术要点
  • wpa_suplicant 详解 文章收集

    wpa suplicant 详解 文章收集 参考资料 https w1 fi wpa supplicant devel index html https zhuanlan zhihu com p 24246712 https www cnb