Android连载44-WPA_Supplicant相关学习

一、Wpa_Supplicant简介

  • 这是一个开源项目,实现了Station对无线网络进行管理和控制的功能

1.wpa_supplicant_init函数

struct wpa_global* wpa_supplicant_init(struct wap_params* params)
{
	struct wpa_global* global;
	init ret, i;
	...
#ifdef CONFIG_DRIVER_NDIS
		.... // windows driver支持
#endif
#ifdef CONFIG_NO_WPA_MSG
		// 设置全局回调函数
		.....
		ret = eap_register_methods();
#endif

}
  • 该函数主要用来初始化wpa_global以及一些程序相关的资源
  • 下面的第一个函数用于打印出网卡接口名,该回调函数用于获取网卡接口名
  • 第二个函数把输出信息发送给客户端进行处理
static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
void wap_msg_register_ifname_cb(wpa_msg_get_ifname_func _func)
{
	wpa_msg_ifname_cb = func;
}
static wap_msg_cb_fun wpa_msg_cb = NULL;
void wpa_msg_register_cb(wpa_msg_cb_func func) {
	wpa_msg_cb = func;
}

2.该函数的其他三个关键点

int eap_register_methods(void)
{
	int res = 0;
#ifdef EAP_MD5
	if (ret == 0)
		ret = eap_peer_md5_register();
#endif 
	...
#ifdef EAP_SERVER_MD5
		if (ret == 0)
			ret = eap)server_md5_register();
#endif
	....
		return ret;
}
  • 通过编译宏以及配置项来初始化所需要的eap方法
## 3.eloop提供的时间注册API
```cpp
int eloop_register_read_sock(int sock, eloop_sock_handler handler, void *eloop_data, void *user_data); // 注册socket读事件处理函数
int eloop_register_sock(int sock, eloop_event_type type, eloop_sock_handler handler, void *eloop_data, void *user_data); // 注册socket事件处理函数
int ellop_register_timeout(unsigned int secs, unsigned int usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data); // 注册超时事件处理函数
int eloop_register_signal(int sig, eloop_sign_handler handler, void *user_data); // 注册信号事件处理函数

二、wpa_drivers数组 和 driver i/f 模块

  • 直接上代码
	struct wpa_driver_ops* wap_drivers[] = {
#ifdef CONFIG_DRIVER_WEXT &wpa_diver_wext_ops,
#endif
#ifdef CONFIG_DRIVER_NL80211 &wpa_driver_nl80211_ops,
#endif
}
  • 下面是wap_driver_nl80211_ops的源码
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
	.name = "nl80211",
	.desc = "Linux nl80211/cfg80211",
	.get_bssid = wpa_driver_nl80211_get_bssid,
	...
	.scan2 = wpa_driver_nl80211_scan,
	...
	.get_scan_result2 = wpa_driver_nl80211_get_scan_results,
	...
	.disassociate = wpa_driver_nl80211_disassociate,
	.autherticate = wpa_driver_nl80211_authenticate,
	...
}
  • 接下来分析两一个关键函数wpa_supplicant_add_iface

三、wpa_supplicant_add_iface函数分析

  • 所谓添加接口就是初始化设备
struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, struct wpa_interface *iface)
{
	struct wpa_supplicant *wpa_s;
	struct wpa_interface t_iface;
	struct wpa_ssid *ssid;
	....
	wpa_s = wpa_supplicant_alloc();
	....
	wpa_s->global = global;
	t_iface = *iface;
	....
	if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
		.....
	}
	// 通过dbus通知外界有新的iface加入
	if (wpas_notify_iface_added(wpa_s)) {
		....
	}
	// 通过dbus通知外界有新的无线网络加入
	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
		wpas_notify_network_added(wpas_s, ssid);
	}
	wpa_s->next = global->ifaces;
	global->ifaces = wpa_s;
	return wpa_s;
}
  • 下面介绍一下结构体
    • +next: struct wpa_ssid* // 所欲wpa_ssid对象都保存在一个链表当中,头指针保存在另外一个结构体wpa_config的ssid变量中
    • +pnext: struct wpa_ssid* // wpa_ssid喊可以按优先级保存在另一个链表之中,头指针为wpa_config的pssid比哦啊两种
    • +id : int // 每一个无线网路都有一个唯一的编号
    • +priority: int // 该网络对应的priority值,默认为0
    • +ssid: u8* // 此无线网络的ssid,也就是无线网络名
    • +ssid_len: size_t // ssid变量的长度
    • +bssid: u8数组 // 用于保存bssid,数组长度为ETH_ALEN(值为6)
    • +psk:u8数组 // 数组长度为32,用于保存WPA中的Pre-shared Key
    • +psk_set: init 、、 是否设置了上述psk参数
    • +passphrase: char* // 为WPA设置的ASCII字符密码
  • 详细介绍内部变量一些含义
    • passphrase,这个变量只和WPA /WPA2-PSK模式有光,用于存储输入的字符串密码,WPAS将他和ssid进行一定的的计算最终得到PSK
    • pairwise_cipher、group_cipher,分别表示这个无线网络的单播和组播的加密方法。
    • key_mgmt与Authentication and Key Managerment有关。
    • proto代表无线网络支持的安全协议类型
    • auth_alg 表示该无线网络所支持的身份验证算法
    • eapol_flags 和动态WEP Key相关
    • proactive_key_caching和OPC技术有关

802.1X的目的就是为了得到PMKSA

四、wps_supplicant结构体

  • wpa_supplicant结构体定义的成员变量非常多
  • L2是link layer的缩写

五、wpa_supplicant_init_iface函数分析

  • 从代码入手,下面wpa_s->confname的值为“/data/misc/wifi/wpa_supplicant.conf”
static int wpa_supplicant_init_iface(struct wpa_supplicant* wpa_s, struct wpa_interface* iface)
{
	const char* ifname, * driver;
	struct wpa_driver_capa capa;
	if (iface->confname) {
		...// CONFI_BACKEND_FILE处理,此宏指明了WPAS使用的配置项信息来源于文件
			wpa_s->conf = wpa_config_read(wpa_s->confname);
	}
}
  • 函数struct wpa_config *wpa_config_read(const char *name)函数就是解析刚才的配置文件,转换成数据结构

六、源码

  • gitee路径:https://gitee.com/dongqianrui/AndroidStudioProject/tree/master/Test1
  • CSDN:https://blog.csdn.net/weixin_44630050
  • 博客园:https://www.cnblogs.com/ruigege0000/
  • 欢迎关注微信公众号:傅里叶变换,个人账号,仅用于技术交流

你可能感兴趣的:(Android,android,学习,java)