1 | /**
|
---|
2 | \page porting Porting to different target boards and operating systems
|
---|
3 |
|
---|
4 | %wpa_supplicant was designed to be easily portable to different
|
---|
5 | hardware (board, CPU) and software (OS, drivers) targets. It is
|
---|
6 | already used with number of operating systems and numerous wireless
|
---|
7 | card models and drivers. The main %wpa_supplicant repository includes
|
---|
8 | support for Linux, FreeBSD, and Windows. In addition, the code has been
|
---|
9 | ported to number of other operating systems like VxWorks, PalmOS,
|
---|
10 | Windows CE, and Windows Mobile. On the hardware
|
---|
11 | side, %wpa_supplicant is used on various systems: desktops, laptops,
|
---|
12 | PDAs, and embedded devices with CPUs including x86, PowerPC,
|
---|
13 | arm/xscale, and MIPS. Both big and little endian configurations are
|
---|
14 | supported.
|
---|
15 |
|
---|
16 |
|
---|
17 | \section ansi_c_extra Extra functions on top of ANSI C
|
---|
18 |
|
---|
19 | %wpa_supplicant is mostly using ANSI C functions that are available on
|
---|
20 | most targets. However, couple of additional functions that are common
|
---|
21 | on modern UNIX systems are used. Number of these are listed with
|
---|
22 | prototypes in common.h (the \verbatim #ifdef CONFIG_ANSI_C_EXTRA \endverbatim
|
---|
23 | block). These functions may need to be implemented or at least defined
|
---|
24 | as macros to native functions in the target OS or C library.
|
---|
25 |
|
---|
26 | Many of the common ANSI C functions are used through a wrapper
|
---|
27 | definitions in os.h to allow these to be replaced easily with a
|
---|
28 | platform specific version in case standard C libraries are not
|
---|
29 | available. In addition, os.h defines couple of common platform
|
---|
30 | specific functions that are implemented in os_unix.c for UNIX like
|
---|
31 | targets and in os_win32.c for Win32 API. If the target platform does
|
---|
32 | not support either of these examples, a new os_*.c file may need to be
|
---|
33 | added.
|
---|
34 |
|
---|
35 | Unless OS_NO_C_LIB_DEFINES is defined, the standard ANSI C and POSIX
|
---|
36 | functions are used by defining the os_*() wrappers to use them
|
---|
37 | directly in order to avoid extra cost in size and speed. If the target
|
---|
38 | platform needs different versions of the functions, os.h can be
|
---|
39 | modified to define the suitable macros or alternatively,
|
---|
40 | OS_NO_C_LIB_DEFINES may be defined for the build and the wrapper
|
---|
41 | functions can then be implemented in a new os_*.c wrapper file.
|
---|
42 |
|
---|
43 | common.h defines number of helper macros for handling integers of
|
---|
44 | different size and byte order. Suitable version of these definitions
|
---|
45 | may need to be added for the target platform.
|
---|
46 |
|
---|
47 |
|
---|
48 | \section configuration_backend Configuration backend
|
---|
49 |
|
---|
50 | %wpa_supplicant implements a configuration interface that allows the
|
---|
51 | backend to be easily replaced in order to read configuration data from
|
---|
52 | a suitable source depending on the target platform. config.c
|
---|
53 | implements the generic code that can be shared with all configuration
|
---|
54 | backends. Each backend is implemented in its own config_*.c file.
|
---|
55 |
|
---|
56 | The included config_file.c backend uses a text file for configuration
|
---|
57 | and config_winreg.c uses Windows registry. These files can be used as
|
---|
58 | an example for a new configuration backend if the target platform uses
|
---|
59 | different mechanism for configuration parameters. In addition,
|
---|
60 | config_none.c can be used as an empty starting point for building a
|
---|
61 | new configuration backend.
|
---|
62 |
|
---|
63 |
|
---|
64 | \section driver_iface_porting Driver interface
|
---|
65 |
|
---|
66 | Unless the target OS and driver is already supported, most porting
|
---|
67 | projects have to implement a driver wrapper. This may be done by
|
---|
68 | adding a new driver interface module or modifying an existing module
|
---|
69 | (driver_*.c) if the new target is similar to one of them. \ref
|
---|
70 | driver_wrapper "Driver wrapper implementation" describes the details
|
---|
71 | of the driver interface and discusses the tasks involved in porting
|
---|
72 | this part of %wpa_supplicant.
|
---|
73 |
|
---|
74 |
|
---|
75 | \section l2_packet_porting l2_packet (link layer access)
|
---|
76 |
|
---|
77 | %wpa_supplicant needs to have access to sending and receiving layer 2
|
---|
78 | (link layer) packets with two Ethertypes: EAP-over-LAN (EAPOL) 0x888e
|
---|
79 | and RSN pre-authentication 0x88c7. l2_packet.h defines the interfaces
|
---|
80 | used for this in the core %wpa_supplicant implementation.
|
---|
81 |
|
---|
82 | If the target operating system supports a generic mechanism for link
|
---|
83 | layer access, that is likely the best mechanism for providing the
|
---|
84 | needed functionality for %wpa_supplicant. Linux packet socket is an
|
---|
85 | example of such a generic mechanism. If this is not available, a
|
---|
86 | separate interface may need to be implemented to the network stack or
|
---|
87 | driver. This is usually an intermediate or protocol driver that is
|
---|
88 | operating between the device driver and the OS network stack. If such
|
---|
89 | a mechanism is not feasible, the interface can also be implemented
|
---|
90 | directly in the device driver.
|
---|
91 |
|
---|
92 | The main %wpa_supplicant repository includes l2_packet implementations
|
---|
93 | for Linux using packet sockets (l2_packet_linux.c), more portable
|
---|
94 | version using libpcap/libdnet libraries (l2_packet_pcap.c; this
|
---|
95 | supports WinPcap, too), and FreeBSD specific version of libpcap
|
---|
96 | interface (l2_packet_freebsd.c).
|
---|
97 |
|
---|
98 | If the target operating system is supported by libpcap (receiving) and
|
---|
99 | libdnet (sending), l2_packet_pcap.c can likely be used with minimal or
|
---|
100 | no changes. If this is not a case or a proprietary interface for link
|
---|
101 | layer is required, a new l2_packet module may need to be
|
---|
102 | added. Alternatively, struct wpa_driver_ops::send_eapol() handler can
|
---|
103 | be used to override the l2_packet library if the link layer access is
|
---|
104 | integrated with the driver interface implementation.
|
---|
105 |
|
---|
106 |
|
---|
107 | \section eloop_porting Event loop
|
---|
108 |
|
---|
109 | %wpa_supplicant uses a single process/thread model and an event loop
|
---|
110 | to provide callbacks on events (registered timeout, received packet,
|
---|
111 | signal). eloop.h defines the event loop interface. eloop.c is an
|
---|
112 | implementation of such an event loop using select() and sockets. This
|
---|
113 | is suitable for most UNIX/POSIX systems. When porting to other
|
---|
114 | operating systems, it may be necessary to replace that implementation
|
---|
115 | with OS specific mechanisms that provide similar functionality.
|
---|
116 |
|
---|
117 |
|
---|
118 | \section ctrl_iface_porting Control interface
|
---|
119 |
|
---|
120 | %wpa_supplicant uses a \ref ctrl_iface_page "control interface"
|
---|
121 | to allow external processed
|
---|
122 | to get status information and to control the operations. Currently,
|
---|
123 | this is implemented with socket based communication; both UNIX domain
|
---|
124 | sockets and UDP sockets are supported. If the target OS does not
|
---|
125 | support sockets, this interface will likely need to be modified to use
|
---|
126 | another mechanism like message queues. The control interface is
|
---|
127 | optional component, so it is also possible to run %wpa_supplicant
|
---|
128 | without porting this part.
|
---|
129 |
|
---|
130 | The %wpa_supplicant side of the control interface is implemented in
|
---|
131 | ctrl_iface.c. Matching client side is implemented as a control
|
---|
132 | interface library in wpa_ctrl.c.
|
---|
133 |
|
---|
134 |
|
---|
135 | \section entry_point Program entry point
|
---|
136 |
|
---|
137 | %wpa_supplicant defines a set of functions that can be used to
|
---|
138 | initialize main supplicant processing. Each operating system has a
|
---|
139 | mechanism for starting new processing or threads. This is usually a
|
---|
140 | function with a specific set of arguments and calling convention. This
|
---|
141 | function is responsible on initializing %wpa_supplicant.
|
---|
142 |
|
---|
143 | main.c includes an entry point for UNIX-like operating system, i.e.,
|
---|
144 | main() function that uses command line arguments for setting
|
---|
145 | parameters for %wpa_supplicant. When porting to other operating
|
---|
146 | systems, similar OS-specific entry point implementation is needed. It
|
---|
147 | can be implemented in a new file that is then linked with
|
---|
148 | %wpa_supplicant instead of main.o. main.c is also a good example on
|
---|
149 | how the initialization process should be done.
|
---|
150 |
|
---|
151 | The supplicant initialization functions are defined in
|
---|
152 | wpa_supplicant_i.h. In most cases, the entry point function should
|
---|
153 | start by fetching configuration parameters. After this, a global
|
---|
154 | %wpa_supplicant context is initialized with a call to
|
---|
155 | wpa_supplicant_init(). After this, existing network interfaces can be
|
---|
156 | added with wpa_supplicant_add_iface(). wpa_supplicant_run() is then
|
---|
157 | used to start the main event loop. Once this returns at program
|
---|
158 | termination time, wpa_supplicant_deinit() is used to release global
|
---|
159 | context data.
|
---|
160 |
|
---|
161 | wpa_supplicant_add_iface() and wpa_supplicant_remove_iface() can be
|
---|
162 | used dynamically to add and remove interfaces based on when
|
---|
163 | %wpa_supplicant processing is needed for them. This can be done, e.g.,
|
---|
164 | when hotplug network adapters are being inserted and ejected. It is
|
---|
165 | also possible to do this when a network interface is being
|
---|
166 | enabled/disabled if it is desirable that %wpa_supplicant processing
|
---|
167 | for the interface is fully enabled/disabled at the same time.
|
---|
168 |
|
---|
169 |
|
---|
170 | \section simple_build Simple build example
|
---|
171 |
|
---|
172 | One way to start a porting project is to begin with a very simple
|
---|
173 | build of %wpa_supplicant with WPA-PSK support and once that is
|
---|
174 | building correctly, start adding features.
|
---|
175 |
|
---|
176 | Following command can be used to build very simple version of
|
---|
177 | %wpa_supplicant:
|
---|
178 |
|
---|
179 | \verbatim
|
---|
180 | cc -o wpa_supplicant config.c eloop.c common.c md5.c rc4.c sha1.c \
|
---|
181 | config_none.c l2_packet_none.c tls_none.c wpa.c preauth.c \
|
---|
182 | aes_wrap.c wpa_supplicant.c events.c main_none.c drivers.c
|
---|
183 | \endverbatim
|
---|
184 |
|
---|
185 | The end result is not really very useful since it uses empty functions
|
---|
186 | for configuration parsing and layer 2 packet access and does not
|
---|
187 | include a driver interface. However, this is a good starting point
|
---|
188 | since the build is complete in the sense that all functions are
|
---|
189 | present and this is easy to configure to a build system by just
|
---|
190 | including the listed C files.
|
---|
191 |
|
---|
192 | Once this version can be build successfully, the end result can be
|
---|
193 | made functional by adding a proper program entry point (main*.c),
|
---|
194 | driver interface (driver_*.c and matching CONFIG_DRIVER_* define for
|
---|
195 | registration in drivers.c), configuration parser/writer (config_*.c),
|
---|
196 | and layer 2 packet access implementation (l2_packet_*.c). After these
|
---|
197 | components have been added, the end result should be a working
|
---|
198 | WPA/WPA2-PSK enabled supplicant.
|
---|
199 |
|
---|
200 | After the basic functionality has been verified to work, more features
|
---|
201 | can be added by linking in more files and defining C pre-processor
|
---|
202 | defines. Currently, the best source of information for what options
|
---|
203 | are available and which files needs to be included is in the Makefile
|
---|
204 | used for building the supplicant with make. Similar configuration will
|
---|
205 | be needed for build systems that either use different type of make
|
---|
206 | tool or a GUI-based project configuration.
|
---|
207 |
|
---|
208 | */
|
---|