supplicant 属于hostap的client客户端角色,另一角色为hostapd,即authenticator认证者,通常搭配第三方authenticator server可以实现IEEE802.1X协议的802.1x认证过程以及后续的加密过程,IEEE802.1X 2010协议将802.1x认证后的加密过程称为MACSEC,即Ethernet有线加密过程,而WIFI中的加密过程在IEEE802.11相关协议介绍。Opensource的hostap代码可以自己获取:git clone git://w1.fi/hostap.git. hostap项目工程中的wpa_supplicant即client,hostapd即authenticator,两者合在一起称之为hostap。
wpa_supplicant的初始化是从main函数开始的,其定义在wpa_supplicant文件夹下的main.c文件。一条简单的wpa_supplicant的应用程序run命令: wpa_supplicant -D xxxx -iethx -c xxxx.conf . -D 后的参数xxxx表示使用的wapper driver name,-i 后的参数ethx 为interface name -c 后的参数xxxx.conf为配置文件名。 初始化过程有几个重要的结构体或结构体指针的定义:
struct wpa_interface *iface: interface接口信息,可以看到getopt解析参数的时候 driver name,,interface name和配置文件名分别保存在 struct wpa_interface结构体的成员driver,ifname和confname中。
struct wpa_params params:保存输入参数,除上述保存在interface结构体的输入参数外,其他参数都先保存在该结构中。
wpa_global *global: gloabl全局上下文信息。它有一个成员 struct wpa_supplicant *ifaces用来指向一个wpa_supplicant对象,而所有的wpa_supplicant对象通过单向链表连接。
struct wpa_supplicant *wpa_s:这是wpa_supplicant使用最频繁的结构,常常用它来表示一个wpa_supplicant instance。通常一个wpa_interface对应一个wpa_supplicant instance。
下面来看初始化过程具体做了什么,来看下面两个重要函数.
global = wpa_supplicant_init(¶ms);
wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
第一个函数使用输入参数params初始化一个global结构,第二个函数在for循环中调用,以每个interface的信息和global为输入,初始化wpa_s , 即wpa_supplicant实例。点开 wpa_supplicant_add_iface 可以看到有以下几行代码:
wpa_s->global = global;
.........
wpa_s->next = global->ifaces; //新的wpa_s instance的next指向链表的头指针
global->ifaces = wpa_s;//链表的头指针指向新的wpa_s instance, 每次将新的节点向前插入作为头结点
这几行将所有的wpa_s instance通过链表连接,而global的ifaces指向链表的头指针。链表的每个wpa_s instance节点都有一个global变量指向同一个global全局上下文变量。至此,这几个重要变量建立起关系。