123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- /**
- \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)
- */
|