wpa_supplicant初始化流程分析

來源:互聯網
上載者:User

原文地址::http://biancheng.dnbcw.info/win2003/242212.html

 

(以下分析基於 wpa_supplicant 0.5.10 版本)

1. 啟動命令
wpa supplicant 在啟動時,啟動命令可以帶有很多參數,目前我們的啟動命令如下:
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<ifname> : 網路介面名稱
-c<conf>: 設定檔名稱
-C<ctrl_intf>: 控制介面名稱
-D<driver>: 驅動類型
-p<driver_param>: 驅動參數
-b<br_ifname>: 橋介面名稱

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模組的對外介面,主要有以下幾種:
3.1. global control interface: 用於配置(增加或刪除)網路介面。
3.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.3. socket for ioctl: 發送命令到kernel space。
3.4. socket (netlink) for interact between kernel and userspace(AF_NETLINK, NETLINK_ROUTE): 接受kernel發送上來的event。
3.5. socket for l2 packet(PF_PACKET): 處理802.1x報文。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.