1. PF_INET socket接口,主要用於向kernel 發送ioctl命令,控制並獲取相應信息。linux
2. PF_NETLINK socket接口,主要用於接收kernel發送上來的event 事件。sass
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接口。less
(1)「driver.h」,「drivers.c」主要用於封裝底層差別對外顯示一個相同的 wpa_driver_ops接口。Wpa_supplicant可支持atmel, Broadcom, ipw, madwifi, ndis, nl80211, wext等多種驅動。socket
其中一個最主要的數據結構爲wpa_driver_ops, 其定義了driver相關的各類操做接口。函數
(2)「driver_wext.h」,「driver_wext.c」實現了wext形式的wpa_driver_ops,並建立了PF_INETsocket接口和PF_NETLINK socket接口,而後經過這兩個接口完成與kernel的信息交互。oop
Wext提供的一個主要數據結構爲:spa
struct wpa_driver_wext_data {debug
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層數據後,將其發送到上層 */
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