wpa_supplicant软件架构分析 (与驱动通信的接口)

1.    PF_INET socket接口,主要用于向kernel 发送ioctl命令,控制并获取相应信息。

2.    PF_NETLINK socket接口,主要用于接收kernel发送上来的event 事件。

3.    PF_PACKET socket接口,主要用于向driver传递802.1X报文。

 

主要涉及到的文件包 括:“driver.h”,“drivers.c”,“driver_wext.h”,“driver_wext.c”,“l2_packet.h”和 “l2_packet_linux.c”。其中“driver.h”,“drivers.c”,“driver_wext.h”和 “driver_wext.c”实现PF_INETsocket接口和PF_NETLINK socket接口;“l2_packet.h”和“l2_packet_linux.c”实现PF_PACKET socket接口。

 

(1)“driver.h”,“drivers.c”主要用于封装底层差异对外显示一个相同的 wpa_driver_ops接口。Wpa_supplicant可支持atmel, Broadcom, ipw, madwifi, ndis, nl80211, wext等多种驱动。

其中一个最主要的数据结构为wpa_driver_ops, 其定义了driver相关的各种操作接口。

 

(2)“driver_wext.h”,“driver_wext.c”实现了wext形式的wpa_driver_ops,并创建了PF_INETsocket接口和PF_NETLINK socket接口,然后通过这两个接口完成与kernel的信息交互。

 

Wext提供的一个主要数据结构为:

struct wpa_driver_wext_data {

       void *ctx;

       int event_sock;

       int ioctl_sock;

       int mlme_sock;

       char ifname[IFNAMSIZ + 1];

       int ifindex;

       int ifindex2;

       int if_removed;

       u8 *assoc_req_ies;

       size_t assoc_req_ies_len;

       u8 *assoc_resp_ies;

       size_t assoc_resp_ies_len;

       struct wpa_driver_capa capa;

       int has_capability;

       int we_version_compiled;

 

       /* for set_auth_alg fallback */

       int use_crypt;

       int auth_alg_fallback;

 

       int operstate;

 

       char mlmedev[IFNAMSIZ + 1];

 

       int scan_complete_events;

};

其中event_sock 为PF_NETLINK socket接口,ioctl_sock为PF_INET socket借口。

 

Driver_wext.c实现了大量底层处理函数用于实现wpa_driver_ops操作参数,其中比较重要的有:

void * wpa_driver_wext_init(void *ctx, const char *ifname);

/* 初始化wpa_driver_wext_data 数据结构,并创建PF_NETLINK socket和 PF_INET socket 接口 */

 

void wpa_driver_wext_deinit(void *priv);

/* 销毁wpa_driver_wext_data 数据结构,PF_NETLINK socket和 PF_INETsocket 接口 */

 

static void wpa_driver_wext_event_receive(int sock, void *eloop_ctx,

                                     void *sock_ctx);

/* 处理kernel主动发送的event事件的 callback 函数 */

 

最后,将实现的操作函数映射到一个全局的wpa_driver_ops类型数据结构 wpa_driver_wext_ops中。

 

const struct wpa_driver_ops wpa_driver_wext_ops = {

       .name = "wext",

       .desc = "Linux wireless extensions (generic)",

       .get_bssid = wpa_driver_wext_get_bssid,

       .get_ssid = wpa_driver_wext_get_ssid,

       .set_wpa = wpa_driver_wext_set_wpa,

       .set_key = wpa_driver_wext_set_key,

       .set_countermeasures = wpa_driver_wext_set_countermeasures,

       .set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted,

       .scan = wpa_driver_wext_scan,

       .get_scan_results2 = wpa_driver_wext_get_scan_results,

       .deauthenticate = wpa_driver_wext_deauthenticate,

       .disassociate = wpa_driver_wext_disassociate,

       .set_mode = wpa_driver_wext_set_mode,

       .associate = wpa_driver_wext_associate,

       .set_auth_alg = wpa_driver_wext_set_auth_alg,

       .init = wpa_driver_wext_init,

       .deinit = wpa_driver_wext_deinit,

       .add_pmkid = wpa_driver_wext_add_pmkid,

       .remove_pmkid = wpa_driver_wext_remove_pmkid,

       .flush_pmkid = wpa_driver_wext_flush_pmkid,

       .get_capa = wpa_driver_wext_get_capa,

       .set_operstate = wpa_driver_wext_set_operstate,

};

 

(3)“l2_packet.h”和“l2_packet_linux.c”主要用于实现PF_PACKET socket接口,通过该接口,wpa_supplicant可以直接将802.1X packet发送到L2层,而不经过TCP/IP协议栈。

 

其中主要的功能函数为:

struct l2_packet_data * l2_packet_init(

       const char *ifname, const u8 *own_addr, unsigned short protocol,

       void (*rx_callback)(void *ctx, const u8 *src_addr,

                         const u8 *buf, size_t len),

       void *rx_callback_ctx, int l2_hdr);

/* 创建并初始化PF_PACKET socket接口,其中rx_callback 为从L2接收到的packet 处理callback函数 */

 

void l2_packet_deinit(struct l2_packet_data *l2);

/* 销毁 PF_PACKET socket接口 */

 

int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,

                 const u8 *buf, size_t len);

/* L2层packet发送函数,wpa_supplicant用此发送L2层 802.1X packet  */

 

static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx);

/*  L2层packet接收函数,接收来自L2层数据后,将其发送到上层  */

4. Control interface commands

       PING

       MIB

       STATUS

       STATUS-VERBOSE

       PMKSA

       SET <variable> <valus>

       LOGON

       LOGOFF

       REASSOCIATE

       RECONNECT

       PREAUTH <BSSID>

       ATTACH

       DETACH

       LEVEL <debug level>

       RECONFIGURE

       TERMINATE

       BSSID <network id> <BSSID>

       LIST_NETWORKS

       DISCONNECT

       SCAN

       SCAN_RESULTS

       BSS

       SELECT_NETWORK <network id>

       ENABLE_NETWORK <network id>

       DISABLE_NETWORK <network id>

       ADD_NETWORK

       REMOVE_NETWORK <network id>

       SET_NETWORK <network id> <variable> <value>

       GET_NETWORK <network id> <variable>

       SAVE_CONFIG


你可能感兴趣的:(wpa_supplicant软件架构分析 (与驱动通信的接口))