| /** | |
| \page driver_wrapper Driver wrapper implementation (driver.h, drivers.c) | |
| All hardware and driver dependent functionality is in separate C files | |
| that implement defined wrapper functions. Other parts | |
| of the wpa_supplicant are designed to be hardware, driver, and operating | |
| system independent. | |
| Driver wrappers need to implement whatever calls are used in the | |
| target operating system/driver for controlling wireless LAN | |
| devices. As an example, in case of Linux, these are mostly some glue | |
| code and ioctl() calls and netlink message parsing for Linux Wireless | |
| Extensions (WE). Since features required for WPA were added only recently to | |
| Linux Wireless Extensions (in version 18), some driver specific code is used | |
| in number of driver interface implementations. These driver dependent parts | |
| can be replaced with generic code in \ref driver_wext.c once the target driver | |
| includes full support for WE-18. After that, all Linux drivers, at | |
| least in theory, could use the same driver wrapper code. | |
| A driver wrapper needs to implement some or all of the functions | |
| defined in \ref driver.h. These functions are registered by filling struct | |
| \ref wpa_driver_ops with function pointers. Hardware independent parts of | |
| wpa_supplicant will call these functions to control the driver/wlan | |
| card. In addition, support for driver events is required. The event | |
| callback function, \ref wpa_supplicant_event(), and its parameters are | |
| documented in \ref driver.h. In addition, a pointer to the 'struct | |
| \ref wpa_driver_ops' needs to be registered in \ref drivers.c file. | |
| When porting to other operating systems, the driver wrapper should be | |
| modified to use the native interface of the target OS. It is possible | |
| that some extra requirements for the interface between the driver | |
| wrapper and generic wpa_supplicant code are discovered during porting | |
| to a new operating system. These will be addressed on case by case | |
| basis by modifying the interface and updating the other driver | |
| wrappers for this. The goal is to avoid changing this interface | |
| without very good reasons in order to limit the number of changes | |
| needed to other wrappers and hardware independent parts of | |
| wpa_supplicant. When changes are required, recommended way is to | |
| make them in backwards compatible way that allows existing driver | |
| interface implementations to be compiled without any modification. | |
| Generic Linux Wireless Extensions functions are implemented in | |
| \ref driver_wext.c. All Linux driver wrappers can use these when the kernel | |
| driver supports the generic ioctl()s and wireless events. Driver | |
| specific functions are implemented in separate C files, e.g., | |
| \ref driver_hostap.c. These files need to define struct \ref wpa_driver_ops | |
| entry that will be used in \ref wpa_supplicant.c when calling driver | |
| functions. struct \ref wpa_driver_ops entries are registered in \ref drivers.c. | |
| In general, it is likely to be useful to first take a look at couple | |
| of driver interface examples before starting on implementing a new | |
| one. \ref driver_hostap.c and \ref driver_wext.c include a complete | |
| implementation for Linux drivers that use wpa_supplicant-based control | |
| of WPA IE and roaming. \ref driver_ndis.c (with help from \ref driver_ndis_.c) | |
| is an example of a complete interface for Windows NDIS interface for | |
| drivers that generate WPA IE themselves and decide when to roam. These | |
| example implementations include full support for all security modes. | |
| \section driver_req Driver requirements for WPA | |
| WPA introduces new requirements for the device driver. At least some | |
| of these need to be implemented in order to provide enough support for | |
| wpa_supplicant. | |
| \subsection driver_tkip_ccmp TKIP/CCMP | |
| WPA requires that the pairwise cipher suite (encryption algorithm for | |
| unicast data packets) is TKIP or CCMP. These are new encryption | |
| protocols and thus, the driver will need to be modified to support | |
| them. Depending on the used wlan hardware, some parts of these may be | |
| implemented by the hardware/firmware. | |
| Specification for both TKIP and CCMP is available from IEEE (IEEE | |
| 802.11i amendment). Fully functional, hardware independent | |
| implementation of both encryption protocols is also available in Host | |
| AP driver (driver/modules/hostap_{tkip,ccmp}.c). In addition, Linux 2.6 | |
| kernel tree has generic implementations for WEP, TKIP, and CCMP that can | |
| be used in Linux drivers. | |
| The driver will also need to provide configuration mechanism to allow | |
| user space programs to configure TKIP and CCMP. Linux Wireless Extensions | |
| v18 added support for configuring these algorithms and | |
| individual/non-default keys. If the target kernel does not include WE-18, | |
| private ioctls can be used to provide similar functionality. | |
| \subsection driver_roaming Roaming control and scanning support | |
| wpa_supplicant can optionally control AP selection based on the | |
| information received from Beacon and/or Probe Response frames | |
| (ap_scan=1 mode in configuration). This means that the driver should | |
| support external control for scan process. In case of Linux, use of | |
| new Wireless Extensions scan support (i.e., 'iwlist wlan0 scan') is | |
| recommended. The current driver wrapper (\ref driver_wext.c) uses this for | |
| scan results. | |
| Scan results must also include the WPA information element. Support for | |
| this was added in WE-18. With older versions, a custom event can be used | |
| to provide the full WPA IE (including element id and length) as a hex | |
| string that is included in the scan results. | |
| wpa_supplicant needs to also be able to request the driver to | |
| associate with a specific BSS. Current Host AP driver and matching | |
| \ref driver_hostap.c wrapper uses following sequence for this | |
| request. Similar/identical mechanism should be usable also with other | |
| drivers. | |
| - set WPA IE for AssocReq with private ioctl | |
| - set SSID with SIOCSIWESSID | |
| - set channel/frequency with SIOCSIWFREQ | |
| - set BSSID with SIOCSIWAP | |
| (this last ioctl will trigger the driver to request association) | |
| \subsection driver_wpa_ie WPA IE generation | |
| wpa_supplicant selects which cipher suites and key management suites | |
| are used. Based on this information, it generates a WPA IE. This is | |
| provided to the driver interface in the associate call. This does not | |
| match with Windows NDIS drivers which generate the WPA IE | |
| themselves. | |
| wpa_supplicant allows Windows NDIS-like behavior by providing the | |
| selected cipher and key management suites in the associate call. If | |
| the driver generates its own WPA IE and that differs from the one | |
| generated by wpa_supplicant, the driver has to inform wpa_supplicant | |
| about the used WPA IE (i.e., the one it used in (Re)Associate | |
| Request). This notification is done using EVENT_ASSOCINFO event (see | |
| \ref driver.h). wpa_supplicant is normally configured to use | |
| ap_scan=2 mode with drivers that control WPA IE generation and roaming. | |
| \subsection driver_events Driver events | |
| wpa_supplicant needs to receive event callbacks when certain events | |
| occur (association, disassociation, Michael MIC failure, scan results | |
| available, PMKSA caching candidate). These events and the callback | |
| details are defined in \ref driver.h (\ref wpa_supplicant_event() function | |
| and enum \ref wpa_event_type). | |
| On Linux, association and disassociation can use existing Wireless | |
| Extensions event that is reporting new AP with SIOCGIWAP | |
| event. Similarly, completion of a scan can be reported with SIOCGIWSCAN | |
| event. | |
| Michael MIC failure event was added in WE-18. Older versions of Wireless | |
| Extensions will need to use a custom event. Host AP driver used a custom | |
| event with following contents: MLME-MICHAELMICFAILURE.indication(keyid=# | |
| broadcast/unicast addr=addr2). This is the recommended format until | |
| the driver can be moved to use WE-18 mechanism. | |
| \subsection driver_wext_summary Summary of Linux Wireless Extensions use | |
| AP selection depends on ap_scan configuration: | |
| ap_scan=1: | |
| - wpa_supplicant requests scan with SIOCSIWSCAN | |
| - driver reports scan complete with wireless event SIOCGIWSCAN | |
| - wpa_supplicant reads scan results with SIOCGIWSCAN (multiple call if | |
| a larget buffer is needed) | |
| - wpa_supplicant decides which AP to use based on scan results | |
| - wpa_supplicant configures driver to associate with the selected BSS | |
| (SIOCSIWMODE, SIOCSIWGENIE, SIOCSIWAUTH, SIOCSIWFREQ, | |
| SIOCSIWESSID, SIOCSIWAP) | |
| ap_scan=2: | |
| - wpa_supplicant configures driver to associate with an SSID | |
| (SIOCSIWMODE, SIOCSIWGENIE, SIOCSIWAUTH, SIOCSIWESSID) | |
| After this, both modes use similar steps: | |
| - optionally (or required for drivers that generate WPA/RSN IE for | |
| (Re)AssocReq), driver reports association parameters (AssocReq IEs) | |
| with wireless event IWEVASSOCREQIE (and optionally IWEVASSOCRESPIE) | |
| - driver reports association with wireless event SIOCGIWAP | |
| - wpa_supplicant takes care of EAPOL frame handling (validating | |
| information from associnfo and if needed, from scan results if WPA/RSN | |
| IE from the Beacon frame is not reported through associnfo) | |
| */ |