b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | /** |
| 2 | \page driver_wrapper Driver wrapper implementation (driver.h, drivers.c) |
| 3 | |
| 4 | All hardware and driver dependent functionality is in separate C files |
| 5 | that implement defined wrapper functions. Other parts |
| 6 | of the wpa_supplicant are designed to be hardware, driver, and operating |
| 7 | system independent. |
| 8 | |
| 9 | Driver wrappers need to implement whatever calls are used in the |
| 10 | target operating system/driver for controlling wireless LAN |
| 11 | devices. As an example, in case of Linux, these are mostly some glue |
| 12 | code and ioctl() calls and netlink message parsing for Linux Wireless |
| 13 | Extensions (WE). Since features required for WPA were added only recently to |
| 14 | Linux Wireless Extensions (in version 18), some driver specific code is used |
| 15 | in number of driver interface implementations. These driver dependent parts |
| 16 | can be replaced with generic code in \ref driver_wext.c once the target driver |
| 17 | includes full support for WE-18. After that, all Linux drivers, at |
| 18 | least in theory, could use the same driver wrapper code. |
| 19 | |
| 20 | A driver wrapper needs to implement some or all of the functions |
| 21 | defined in \ref driver.h. These functions are registered by filling struct |
| 22 | \ref wpa_driver_ops with function pointers. Hardware independent parts of |
| 23 | wpa_supplicant will call these functions to control the driver/wlan |
| 24 | card. In addition, support for driver events is required. The event |
| 25 | callback function, \ref wpa_supplicant_event(), and its parameters are |
| 26 | documented in \ref driver.h. In addition, a pointer to the 'struct |
| 27 | \ref wpa_driver_ops' needs to be registered in \ref drivers.c file. |
| 28 | |
| 29 | When porting to other operating systems, the driver wrapper should be |
| 30 | modified to use the native interface of the target OS. It is possible |
| 31 | that some extra requirements for the interface between the driver |
| 32 | wrapper and generic wpa_supplicant code are discovered during porting |
| 33 | to a new operating system. These will be addressed on case by case |
| 34 | basis by modifying the interface and updating the other driver |
| 35 | wrappers for this. The goal is to avoid changing this interface |
| 36 | without very good reasons in order to limit the number of changes |
| 37 | needed to other wrappers and hardware independent parts of |
| 38 | wpa_supplicant. When changes are required, recommended way is to |
| 39 | make them in backwards compatible way that allows existing driver |
| 40 | interface implementations to be compiled without any modification. |
| 41 | |
| 42 | Generic Linux Wireless Extensions functions are implemented in |
| 43 | \ref driver_wext.c. All Linux driver wrappers can use these when the kernel |
| 44 | driver supports the generic ioctl()s and wireless events. Driver |
| 45 | specific functions are implemented in separate C files, e.g., |
| 46 | \ref driver_hostap.c. These files need to define struct \ref wpa_driver_ops |
| 47 | entry that will be used in \ref wpa_supplicant.c when calling driver |
| 48 | functions. struct \ref wpa_driver_ops entries are registered in \ref drivers.c. |
| 49 | |
| 50 | In general, it is likely to be useful to first take a look at couple |
| 51 | of driver interface examples before starting on implementing a new |
| 52 | one. \ref driver_hostap.c and \ref driver_wext.c include a complete |
| 53 | implementation for Linux drivers that use wpa_supplicant-based control |
| 54 | of WPA IE and roaming. \ref driver_ndis.c (with help from \ref driver_ndis_.c) |
| 55 | is an example of a complete interface for Windows NDIS interface for |
| 56 | drivers that generate WPA IE themselves and decide when to roam. These |
| 57 | example implementations include full support for all security modes. |
| 58 | |
| 59 | |
| 60 | \section driver_req Driver requirements for WPA |
| 61 | |
| 62 | WPA introduces new requirements for the device driver. At least some |
| 63 | of these need to be implemented in order to provide enough support for |
| 64 | wpa_supplicant. |
| 65 | |
| 66 | \subsection driver_tkip_ccmp TKIP/CCMP |
| 67 | |
| 68 | WPA requires that the pairwise cipher suite (encryption algorithm for |
| 69 | unicast data packets) is TKIP or CCMP. These are new encryption |
| 70 | protocols and thus, the driver will need to be modified to support |
| 71 | them. Depending on the used wlan hardware, some parts of these may be |
| 72 | implemented by the hardware/firmware. |
| 73 | |
| 74 | Specification for both TKIP and CCMP is available from IEEE (IEEE |
| 75 | 802.11i amendment). Fully functional, hardware independent |
| 76 | implementation of both encryption protocols is also available in Host |
| 77 | AP driver (driver/modules/hostap_{tkip,ccmp}.c). In addition, Linux 2.6 |
| 78 | kernel tree has generic implementations for WEP, TKIP, and CCMP that can |
| 79 | be used in Linux drivers. |
| 80 | |
| 81 | The driver will also need to provide configuration mechanism to allow |
| 82 | user space programs to configure TKIP and CCMP. Linux Wireless Extensions |
| 83 | v18 added support for configuring these algorithms and |
| 84 | individual/non-default keys. If the target kernel does not include WE-18, |
| 85 | private ioctls can be used to provide similar functionality. |
| 86 | |
| 87 | \subsection driver_roaming Roaming control and scanning support |
| 88 | |
| 89 | wpa_supplicant can optionally control AP selection based on the |
| 90 | information received from Beacon and/or Probe Response frames |
| 91 | (ap_scan=1 mode in configuration). This means that the driver should |
| 92 | support external control for scan process. In case of Linux, use of |
| 93 | new Wireless Extensions scan support (i.e., 'iwlist wlan0 scan') is |
| 94 | recommended. The current driver wrapper (\ref driver_wext.c) uses this for |
| 95 | scan results. |
| 96 | |
| 97 | Scan results must also include the WPA information element. Support for |
| 98 | this was added in WE-18. With older versions, a custom event can be used |
| 99 | to provide the full WPA IE (including element id and length) as a hex |
| 100 | string that is included in the scan results. |
| 101 | |
| 102 | wpa_supplicant needs to also be able to request the driver to |
| 103 | associate with a specific BSS. Current Host AP driver and matching |
| 104 | \ref driver_hostap.c wrapper uses following sequence for this |
| 105 | request. Similar/identical mechanism should be usable also with other |
| 106 | drivers. |
| 107 | |
| 108 | - set WPA IE for AssocReq with private ioctl |
| 109 | - set SSID with SIOCSIWESSID |
| 110 | - set channel/frequency with SIOCSIWFREQ |
| 111 | - set BSSID with SIOCSIWAP |
| 112 | (this last ioctl will trigger the driver to request association) |
| 113 | |
| 114 | \subsection driver_wpa_ie WPA IE generation |
| 115 | |
| 116 | wpa_supplicant selects which cipher suites and key management suites |
| 117 | are used. Based on this information, it generates a WPA IE. This is |
| 118 | provided to the driver interface in the associate call. This does not |
| 119 | match with Windows NDIS drivers which generate the WPA IE |
| 120 | themselves. |
| 121 | |
| 122 | wpa_supplicant allows Windows NDIS-like behavior by providing the |
| 123 | selected cipher and key management suites in the associate call. If |
| 124 | the driver generates its own WPA IE and that differs from the one |
| 125 | generated by wpa_supplicant, the driver has to inform wpa_supplicant |
| 126 | about the used WPA IE (i.e., the one it used in (Re)Associate |
| 127 | Request). This notification is done using EVENT_ASSOCINFO event (see |
| 128 | \ref driver.h). wpa_supplicant is normally configured to use |
| 129 | ap_scan=2 mode with drivers that control WPA IE generation and roaming. |
| 130 | |
| 131 | \subsection driver_events Driver events |
| 132 | |
| 133 | wpa_supplicant needs to receive event callbacks when certain events |
| 134 | occur (association, disassociation, Michael MIC failure, scan results |
| 135 | available, PMKSA caching candidate). These events and the callback |
| 136 | details are defined in \ref driver.h (\ref wpa_supplicant_event() function |
| 137 | and enum \ref wpa_event_type). |
| 138 | |
| 139 | On Linux, association and disassociation can use existing Wireless |
| 140 | Extensions event that is reporting new AP with SIOCGIWAP |
| 141 | event. Similarly, completion of a scan can be reported with SIOCGIWSCAN |
| 142 | event. |
| 143 | |
| 144 | Michael MIC failure event was added in WE-18. Older versions of Wireless |
| 145 | Extensions will need to use a custom event. Host AP driver used a custom |
| 146 | event with following contents: MLME-MICHAELMICFAILURE.indication(keyid=# |
| 147 | broadcast/unicast addr=addr2). This is the recommended format until |
| 148 | the driver can be moved to use WE-18 mechanism. |
| 149 | |
| 150 | \subsection driver_wext_summary Summary of Linux Wireless Extensions use |
| 151 | |
| 152 | AP selection depends on ap_scan configuration: |
| 153 | |
| 154 | ap_scan=1: |
| 155 | |
| 156 | - wpa_supplicant requests scan with SIOCSIWSCAN |
| 157 | - driver reports scan complete with wireless event SIOCGIWSCAN |
| 158 | - wpa_supplicant reads scan results with SIOCGIWSCAN (multiple call if |
| 159 | a larger buffer is needed) |
| 160 | - wpa_supplicant decides which AP to use based on scan results |
| 161 | - wpa_supplicant configures driver to associate with the selected BSS |
| 162 | (SIOCSIWMODE, SIOCSIWGENIE, SIOCSIWAUTH, SIOCSIWFREQ, |
| 163 | SIOCSIWESSID, SIOCSIWAP) |
| 164 | |
| 165 | ap_scan=2: |
| 166 | |
| 167 | - wpa_supplicant configures driver to associate with an SSID |
| 168 | (SIOCSIWMODE, SIOCSIWGENIE, SIOCSIWAUTH, SIOCSIWESSID) |
| 169 | |
| 170 | |
| 171 | After this, both modes use similar steps: |
| 172 | |
| 173 | - optionally (or required for drivers that generate WPA/RSN IE for |
| 174 | (Re)AssocReq), driver reports association parameters (AssocReq IEs) |
| 175 | with wireless event IWEVASSOCREQIE (and optionally IWEVASSOCRESPIE) |
| 176 | - driver reports association with wireless event SIOCGIWAP |
| 177 | - wpa_supplicant takes care of EAPOL frame handling (validating |
| 178 | information from associnfo and if needed, from scan results if WPA/RSN |
| 179 | IE from the Beacon frame is not reported through associnfo) |
| 180 | */ |