wpa_supplicant 使用


(1)通過adb命令行,可以直接打開supplicant,從而運行wpa_cli,可以解決客戶沒有顯示屏而無法操作WIFI的問題,還可以避免UI的問題帶到driver。進一步來說,可以用在很多沒有鍵盤輸入和LCD輸出的安卓終端產品的操作上。

        wpa_supplicant包含兩個主要的可執行工具:wpa_supplicant和wpa_cli。wpa_supplicant是核心程序, 它和wpa_cli的關系就是服務和客戶端的關系:后台運行wpa_supplicant,使用wpa_cli來搜索、設置、和連接網絡。

(2)在wpa_cli交互模式下可以執行很多命令,列表如下:

 

Full command

Short command

Description

status

stat

displays the current connection status

disconnect

disc

prevents wpa_supplicant from connecting to any access point

quit

q

exits wpa_cli

terminate

term

kills wpa_supplicant

reconfigure

recon

reloads wpa_supplicant with the configuration file supplied (-c parameter)

scan

scan

scans for available access points (only scans it, doesn't display anything)

scan_result

scan_r

displays the results of the last scan

list_networks

list_n

displays a list of configured networks and their status (active or not, enabled or disabled)

select_network

select_n

select a network among those defined to initiate a connection (ie select_network 0)

enable_network

enable_n

makes a configured network available for selection (ie enable_network 0)

disable_network

disable_n

makes a configured network unavailable for selection (ie disable_network 0)

remove_network

remove_n

removes a network and its configuration from the list (ie remove_network 0)

add_network

add_n

adds a new network to the list. Its id will be created automatically

set_network

set_n

shows a very short list of available options to configure a network when supplied with no parameters.

See next section for a list of extremely useful parameters to be used with set_network and get_network.

get_network

get_n

displays the required parameter for the specified network. See next section for a list of parameters

save_config

save_c

saves the configuration


(3)平台操作實例(僅限於MTK平台 且具ROOT權限)

        A,首先保證ADB連入,且能運行adb remount,這樣避免系統文件只讀。然后設置wpa_cli和wpa_supplicant有較強權限。

        B,運行echo 1 > /dev/wmtWifi,啟動WIFI驅動。但是這個使能不會表現在安卓界面上層,默認是要在啟動安卓時開啟WIFI模塊的,也即設置中的WIFI要默認ON。

        C,進入/system/bin目錄,首先運行服務端wpa_supplicant。

./wpa_supplicant -iwlan0 -Dnl80211 -c/system/etc/wifi/wpa_supplicant.conf

正常啟動后的回顯如下:

不可收入態表明該服務端已經在運行了(也可能是可輸入狀態,只要后面的wpa_cali可連接就行)。-i -D -c的參數意義可直接在Help中查詢,具體有些參數可能因平台不同而有差異。

        D,另開啟一個ADB SHELL,作客戶端運行wpa_cali。如下:

cd /system/bin

wpa_cli -p /data/misc/wpa_supplicant

回顯如下說明正常並處於交互模式:


      E,執行一系列命令看看

scan


scan_results


        F,連WIFI的命令行,有以下幾種:

for AP that doesn`t have encryption
>add_network (It will display a network id for you, assume it returns 0)
>set_network 0 ssid “666”
>set_network 0 key_mgmt NONE
>enable_network 0
>quit


for AP that has WEP
>add_network (assume returns 1)
>set_network 1 ssid “666”
>set_network 1 key_mgmt NONE
>set_network 1 wep_key0 “your ap passwork”(if usting ASCII, it need
double quotation marks, if using hex, then don`t need the double quotation
marks)
>set_network 1 wep_tx_keyidx 0
>select_network 1 (optional, remember, if you are connecting with another
AP, you should select it to disable the another)
>enable_network 1

for AP that has WPA-PSK/WPA2-PSK
>add_network (assume returns 2)
>set_network 2 ssid “666”
>set_network 2 psk “your pre-shared key”
>select_network 2 (optional, remember, if you are connecting with another
AP, you should select it to disable the another)
>enable_network 2

     我自己的實驗圖如下:


以上過程就說明聯網OK,可以上網了。


參考原文:http://cache.baiducontent.com /c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246100024b8ed7a66471980853a3c50f11e41bca770216c5d61aa9bc98b4addb9922b3bcd7a742613d51742c419de8a1c729f7e875a98ea42b3e1&p=8b2a975bcd8711a052eedb2f4a4c&newp=8b2a971f81822dec08e29e7d495d92695c02dc3051dcd14f2895ff0b&user=baidu&fm=sc&query=adb+shell+wifi&qid=&p1=4

參考原文:http://blog.sina.com.cn/s/blog_55465b470100l73l.html

 

 

 

 

 

 

 

 

 

    Android系統中對於WIFI的設置集成到了“設置”中,其實跟手動設置差不多。這里介紹下如何手動連接WIFI,以方便以后調試WIFI。

        第一步要做的就是要加載WIFI模塊驅動了。當然如果你的WIFI是編譯到內核里面的,就不需要的。我們的WIFI芯片用的是BCM4330,編譯為模塊。

insmod /system/lib/modules/kernel/drivers/net/wireless/bcm4330/bcm4330.ko firmware_path=/system/vendor/firmware/bcm4330.bin \ nvram_path=/system/vendor/firmware/nvram.txt

       這樣驅動模塊加載后,需要啟動wpa_supplicant

root@android:/ # wpa_supplicant -Dwext -iwlan0 -C/data/system/wpa_supplicant -c/data/misc/wifi/wpa_supplicant.conf &  

然后ps|grep wpa看看有沒有起來,在wifi工作過程中,這個進程要始終都在的。

        接着啟動客戶端wpa_cli進行配置並連接wifi熱點

130|root@android:/ # wpa_cli -p/data/system/wpa_supplicant -iwlan0
wpa_cli v0.8.x
Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors


This program is free software. You can distribute it and/or modify it
under the terms of the GNU General Public License version 2.


Alternatively, this software may be distributed under the terms of the
BSD license. See README and COPYING for more details.






Interactive mode



其中/data/system/wpa_supplicant 是剛剛啟動wpa_supplicant的時候創建的一個套接字

接着進行搜索wifi

> scan
OK
<3>CTRL-EVENT-SCAN-RESULTS 

查看搜到的有哪些熱點

> scan_result
bssid / frequency / signal level / flags / ssid
40:16:9f:67:0f:00       2462    -42     [WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS]       HHCN-NET
b0:48:7a:49:44:68       2437    -58     [WPA2-PSK-CCMP][WPS][ESS]       HHTech.Arch
e0:05:c5:97:d8:5a       2412    -71     [WPA-PSK-CCMP][WPA2-PSK-CCMP-preauth][ESS]      1103-5
40:16:9f:67:0c:a6       2412    -74     [WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS]       hardware
b0:48:7a:49:65:54       2437    -58     [WPA-PSK-CCMP][WPA2-PSK-CCMP][WPS][ESS] Dept_driver

接着設置wifi,就連接Dept_driver這個熱點吧

> add_net
3
> set_net 3 ssid "Dept_driver"
OK


Dept_driver的加密方式是WPA2-PSK

> set_net 3 psk "password"
OK
> select_net 3
OK
<3>CTRL-EVENT-STATE-CHANGE id=0 state=0 BSSID=00:00:00:00:0[ 2752.332061] dhd_aoe_hostip_clr failed code -23
0:00
<3>CTR[ 2752.337768] dhd_aoe_arp_clr failed code 1
L-EVENT-STATE-CHANGE id=-1 state=3 BSSID=00:00:00:00:00:00
<3>CTRL-EVENT-DISCONNECTED bssid=00:00:00:00:00:00 reason=0
<3>CTRL-EVENT-STATE-CHANGE id=-1 state=0 BSSID=00:00:00:00:00:00
<3>CTRL-EVENT-STATE-CHANGE id=-1 state=3 BSSID=00:00:00:00:00:00
<3>CTRL-EVENT-SCAN-RESULTS 
<3>WPS-AP-AVAILABLE 
<3>Trying to associate with b0:48:7a:49:65:54 (SSID='Dept_driver' freq=2437 MHz)
<3>CTRL-EVENT-STATE-CHANGE id=-1 state=5 BSSID=b0:48:7a:49:65:54
[ 2753.153717] wl_iw_set_essid: join SSID=Dept_driver ch=6
<3>CTRL-EVENT-STATE-CHANGE id=3 state=6 BSSID=b0:48:7a:49:65:54
<3>Associated with b0:48:7a:49:65:54
<3>CTRL-EVENT-STATE-CHANGE id=3 state=7 BSSID=00:00:00:00:00:00
<3>CTRL-EVENT-STATE-CHANGE id=3 state=8 BSSID=00:00:00:00:00:00
<3>WPA: Key negotiation completed with b0:48:7a:49:65:54 [PTK=CCMP GTK=CCMP]
<3>CTRL-EVENT-CONNECTED - Connection to b0:48:7a:49:65:54 completed (reauth) [id=3 id_str=]
<3>CTRL-EVENT-STATE-CHANGE id=3 state=9 BSSID=00:00:00:00:00:00

> enable_net 3
OK
> q


這樣,就都設置好了,接着用dhcpd分配一個IP地址

root@android:/ # dhcpcd wlan0                                                  
dhcpcd[3940]: version 5.2.10 starting
dhcpcd[3940]: host does not support a monotonic clock - timing can skew
dhcpcd[3940]: wlan0: rebinding lease of 192.168.1.216
dhcpcd[3940]: wlan0: acknowledged 192.168.1.216 from 192.168.1.1 `�'
dhcpcd[3940]: wlan0: leased 192.168.1.216 for 7200 seconds
dhcpcd[3940]: forked to background, child pid 3971
root@android:/ # busybox ifconfig wlan0                                        
wlan0     Link encap:Ethernet  HWaddr AC:E8:7B:89:D3:C0  
          inet addr:192.168.1.216  Bcast:255.255.255.255  Mask:255.255.255.0
          inet6 addr: fe80::aee8:7bff:fe89:d3c0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6637 errors:0 dropped:25 overruns:0 frame:0
          TX packets:4357 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3825961 (3.6 MiB)  TX bytes:704832 (688.3 KiB)


這樣就完成了。可以上網了。

 

 

 

wpa_supplicant軟件架構分析

2013年11月26日 ⁄ 綜合 ⁄ 共 12345字 ⁄ 字號 ⁄ 評論關閉
 

原文地址:http://blog.csdn.net/fxfzz/article/details/6176414

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提供向上的控制接口 control interface,用於與其他模塊(如UI)進行通信,其他模塊可以通過control interface 來獲取信息或下發命令。Wpa_supplicant通過socket通信機制實現下行接口,與內核進行通信,獲取信息或下發命令。

 

3.1 上行接口

Wpa_supplicant提供兩種方式的上行接口。一種基於傳統dbus機制實現與其他進程間的IPC通信;另一種通過Unix domain socket機制實現進程間的IPC通信。

3.1.1 Dbus接口

該接口主要在文件“ctrl_iface_dbus.h”,“ctrl_iface_dbus.c”,“ctrl_iface_dbus_handler.h”和“ctrl_iface_dbus_handler.c”中實現,提供一些基本的控制方法。

 

DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message);

 

DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,

                                        struct wpa_global *global);

 

DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,

                                          struct wpa_global *global);

 

DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,

                                        struct wpa_global *global);

 

DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,

                                          struct wpa_global *global);

 

DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,

                               struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,

                                      struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,

                                    struct wpa_supplicant *wpa_s,

                                    struct wpa_scan_res *res);

 

DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,

                                      struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,

                                     struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,

                                        struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,

                                     struct wpa_supplicant *wpa_s,

                                     struct wpa_ssid *ssid);

 

DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,

                                        struct wpa_supplicant *wpa_s,

                                        struct wpa_ssid *ssid);

 

DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,

                                         struct wpa_supplicant *wpa_s,

                                         struct wpa_ssid *ssid);

 

DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,

                                             struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,

                                    struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,

                                          struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_set_smartcard_modules(

       DBusMessage *message, struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,

                                   struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,

                                      struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,

                                    struct wpa_supplicant *wpa_s);

 

DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,

                                      struct wpa_supplicant *wpa_s);

 

3.1.2 Unix domain socket 接口

該接口主要在文件“wpa_ctrl.h”,“wpa_ctrl.c”,“ctrl_iface_unix.c”,“ctrl_iface.h”和“ctrl_iface.c”實現。

 

(1)“wpa_ctrl.h”,“wpa_ctrl.c” 完成對control interface的封裝,對外提供統一的接口。其主要的工作是通過Unix domain socket建立一個control interface 的client結點,與作為server的wpa_supplicant結點通信。

 

主要功能函數:

struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);

/* 建立並初始化一個Unix domain socket的client結點,並與作為server的wpa_supplicant結點綁定 */

void wpa_ctrl_close(struct wpa_ctrl *ctrl);

/* 撤銷並銷毀已建立的Unix domain socket的client結點 */

 

int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,

                   char *reply, size_t *reply_len,

                   void (*msg_cb)(char *msg, size_t len));

 

/* 用戶模塊直接調用該函數對wpa_supplicant發送命令並獲取所需信息

 * 可以發送的命令如附件1所示 */

Note:

       Wpa_supplicant 提供兩種由外部模塊獲取信息的方式:一種是外部模塊通過發送request 命令然后獲取response的問答模式,另一種是wpa_supplicant主動向外部發送event事件,由外部模塊監聽接收。

 

       一般的常用做法是外部模塊通過調用wpa_ctrl_open()兩次,建立兩個control interface接口,一個為ctrl
interface,用於發送命令,獲取信息,另一個為monitor interface,用於監聽接收來自於wpa_supplicantevent時間。此舉可以降低通信的耦合性,避免responseevent的相互干擾。

 

int wpa_ctrl_attach(struct wpa_ctrl *ctrl);

/* 注冊 某個 control interface 作為 monitor interface */

 

int wpa_ctrl_detach(struct wpa_ctrl *ctrl);

/* 撤銷某個 monitor interface 為 普通的 control interface  */

 

int wpa_ctrl_pending(struct wpa_ctrl *ctrl);

/* 判斷是否有掛起的event 事件 */

 

int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);

/* 獲取掛起的event 事件 */

 

(2)“ctrl_iface_unix.c”實現wpa_supplicant的Unix domain socket通信機制中server結點,完成對client結點的響應。

       其中最主要的兩個函數為:

static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,

                                         void *sock_ctx)

/* 接收並解析client發送request命令,然后根據不同的命令調用底層不同的處理函數;

 * 然后將獲得response結果回饋到 client 結點。

 */

 

static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,

                                      int level, const char *buf,

                                      size_t len)

/* 向注冊的monitor interfaces 主動發送event事件 */

 

(3)“ctrl_iface.h”和“ctrl_iface.c”主要實現了各種request命令的底層處理函數。

 

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報文。

 

主要涉及到的文件包 括:“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_INET socket接口和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_INET socket接口和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_INET socket 接口 */

 

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

本文譯至:https://wiki.archlinux.org/index.php/WPA_Supplicant_%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29

wpa_supplicant 是跨平台的 WPAsupplicant,支持 WEP, WPA 和 WPA2 (IEEE 802.11i / RSN (Robust Secure Network)). 可以在桌面、筆記本甚至嵌入式系統中使用。

wpa_supplicant 是在客戶端使用的 IEEE 802.1X/WPA 組件, 支持與 WPA Authenticator 的交互,控制漫游和無線驅動的 IEEE 802.11 驗證和關聯。 

安裝

官方軟件倉庫 中安裝軟件包 wpa_supplicant

此外軟件包 wpa_supplicant_gui 提供了圖形界面wpa_gui。 

啟動

本節介紹啟動wpa_supplicant的常用方法,選擇一個最適合你的。

systemd

wpa_supplicant提供多種服務的文件:

  • wpa_supplicant.service - 使用 D-Bus, 推薦 NetworkManager 的用戶.
  • wpa_supplicant@.service - 接受接口名作為參數,並為該接口啟動wpa_supplicant守護進程。它讀取/etc/wpa_supplicant/wpa_supplicant-interface.conf的配置文件
  • wpa_supplicant-nl80211@.service -  也是接口特定的,但明確強制nl80211驅動程序 (見下文). 配置文件路徑是/etc/wpa_supplicant/wpa_supplicant-nl80211-interface.conf
  • wpa_supplicant-wired@.service - 也是接口特定的, 使用 wired 驅動. 配置文件路徑是/etc/wpa_supplicant/wpa_supplicant-wired-interface.conf

dhcpcd

dhcpcd包含了一個鈎子(默認為啟用)來自動啟動對應無線接口的wpa_supplicant。它只在如下情況下啟動:

  • 沒有wpa_supplicant進程在該接口在監聽。
  • 存在一個wpa_supplicant的配置文件。dhcpcd 默認檢查 /etc/wpa_supplicant.conf 和 /etc/wpa_supplicant/wpa_supplicant.conf,但可以通過在/etc/dhcpcd.conf設置env wpa_supplicant_conf=configuration_file_path來添加自定義路徑。

手動

wpa_supplicant接受多個命令行參數,特別是:

  • -B - 在后台執行
  • -c 文件名 -路徑配置文件
  • -i 接口 - 監聽的接口

關於完整的參數列表,參考 man 8 wpa_supplicant。例如,常見的用法是:

# wpa_supplicant -B -i interface -c configuration_file

配置

wpa_supplicant提供了一個參考配置文件/etc/wpa_supplicant/wpa_supplicant.conf,其中包含 了所有可用的選項及其用法和例子的詳細文檔。考慮先把它備份起來,因為下面描述的自動添加網絡配置到wpa_supplicant.conf的方法下刪除 了文件中的所有注釋。

在其最簡單的形式中,一個配置文件,只需要一個網絡配置塊。例如:

/etc/wpa_supplicant/foobar.conf
network={
    ssid="..."
}

一旦你有一個配置文件,如前節所述,就可以啟動wpa_supplicant守護進程,並使用一個靜態IP或DHCP連接到無線網絡。

wpa_passphrase

網絡配置可以使用wpa_passphrase工具自動生成並添加到配置文件中。這在連接到需要密碼的安全網絡時是有用的。例如:

$ wpa_passphrase essid passphrase
network={
    ssid="essid"
    #psk="passphrase"
    psk=f5d1c49e15e679bebe385c37648d4141bc5c9297796a8a185d7bc5ac62f954e3
}

一些異常復雜的口令可能需要從文件輸入:

$ wpa_passphrase essid < passphrase.txt
提示:wpa_supplicant和wpa_passphrase可以結合起來關聯到幾乎所有的WPA2(個人)網絡:
# wpa_supplicant -B -i interface -c <(wpa_passphrase essid passphrase)

指定驅動

您可能需要指定一個驅動來使用。關於支持的驅動程序的列表,請參考wpa_supplicant -h的輸出結果。

  • nl80211 是當前的標准,但不是所有的無線芯片的模塊支持。
  • wext 目前已過時,但仍得到廣泛支持。

使用 -D 開關來指定驅動:

# wpa_supplicant -B -i interface -c configuration_file -D driver

使用 wpa_cli

wpa_supplicant可以通過使用wpa_cli命令,在運行時手動進行控制。要啟用wpa_cli,wpa_supplicant守護進 程必須被配置為通過在wpa_supplicant的配置文件(默認位置:/etc/wpa_supplicant /wpa_supplicant.conf)設置ctrl_interface變量來創建一個“控制接口”(套接字)。

用戶也將需要通過指定可以訪問它的組來獲准訪問該套接字。一個新的組可能為此被創建,並且用戶添加到它,或已存在的組可以使用 - 通常是 wheel。

下面的設置將在/run/wpa_supplicant/中創建套接字並允許wheel組的成員進行訪問:

ctrl_interface=DIR=/run/wpa_supplicant GROUP=wheel

可以通過wpa_cli修改的wpa_supplicant配置文件自身。這在手動添加新的網絡到配置文件,而無需重新啟動wpa_supplicant守護進程時是有用的。為了實現這一目標,在配置文件中設置update_config變量設置為1:

update_config=1

在wpa_cli開始之前,wpa_supplicant守護進程必須處於運行狀態。(見#Starting了解詳情)。然后啟動

$ wpa_cli

它會尋找配置文件中給定位置的控制套接字,位置也可以使用p選項手動設置)。您可以使用-i選項配置的接口,不然的話將使用wpa_supplicant所管理的第一個被找到的無線接口。

當wpa_cli被調用時,將出現交互式提示符(>)。提示包括tab 補全和已完成命令的說明。


使用wpa_cli添加一個新的網絡

掃描可用網絡,在>提示符之后輸入“scan”。在掃描完成后將顯示通知:

> scan
OK
<3>CTRL-EVENT-SCAN-RESULTS
>

然后輸入 "scan_results" 來顯示結果:

> scan_results
bssid / frequency / signal level / flags / ssid
00:00:00:00:00:00 2462 -49 [WPA2-PSK-CCMP][ESS] MYSSID
11:11:11:11:11:11 2437 -64 [WPA2-PSK-CCMP][ESS] ANOTHERSSID
>

為了與MYSSID相關聯,需要告知wpa_supplicant。在配置文件中的各個網絡是以零開始按數值進行索引。如果您添加了一個新的網絡,它會被相應地分配一個新數字。

> add_network
0
>

使用這個數字來指定你的設置應用到哪個網絡。對於一個新的網絡,在引號里設置其SSID:

> set_network 0 ssid "MYSSID"
OK
>

即使你的無線接入點沒有被保護,cli也顯式地需要一個PSK,同樣在引號內。密碼必須是8-63個字符:

> set_network 0 psk "passkey"
OK
>

使能:

> enable_network 0
OK
>

修改寫入配置文件:

> save_config
OK
>

動作腳本

wpa_cli可以在后台模式下運行,並執行基於wpa_supplicant事件的指定腳本。可以支持兩類事件:連接和斷開。一些環境變量可用於腳本,細節請參考man 8wpa_cli。

下面的例子將使用桌面通知,通知有關事件的用戶:

#!/bin/bash

case "$2" in
    CONNECTED)
        notify-send "WPA supplicant: connection established";
        ;;
    DISCONNECTED)
        notify-send "WPA supplicant: connection lost";
        ;;
esac

記住修改腳本為可執行,然后使用-a來傳遞腳本路徑給wpa_cli:

$ wpa_cli -a path_to_script

另請參閱

 

 

 

目前可以使用wireless-tools wpa_supplicant工具來配置無線網絡。請記住重要的一點是,對無線網絡的配置是全局性的,而非針對具體的接口。

wpa_supplicant是一個較好的選擇,但缺點是它不支持所有的驅動。請瀏覽wpa_supplicant網站獲得它所支持的驅動列表。另外,wpa_supplicant目前只能連接到那些你已經配置好ESSID的無線網絡。wireless-tools支持幾乎所有的無線網卡和驅動,但它不能連接到那些只支持WPAAP

經過編譯后的wpa_supplicant源程序可以看到兩個主要的可執行工具:wpa_supplicantwpa_cliwpa_supplicant是核心程序,它和wpa_cli的關系就是服務和客戶端的關系:后台運行wpa_supplicant,使用wpa_cli來搜索、設置、和連接網絡。

如何用wpa_supplicant使能一個wifi連接?

Step by step

1、運行wpa_supplicant程序;

執行:/system/bin/wpa_supplicant -d -Dwext -iwlan0 -c/data/misc/wifi/wpa_supplicant.conf

其中:

-d :增加調試信息

-Dwext wext,驅動名稱

-iwlan0 wlan0,網絡接口名稱

/system/bin/wpa_supplicant wpa_supplicant可執行程序path

/data/misc/wifi/wpa_supplicant.conf wpa_supplicant的配置文件path

2、運行命令行工具wpa_cli

執行wpa_cli -iwlan0 -p/data/system/wpa_supplicant

注,-p/data/system/wpa_supplicant中的wpa_supplicant並不是可執行程序,而是個控制套接字。

此時會進入交互模式。其中交互模式的命令如下表:

Full command

Short command

Description

status

stat

displays the current connection status

disconnect

disc

prevents wpa_supplicant from connecting to any access point

quit

q

exits wpa_cli

terminate

term

kills wpa_supplicant

reconfigure

recon

reloads wpa_supplicant with the configuration file supplied (-c parameter)

scan

scan

scans for available access points (only scans it, doesn't display anything)

scan_result

scan_r

displays the results of the last scan

list_networks

list_n

displays a list of configured networks and their status (active or not, enabled or disabled)

select_network

select_n

select a network among those defined to initiate a connection (ie select_network 0)

enable_network

enable_n

makes a configured network available for selection (ie enable_network 0)

disable_network

disable_n

makes a configured network unavailable for selection (ie disable_network 0)

remove_network

remove_n

removes a network and its configuration from the list (ie remove_network 0)

add_network

add_n

adds a new network to the list. Its id will be created automatically

set_network

set_n

shows a very short list of available options to configure a network when supplied with no parameters.

See next section for a list of extremely useful parameters to be used with set_network and get_network.

get_network

get_n

displays the required parameter for the specified network. See next section for a list of parameters

save_config

save_c

saves the configuration

 

設置網絡的基本格式:set_network <network id> <key> <parameter> [<parameter>]

顯示網絡信息的基本格式:get_network <network id> <key>

相應的參數如下表:

Key

Description

Parameters

ssid

Access point name

string

id_str

String identifying the network

string

priority

Connection priority over other APs

number (0 being the default low priority)

bssid

Mac address of the access point

mac address

scan_ssid

Enable/disbale ssid scan

0, 1, 2

key_mgmt

Type of key management

WPA-PSK, WPA_EAP, None

pairwise

Pairwise ciphers for WPA

CCMP, TKIP

group=TKIP

Group ciphers for WPA

CCMP, TKIP, WEP104, WEP40

psk

Pre-Shared Key (clear or encrypted)

string

wep_key0

WEP key (up to 4: wep_key[0123])

string

eap

Extensible Authentication Protocol

MD5, MSCHAPV2, OTP, GTC, TLS, PEAP, TTLS

identity

EAP identity string

string

password

EAP password

string

ca_cert

Pathname to CA certificate file

/full/path/to/certificate

client_cert

Pathname to client certificate

/full/path/to/certificate (PEM/DER)

private_key

Pathname to a client private key file

/full/path/to/private_key (PEM/DER/PFX)

eg.1、連接無加密的AP

>add_network (It will display a network id for you, assume it returns 0)

>set_network 0 ssid "666"

>set_network 0 key_mgmt NONE

>enable_network 0

>quit

eg.2、連接WEP加密AP

>add_network (assume return 1)

>set_network 1 ssid "666"

>set_network 1 key_mgmt NONE

>set_network 1 wep_key0 "your ap password"

>enable_network 1

eg.3、連接WPA-PSK/WPA2-PSK加密的AP

>add_network (assume return 2)

>set_network 2 ssid "666"

>set_network 2 psk "your pre-shared key"

>enable_network 2

到此,wifi模塊就能連接上AP了。

3、以上是通過命令行工具wpa_cli來實現wifi網絡的連接。當然,也可以通過wpa_supplicant的配置文件來實現連接。

再回顧下運行wpa_supplicant時執行的命令:

/system/bin/wpa_supplicant -d -Dwext -iwlan0 -c/data/misc/wifi/wpa_supplicant.conf

我們在執行時加上了-c/data/misc/wifi/wpa_supplicant.conf,我們可以將我們要連接的AP的設置以一定的格式寫入wpa_supplicant.conf配置文件中即可。

eg.

ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=system update_config=1

network={

ssid="my access point"

proto=WPA

key_mgmt=WPA-PSK

psk="you pass words"

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM