181 lines
8.5 KiB
Text
181 lines
8.5 KiB
Text
|
/**
|
||
|
\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 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 driver.h. These functions are registered by filling struct
|
||
|
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, wpa_supplicant_event(), and its parameters are
|
||
|
documented in driver.h. In addition, a pointer to the 'struct
|
||
|
wpa_driver_ops' needs to be registered in 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
|
||
|
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.,
|
||
|
driver_hostap.c. These files need to define struct wpa_driver_ops
|
||
|
entry that will be used in wpa_supplicant.c when calling driver
|
||
|
functions. struct wpa_driver_ops entries are registered in 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. driver_hostap.c and driver_wext.c include a complete
|
||
|
implementation for Linux drivers that use %wpa_supplicant-based control
|
||
|
of WPA IE and roaming. driver_ndis.c (with help from 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 (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
|
||
|
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
|
||
|
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 driver.h (wpa_supplicant_event() function
|
||
|
and enum 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)
|
||
|
*/
|