wpa_supplicant詳解
目前可以使用wireless-tools 或wpa_supplicant工具來配置無線網路。請記住重要的一點是,對無線網路的配置是全域性性的,而非針對具體的介面。
wpa_supplicant是一個較好的選擇,但缺點是它不支援所有的驅動。請瀏覽wpa_supplicant網站獲得它所支援的驅動列表。另外,wpa_supplicant目前只能連線到那些你已經配置好ESSID的無線網路,它可以讓您連線到那些使用WPA的AP。wireless-tools支援幾乎所有的無線網絡卡和驅動,但它不能連線到那些只支援WPA的AP。
關於WPA:
WPA是WiFi Protected Access的縮寫,中文含義為“WiFi網路安全存取”
wpa_supplicant是一個 獨立執行的 守護程序,其核心是一個訊息迴圈,在訊息迴圈中處理WPA狀態機、控制命令、驅動事件、配置資訊等。
經過編譯後 的 wpa_supplicant源程式可以看到兩個主要的可執行工具:wpa_supplicant 和 wpa_cli。wpa_supplicant是核心程式,它和wpa_cli的關係就是服務和客戶端的關係:後臺執行wpa_supplicant,使用 wpa_cli來搜尋、設定、和連線網路。
Android使用一個修改版wpa_supplicant作為daemon來控制WIFI,它是一個安全中介軟體,程式碼位於external/wpa_supplicant,為各種無線網絡卡提供統一的安全機制,wpa_supplicant是通過socket與hardware/libhardware_legacy/wifi/wifi.c通訊,如下圖1所示:
圖 1 : Android 平臺 WiFi 框架
對應上述結構,基於Android 的WiFi控制分為三大元件: 1)客戶端程式,包括wpa_cli命令列或java圖形介面程式,通過unix本地socket與wpa_supplicant daemon服務通訊,傳送命令 並 接收結果; 2)wpa_supplicant daemon服務,對應上述中間部分,功能是“上傳下達”。所有客戶端通過它 控制硬體網絡卡,通過傳送字串命令 控制 是否掃描AP,提取掃描結果和是否關聯 AP等操作,同時將驅動的執行狀態傳送給使用者。該服務是設計支援多種無線網絡卡晶片,因此各個廠商共同提供了一個通用介面給wpa_supplicant呼叫; 3)網絡卡驅動; ------------------------------
wpa_supplicant作用:
1、讀取配置檔案
2、初始化配置引數,驅動函式
3、讓驅動scan當前所有的bssid
4、檢查掃描的引數是否和使用者設定的想否
5、如果相符,通知驅動進行許可權 認證操作
6、連上AP
1.執行 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_supplicant 帶的 引數,用了 兩個資料結構 來儲存,
一個是 wpa_params, 另一個是wpa_interface. 這主要是考慮到wpa_supplicant是可以 同時支援 多個網路介面的。 wpa_params資料結構 主要記錄 與網路介面無關 的一些引數設定。 而每一個網路介面就用一個wpa_interface資料結構來記錄。 在啟動命令列中,可以用-N來指定將要描述一個新的網路介面,對於一個新的網路介面,可以用下面幾個引數描述: -i : 網路介面名稱
-c: 配置檔名稱 -C: 控制介面名稱 -D: 驅動型別名稱 -p: 驅動引數 -b: 橋介面名稱
-d: 增加除錯資訊
/system/bin/wpa_supplicant :是 wpa_supplicant可執行程式的 path;
2. wpa_supplicant 初始化流程
2.1. main()函式:
在這個函式中,主要做了四件事。 a.解析命令列傳進的引數。 b.呼叫wpa_supplicant_init()函式,做wpa_supplicant的初始化工作。 c.呼叫wpa_supplicant_add_iface()函式,增加網路介面。 d.呼叫wpa_supplicant_run()函式,讓wpa_supplicant真正的run起來。
2.2. wpa_supplicant_init()函式:
a.開啟debug 檔案。 b.註冊EAP peer方法。 c.申請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 的控制介面*/ d.設定wpa_global中的wpa_params中的引數。 e.呼叫eloop_init函式 將全域性變數eloop中的user_data指標指向wpa_global。 f .呼叫wpa_supplicant_global_ctrl_iface_init函式初始化global 控制介面。
g.呼叫wpa_supplicant_dbus_ctrl_iface_init函式初始化dbus 控制介面。 h.將該daemon的pid寫入pid_file中。
2.3. wpa_supplicant_add_iface()函式:
該函式根據啟動命令列中帶有的引數增加網路介面, 有幾個就增加幾個。 a.因為wpa_supplicant是與網路介面對應的重要的資料結構,所以,首先分配一個wpa_supplicant資料結構的記憶體。 b.呼叫wpa_supplicant_init_iface() 函式來做網路介面的初始工作,主要包括: 設定驅動型別,預設是wext; 讀取配置檔案,並將其中的資訊設定到wpa_supplicant資料結構中的conf 指標 指向的資料結構,它是一個wpa_config型別; 命令列設定的控制介面ctrl_interface和驅動引數driver_param覆蓋配置檔案裡設定,命令列中的優先; 拷貝網路介面名稱和橋介面名稱到wpa_config資料結構; 對於網路配置塊有兩個連結串列描述它,一個是 config->ssid,它按照配置檔案中的順序依次掛載在這個連結串列上,還有一個是pssid,它是一個二級指標,指向一個指標陣列,該指標陣列 按照優先順序從高到底的順序依次儲存wpa_ssid指標,相同優先順序的在同一連結串列中掛載。 c.呼叫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引數指定的路徑加上網路介面名稱;
2.4. wpa_supplicant_run()函式:
初始化完成之後,讓wpa_supplicant的main event loop run起來。 在 wpa_supplicant中,有許多與外界通訊的socket,它們都是需要註冊到eloop event模組中的,具體地說,就是在eloop_sock_table中增加一項記錄,其中包括了sock_fd, handle, eloop_data, user_data。 eloop event模組就是將這些socket組織起來,統一管理,然後在eloop_run中利用select機制來管理socket的通訊。
3. wpa_supplicant 的 對外 介面 分析
從通訊層次上劃分,wpa_supplicant提供 向上的 control interface,用於與其他模組(如UI)進行通訊,其他模組可以通過control interface 來獲取資訊或下發命令。Wpa_supplicant通過socket通訊機制實現 下行介面,與核心進行通訊,獲取資訊或下發命令。
3.1 上行介面 Wpa_supplicant提供 兩種方式 的 上行介面。一種基於傳統dbus機制實現與其他程序間的IPC通訊;另一種通過Unix domain socket機制 實現 程序間的IPC通訊。
3.1.2 . ctrl interface: 與其他外部模組互動的控制介面。 例如,在初始化時,android 平臺的wifi.c中的 wifi_connect_to_supplicant函式呼叫wpa_ctrl_open函式建立兩個socket,一個是ctrl interface,另一個就是monitor interface, monitor interface這個介面用於監測從wpa_supplicant發出的event事件。這兩個socket建立成功後,monitor interface 會發送ATTACH到wpa_supplicant模組 wpa_supplicant模組收到後,會將該客戶端的socket資訊記錄下來,用於以後傳送事件時用(由於用的是DGRAM的方式)。
3.2 下行介面 Wpa_supplicant提供的下行介面主要用於和kernel(driver)進行通訊,下發命令和獲取資訊。 Wpa_supplicant下行介面主要包括三種重要的介面: 1. PF_INET socket介面,主要用於向kernel 傳送ioctl命令,控制並獲取相應資訊。 2. PF_NETLINK socket介面,主要用於 接收kernel傳送上來的event 事件。 3. PF_PACKET socket介面,主要用於向driver傳遞802.1X報文。