(八十四)學習wpa_supplicant-devel——chapter3

前言:對應wpa_supplicant-devel 中Chapter3 wpa_supplicant control interface,主要內容是wpa_supplicant 控制接口的介紹。

 

1. 控制接口簡介

wpa_supplicant implements a control interface that can be used by external programs to control the opera-
tions of the wpa_supplicant daemon and to get status information and event notifications. There is a small
C library, in a form of a single C file, wpa_ctrl.c, that provides helper functions to facilitate the use of the
control interface. External programs can link this file into them and then use the library functions docu-
mented in wpa_ctrl.h to interact with wpa_supplicant. This library can also be used with C++. wpa_cli.c
and wpa_gui are example programs using this library.
There are multiple mechanisms for inter-process communication. For example, Linux version of wpa_-
supplicant is using UNIX domain sockets for the control interface and Windows version UDP sockets. The
use of the functions defined in wpa_ctrl.h can be used to hide the details of the used IPC from external
programs.

簡單來說wpa_supplicant實現了一個控制接口,能被外部程序用來控制wpa_supplicant以及獲取一些狀態信息和時間通知。

其中有個小的C語音庫,就一個C文件,wpa_ctrl.c,提供了對應的實現。外部程序可以包含這個文件繼而使用在wpa_ctrl.h中提及的功能來與wpa_supplicant進行交互。這個庫也可以通過C++進行調用。wpa_cli.c和wpa_gui是使用該庫的例子供參考。

在IPC中有很多機制,比如,linux版本的wpa_supplicant是使用的UNIX式的socket,而Windows用的是UDP socket.在wpa_ctrl.h中定義的功能可以在掩蓋IPC實現細節的基礎上被外部程序所調用。

簡單看下wpa_ctrl.h的開頭

/*
 * wpa_supplicant/hostapd control interface library
 * Copyright (c) 2004-2017, Jouni Malinen <[email protected]>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#ifndef WPA_CTRL_H
#define WPA_CTRL_H

#ifdef  __cplusplus
extern "C" {
#endif

/* wpa_supplicant control interface - fixed message prefixes */

/** Interactive request for identity/password/pin */
#define WPA_CTRL_REQ "CTRL-REQ-"

/** Response to identity/password/pin request */
#define WPA_CTRL_RSP "CTRL-RSP-"

/* Event messages with fixed prefix */
/** Authentication completed successfully and data connection enabled */
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "

 

2.控制接口的使用

External programs, e.g., a GUI or a configuration utility, that need to communicate with wpa_supplicant
should link in wpa_ctrl.c. This allows them to use helper functions to open connection to the control
interface with wpa_ctrl_open() and to send commands with wpa_ctrl_request().
wpa_supplicant uses the control interface for two types of communication: commands and unsolicited
event messages. Commands are a pair of messages, a request from the external program and a response
from wpa_supplicant. These can be executed using wpa_ctrl_request(). Unsolicited event messages are
sent by wpa_supplicant to the control interface connection without specific request from the external pro-
gram for receiving each message. However, the external program needs to attach to the control interface
with wpa_ctrl_attach() to receive these unsolicited messages.
If the control interface connection is used both for commands and unsolicited event messages, there is
potential for receiving an unsolicited message between the command request and response. wpa_ctrl_-
request() caller will need to supply a callback, msg_cb, for processing these messages. Often it is easier to
open two control interface connections by calling wpa_ctrl_open() twice and then use one of the connec-
tions for commands and the other one for unsolicited messages. This way command request/response pairs
will not be broken by unsolicited messages. wpa_cli is an example of how to use only one connection for
both purposes and wpa_gui demonstrates how to use two separate connections.
Once the control interface connection is not needed anymore, it should be closed by calling wpa_ctrl_-
close(). If the connection was used for unsolicited event messages, it should be first detached by calling
wpa_ctrl_detach().

需要與wpa_supplicant交互的外部程序應該鏈接到wpa_ctrl.c。這個允許它們通過wpa_ctrl_open()使用輔助功能來打開與控制接口的連接,並通過wpa_ctrl_request()發送命令。

wpa_supplicant爲兩種類型的通信使用控制接口:命令和未被要求的事件信息(commands and unsolicited
event messages)。命令是一對消息,一個來自外部程序的請求和一個來自wpa_supplicant的響應。這個可以通過wpa_ctrl_request來執行。未被要求的事件信息是由wpa_supplicant來發送給控制接口鏈接,但不需要來自外部程序的特殊請求來獲取消息。但是,外部程序需要使用wpa_ctrl_attach()附着在控制接口上來接收這個未被要求的消息。

如果控制接口連接既通過commands又通過unsolicited event messages,那麼在請求和相應命令接收間接收到unsolicited event messages是有可能的。wpa_ctrl_request調用這需要提供一個回調,msg_cb來處理這些消息。當然通過調用wpa_ctrl_open兩次打開兩個控制接口連接會方便的多,然後使用其中之一作爲commands,另外一個作爲unsolicited event messages。這樣的請求/相應命令不會被unsolicited event messages所幹擾,大家各司其職。wpa_cli是使用一個連接達到兩種母的的例子,wpa_gui是單獨使用兩個連接的例子。

一個控制接口連接不再需要,它應該通過調用wpa_ctrl_close()及時關閉。如果連接被用來傳遞unsolicited event messages,它應該先調用wpa_ctrl_detach()進行解綁。

總結下接口使用:

  • wpa_ctrl_open():使用輔助功能來打開與控制接口的連接
  • wpa_ctrl_request():發送命令
  • wpa_ctrl_attach():綁定在控制接口上
  • wpa_ctrl_close():關閉
  • wpa_ctrl_detach():解綁
/* wpa_supplicant/hostapd control interface access */

/**
 * wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd
 * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
 * Returns: Pointer to abstract control interface data or %NULL on failure
 *
 * This function is used to open a control interface to wpa_supplicant/hostapd.
 * ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd. This path
 * is configured in wpa_supplicant/hostapd and other programs using the control
 * interface need to use matching path configuration.
 */
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);

/**
 * wpa_ctrl_open2 - Open a control interface to wpa_supplicant/hostapd
 * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
 * @cli_path: Path for client UNIX domain sockets; ignored if UDP socket
 *            is used.
 * Returns: Pointer to abstract control interface data or %NULL on failure
 *
 * This function is used to open a control interface to wpa_supplicant/hostapd
 * when the socket path for client need to be specified explicitly. Default
 * ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd and client
 * socket path is /tmp.
 */
struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path, const char *cli_path);


/**
 * wpa_ctrl_close - Close a control interface to wpa_supplicant/hostapd
 * @ctrl: Control interface data from wpa_ctrl_open()
 *
 * This function is used to close a control interface.
 */
void wpa_ctrl_close(struct wpa_ctrl *ctrl);

/**
 * wpa_ctrl_request - Send a command to wpa_supplicant/hostapd
 * @ctrl: Control interface data from wpa_ctrl_open()
 * @cmd: Command; usually, ASCII text, e.g., "PING"
 * @cmd_len: Length of the cmd in bytes
 * @reply: Buffer for the response
 * @reply_len: Reply buffer length
 * @msg_cb: Callback function for unsolicited messages or %NULL if not used
 * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
 *
 * This function is used to send commands to wpa_supplicant/hostapd. Received
 * response will be written to reply and reply_len is set to the actual length
 * of the reply. This function will block for up to two seconds while waiting
 * for the reply. If unsolicited messages are received, the blocking time may
 * be longer.
 *
 * msg_cb can be used to register a callback function that will be called for
 * unsolicited messages received while waiting for the command response. These
 * messages may be received if wpa_ctrl_request() is called at the same time as
 * wpa_supplicant/hostapd is sending such a message. This can happen only if
 * the program has used wpa_ctrl_attach() to register itself as a monitor for
 * event messages. Alternatively to msg_cb, programs can register two control
 * interface connections and use one of them for commands and the other one for
 * receiving event messages, in other words, call wpa_ctrl_attach() only for
 * the control interface connection that will be used for event messages.
 */
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_ctrl_attach - Register as an event monitor for the control interface
 * @ctrl: Control interface data from wpa_ctrl_open()
 * Returns: 0 on success, -1 on failure, -2 on timeout
 *
 * This function registers the control interface connection as a monitor for
 * wpa_supplicant/hostapd events. After a success wpa_ctrl_attach() call, the
 * control interface connection starts receiving event messages that can be
 * read with wpa_ctrl_recv().
 */
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);


/**
 * wpa_ctrl_detach - Unregister event monitor from the control interface
 * @ctrl: Control interface data from wpa_ctrl_open()
 * Returns: 0 on success, -1 on failure, -2 on timeout
 *
 * This function unregisters the control interface connection as a monitor for
 * wpa_supplicant/hostapd events, i.e., cancels the registration done with
 * wpa_ctrl_attach().
 */
int wpa_ctrl_detach(struct wpa_ctrl *ctrl);

 

繼續看下之前說的兩個demo:wpa_cli是使用一個連接達到兩種目的的例子,wpa_gui是單獨使用兩個連接的例子。

wpa_cli使用可以參考

https://segmentfault.com/a/1190000011579147

https://blog.csdn.net/z2066411585/article/details/78761753

static void usage(void)
{
    printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
           "[-a<action file>] \\\n"
           "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
           "\\\n"
           "        [-s<wpa_client_socket_file_path>] "
           "[command..]\n"
           "  -h = help (show this usage text)\n"
           "  -v = shown version information\n"
           "  -a = run in daemon mode executing the action file based on "
           "events from\n"
           "       wpa_supplicant\n"
           "  -B = run a daemon in the background\n"
           "  default path: " CONFIG_CTRL_IFACE_DIR "\n"
           "  default interface: first interface found in socket path\n");
    print_help(NULL);
}

wpa_gui

相關內容參考

http://blog.163.com/modingfa_002/blog/static/11092546620105841255688/

http://bezstellar.blog.163.com/blog/static/174868780201010184215271/

 

3. 控制接口命令

Following commands can be used with wpa_ctrl_request():

可以隨wpa_ctrl_request使用的命令如下圖所示,對應可以查看pdf,就不復制粘貼了。

 

4.Interactive requests

If wpa_supplicant needs additional information during authentication (e.g., password), it will use a specific
prefix, CTRL-REQ- (WPA_CTRL_REQ macro) in an unsolicited event message. An external program,
e.g., a GUI, can provide such information by using CTRL-RSP- (WPA_CTRL_RSP macro) prefix in a
command with matching field name.
The following fields can be requested in this way from the user:

• IDENTITY (EAP identity/user name)
• PASSWORD (EAP password)
• NEW_PASSWORD (New password if the server is requesting password change)
• PIN (PIN code for accessing a SIM or smartcard)
• OTP (one-time password; like password, but the value is used only once)
• PASSPHRASE (passphrase for a private key file)
CTRL-REQ-<field name>-<network id>-<human readable text>
CTRL-RSP-<field name>-<network id>-<value>
For example, request from wpa_supplicant:
CTRL-REQ-PASSWORD-1-Password needed for SSID test-network
And a matching reply from the GUI:
CTRL-RSP-PASSWORD-1-secret

如果wpa_supplicant在鑑權前需要額外的信息,它可以在unsolicited event message使用使用特別的前綴 CTRL-REQ- (WPA_CTRL_REQ macro)。一個外部程序,比如GUI,能通過在一個命令中使用CTRL-RSP- (WPA_CTRL_RSP macro)前綴+對應的成員名稱提供對應的信息。

下面是可以通過該方法從用戶獲取的成員:

• IDENTITY (EAP identity/user name)
• PASSWORD (EAP password)
• NEW_PASSWORD (New password if the server is requesting password change)
• PIN (PIN code for accessing a SIM or smartcard)
• OTP (one-time password; like password, but the value is used only once)
• PASSPHRASE (passphrase for a private key file)
CTRL-REQ-<field name>-<network id>-<human readable text>
CTRL-RSP-<field name>-<network id>-<value>

比如,一個來自wpa_supplicant的請求:

CTRL-REQ-PASSWORD-1-Password needed for SSID test-network

一個來自GUI的迴應:

CTRL-RSP-PASSWORD-1-secret


4.1 GET_CAPABILITY <option> [strict]


Get list of supported functionality (eap, pairwise, group, proto). Supported functionality is shown as space
separate lists of values used in the same format as in wpa_supplicant configuration. If optional argument,
’strict’, is added, only the values that the driver claims to explicitly support are included. Without this, all
available capabilities are included if the driver does not provide a mechanism for querying capabilities.

得到支持功能的列表。支持的功能會以像wpa_supplicant配置一樣以空格間隔開的列表展現出來。如果可選參數,‘strict’被添加,那麼只有驅動顯式聲明支持的值會被包含。如果驅動不提供一種查詢機制,那麼所有的屬性都會列出來。


Example request/reply pairs:
GET_CAPABILITY eap
AKA FAST GTC LEAP MD5 MSCHAPV2 OTP PAX PEAP PSK SIM TLS TTLS
GET_CAPABILITY pairwise
CCMP TKIP NONE
GET_CAPABILITY pairwise strict
GET_CAPABILITY group
CCMP TKIP WEP104 WEP40
GET_CAPABILITY key_mgmt
WPA-PSK WPA-EAP IEEE8021X NONE
GET_CAPABILITY proto
RSN WPA
GET_CAPABILITY auth_alg
OPEN SHARED LEAP


4.2 AP_SCAN <ap_scan value>


Change ap_scan value: 0 = no scanning, 1 = wpa_supplicant requests scans and uses scan results to select
the AP, 2 = wpa_supplicant does not use scanning and just requests driver to associate and take care of AP
selection

 

4.3 INTERFACES


List configured interfaces.
wlan0
eth0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章