Wpa_supplicant Software Architecture Analysis

Source: Internet
Author: User
Tags unix domain socket wpa supplicant bssid

 

From: http://blog.csdn.net/fxfzz/archive/2011/02/10/6176414.aspx

Author: fxfzz

When WPA Supplicant is started, the startup command can contain many parameters. Currently, our startup command is as follows:

Wpa_supplicant/system/bin/wpa_supplicant-dwext-ieth0-C/data/WiFi/wpa_supplicant.conf-F/data/WiFi/wpa_log.txt

 

Wpa_supplicant uses two data structures to store the parameters in the startup command,

One is wpa_params and the other is wpa_interface.

This is mainly because wpa_supplicant supports multiple network interfaces at the same time.

The wpa_params data structure records parameter settings unrelated to network interfaces.

Each network interface is recorded using a wpa_interface data structure.

You can use-N to specify a new network interface in the startup command line. For a new network interface, you can use the following six parameters:

-I <ifname>: Network Interface Name

-C <conf>: configuration file name

-C <ctrl_intf>: Control Interface Name

-D <driver>: Driver type

-P <driver_param>: Driver Parameter

-B <br_ifname>: bridge Interface Name

 

2. wpa_supplicant initialization process
2.1. Main () function:
In this function, we mainly do four things.

A. parse the parameters passed by the command line.

B. Call the wpa_supplicant_init () function to initialize wpa_supplicant.

C. Call the wpa_supplicant_add_iface () function to add a network interface.

D. Call the wpa_supplicant_run () function to run wpa_supplicant.

 

2.2. wpa_supplicant_init () function:
A. Open the debug file.

B. register the EAP peer method.

C. Apply for the wpa_global memory. The data structure serves as a core to guide other data structures. It consists of four parts:

Wpa_supplicant * ifaces/* each network interface has a corresponding wpa_supplicant data structure. The Pointer Points to the recently added one. In the wpa_supplicant data structure, a pointer points to next */

Wpa_params Params/* common parameters contained in the startup command line */

Ctrl_iface_global_priv * ctrl_iface/* Global Control Interface */

Ctrl_iface_dbus_priv * dbus_ctrl_iface/* scheduler control interface */

D. Set the parameters in wpa_params in wpa_global.

E. Call the eloop_init function to direct the user_data pointer in the global variable eloop to wpa_global.

F. Call the wpa_supplicant_global_ctrl_iface_init function to initialize the global control interface.

G. Call the wpa_supplicant_dbus_ctrl_iface_init function to initialize the ingress control interface.

H. Write the daemon PID to pid_file.

 

2.3. wpa_supplicant_add_iface () function:
This function adds a network interface based on the parameters contained in the startup command line. You can add a few network interfaces.

A. Because wpa_supplicant is an important data structure corresponding to the network interface, first allocate a memory of the wpa_supplicant data structure.

B. Call the wpa_supplicant_init_iface () function to perform the initial work of the network interface, including:

Set the driver type. The default value is wext;

Read the configuration file and set the information to the data structure pointed to by the conf pointer in the wpa_supplicant data structure. It is of the wpa_config type;

The Command Line Control Interface ctrl_interface and the driver parameter driver_param overwrite the settings in the configuration file;

Copy the network interface name and bridge interface name to the wpa_config data structure;

The network configuration block has two linked lists to describe it. One is config-> SSID, Which is mounted to the linked list in sequence in the configuration file, and the other is pssid, it is a second-level pointer pointing to an array of pointers. the pointer array stores the wpa_ssid pointer in order of priority from the top to the bottom, and mounts the pointer with the same priority in the same linked list.

C. Call the wpa_supplicant_init_iface2 () function, mainly including:

Call the wpa_supplicant_init_eapol () function to initialize eapol;

Call the init () function of the corresponding driver type;

Set the param parameter of the driver;

Call the wpa_drv_get_ifname () function to obtain the name of the network interface. This function is not available for wext drivers;

Call the wpa_supplicant_init_wpa () function to initialize WPA and perform corresponding initialization;

Call the wpa_supplicant_driver_init () function to initialize the driver interface parameters.

Wpa_s-> prev_scan_ssid = broadcast_ssid_scan;

Wpa_supplicant_req_scan (maid, interface_count, 100000 );

To actively initiate scan,

Call the wpa_supplicant_ctrl_iface_init () function to initialize the control interface. For a UNIX socket, the local socket file is added by the path specified by the ctrl_interface parameter in the configuration file;

 

2.4. wpa_supplicant_run () function:
After initialization, run the main event loop of wpa_supplicant.

In wpa_supplicant, many sockets that communicate with the outside world need to be registered in the eloop event module. Specifically, a record is added to eloop_sock_table, including sock_fd, handle, eloop_data, user_data.

The eloop event module organizes these sockets for unified management, and uses the select mechanism in eloop_run to manage socket communication.

 

3. interfaces provided by wpa_supplicant
Wpa_supplicant provides an upstream control interface for communication with other modules (such as the UI). Other modules can use the control interface to obtain information or issue commands. Wpa_supplicant implements a downstream interface through the socket communication mechanism to communicate with the kernel to obtain information or issue commands.

 

3.1 upstream Interface
Wpa_supplicant provides two upstream interfaces. One is to implement IPC communication with other processes based on the traditional scheme mechanism, and the other is to implement IPC communication between processes through the Unix domain socket mechanism.

3.1.1 renewal Interface
This interface is mainly implemented in the files "ctrl_iface_dbus.h", "ctrl_iface_dbus.c", "ctrl_iface_dbus_handler.h", and "ctrl_iface_dbus_handler.c", providing some basic control methods.

 

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 interface
This interface is mainly implemented in the files "wpa_ctrl.h", "wpa_ctrl.c", "ctrl_iface_unix.c", "ctrl_iface.h", and "ctrl_iface.c.

 

(1) "wpa_ctrl.h" and "wpa_ctrl.c" encapsulate the control interface and provide a unified interface. The main task is to establish a control interface client node through Unix domain socket and communicate with the wpa_supplicant node as the server.

 

Main functions:

Struct wpa_ctrl * wpa_ctrl_open (const char * ctrl_path );

/* Create and initialize the client node of a Unix domain socket and bind it with the wpa_supplicant node as the server */

Void wpa_ctrl_close (struct wpa_ctrl * CTRL );

/* Undo and destroy the client node of the established Unix domain socket */

 

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 ));

 

/* The user module directly calls this function to send commands to wpa_supplicant and obtain the required information.

* Commands that can be sent are shown in Attachment 1 */

Note:

Wpa_supplicant provides two ways to obtain information from the external module: one is that the external module sends the Request command and obtains the response Q & A mode, and the other is that wpa_supplicant actively sends event events to the outside, received by an external module listener.

 

The common practice is that the external module creates two control interfaces by calling wpa_ctrl_open () twice. One is CTRL interface, which is used to send commands and obtain information, and the other is Monitor interface, it is used to listen for the event time received from wpa_supplicant. This can reduce the coupling of communication and avoid mutual interference between response and event.

 

Int wpa_ctrl_attach (struct wpa_ctrl * CTRL );

/* Register a control interface as the Monitor Interface */

 

Int wpa_ctrl_detach (struct wpa_ctrl * CTRL );

/* Cancel a Monitor interface as a normal control interface */

 

Int wpa_ctrl_pending (struct wpa_ctrl * CTRL );

/* Determine whether a suspended event exists */

 

Int wpa_ctrl_recv (struct wpa_ctrl * Ctrl, char * reply, size_t * reply_len );

/* Get the suspended event */

 

(2) "ctrl_iface_unix.c" implements the server node in the Unix domain socket communication mechanism of wpa_supplicant to respond to the client node.

The two most important functions are:

Static void wpa_supplicant_ctrl_iface_receive (INT sock, void * eloop_ctx,

Void * sock_ctx)

/* Receive and parse the Request command sent by the client, and then call different underlying processing functions according to different commands;

* Return the response result to the client node.

*/

 

Static void wpa_supplicant_ctrl_iface_send (struct ctrl_iface_priv * priv,

Int level, const char * Buf,

Size_t Len)

/* Actively send event events to the registered monitor interfaces */

 

(3) "ctrl_iface.h" and "ctrl_iface.c" mainly implement the underlying processing functions of various request commands.

 

3.2 downstream interface
The downlink interface provided by wpa_supplicant is mainly used to communicate with the kernel (driver), issue commands and obtain information.

The wpa_supplicant downstream interface mainly includes three important interfaces:

1. The pf_inet socket interface is mainly used to send the ioctl command to the kernel to control and obtain the relevant information.

2. The pf_netlink socket interface is mainly used to receive Event Events sent by the kernel.

3. The pf_packet socket interface is used to transmit 802.1x packets to the driver.

 

The main files involved include: "driver. H", "drivers. c", "driver_wext.h", "driver_wext.c", "l2_packet.h", and "l2_packet_linux.c ". "Driver. h "," drivers. c "," driver_wext.h "and" driver_wext.c "implement the pf_inet socket interface and the pf_netlink socket interface;" l2_packet.h "and" l2_packet_linux.c "implement the pf_packet socket interface.

 

(1) "driver. H" and "drivers. c" are mainly used to encapsulate the same wpa_driver_ops interface for external display of underlying differences. Wpa_supplicant supports Atmel, Broadcom, IPW, madwifi, NDIS, nl80211, wext, and other drivers.

One of the most important data structures is wpa_driver_ops, which defines various Driver-related operation interfaces.

 

(2) "driver_wext.h" and "driver_wext.c" implement wpa_driver_ops in wext form, create the pf_inet socket interface and pf_netlink socket interface, and then use these two interfaces to complete information interaction with kernel.

 

Wext provides the following data structures:

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 is the pf_netlink socket interface, and ioctl_sock is an excuse for pf_inet socket.

 

Driver_wext.c implements a large number of underlying processing functions to implement the wpa_driver_ops operation parameters. The following are important:

Void * wpa_driver_wext_init (void * CTX, const char * ifname );

/* Initialize the wpa_driver_wext_data data structure and create the pf_netlink socket and pf_inet socket interfaces */

 

Void wpa_driver_wext_deinit (void * priv );

/* Destroy the wpa_driver_wext_data data structure, and the pf_netlink socket and pf_inet socket interfaces */

 

Static void wpa_driver_wext_event_receive (INT sock, void * eloop_ctx,

Void * sock_ctx );

/* Callback function for Processing Event Events actively sent by kernel */

 

Finally, map the implemented operation function to a global wpa_driver_ops Data Structure 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" and "l2_packet_linux.c" are mainly used to implement the pf_packet socket interface. Through this interface, wpa_supplicant can directly send 802.1x packet to the L2 layer without passing through the TCP/IP protocol stack.

 

The main functions are:

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 );

/* Create and initialize the pf_packet socket interface, in which rx_callback is the callback function processed by packet received from L2 */

 

Void l2_packet_deinit (struct l2_packet_data * l2 );

/* Destroy the pf_packet socket interface */

 

Int l2_packet_send (struct l2_packet_data * L2, const u8 * dst_addr, 2010proto,

Const u8 * Buf, size_t Len );

/* L2 packet sending function. wpa_supplicant uses this function to send L2 802.1x packet */

 

Static void l2_packet_receive (INT sock, void * eloop_ctx, void * sock_ctx );

/* The L2 packet receiving function sends data from the L2 layer to the upper layer */

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

 

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/fxfzz/archive/2011/02/10/6176414.aspx

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.