[802.11] Clean up, document, and add helper inline functions to ieee80211.h
[people/oremanj/gpxe.git] / src / include / gpxe / ieee80211.h
1 #ifndef _GPXE_IEEE80211_H
2 #define _GPXE_IEEE80211_H
3
4 #include <gpxe/if_ether.h>      /* for ETH_ALEN */
5
6 /** @file
7  * Constants and data structures defined in IEEE 802.11, subsetted
8  * according to what gPXE knows how to use.
9  */
10
11 FILE_LICENCE(GPL2_OR_LATER);
12
13 /* Maximum lengths of things: */
14
15 /** Maximum length of frame payload
16  *
17  * This does not include cryptographic overhead, which can be up to 20
18  * bytes, but it DOES include the 802.2 LLC/SNAP headers that are used
19  * on data frames (but not management frames).
20  */
21 #define IEEE80211_MAX_DATA_LEN          2304
22
23 /** Length of LLC/SNAP headers on data frames */
24 #define IEEE80211_LLC_HEADER_LEN        8
25
26 /** Maximum cryptographic overhead before encrypted data */
27 #define IEEE80211_MAX_CRYPTO_HEADER     8
28
29 /** Maximum cryptographic overhead after encrypted data */
30 #define IEEE80211_MAX_CRYPTO_TRAILER    12
31
32 /** Total maximum cryptographic overhead */
33 #define IEEE80211_MAX_CRYPTO_OVERHEAD   20
34
35 /** Bytes of network-layer data that can go into a regular data frame */
36 #define IEEE80211_MAX_FRAME_DATA        2296
37
38 /** Frame header length for frames we might work with
39  *
40  * QoS adds a two-byte field on top of this, and APs communicating
41  * with each other in Wireless Distribution System (WDS) mode add an
42  * extra 6-byte MAC address field, but we do not work with such
43  * frames.
44  */
45 #define IEEE80211_TYP_FRAME_HEADER_LEN  24
46
47 /** Theoretical maximum frame header length
48  *
49  * This includes the QoS and WDS Addr4 fields that we should never
50  * see.
51  */
52 #define IEEE80211_MAX_FRAME_HEADER_LEN  32
53
54 /** Maximum combined frame length
55  *
56  * The biggest frame will include 32 frame header bytes, 20 bytes of
57  * crypto overhead, and 2304 data bytes.
58  */
59 #define IEEE80211_MAX_FRAME_LEN         2356
60
61 /** Maximum length of an ESSID */
62 #define IEEE80211_MAX_SSID_LEN          32
63
64 /* ---------- Frame Control defines ---------- */
65
66 /** 802.11 Frame Control field, Version bitmask */
67 #define IEEE80211_FC_VERSION    0x0003
68
69 /** Expected value of Version bits in Frame Control */
70 #define  IEEE80211_THIS_VERSION  0x0000
71
72
73 /** 802.11 Frame Control field, Frame Type bitmask */
74 #define IEEE80211_FC_TYPE       0x000C
75
76 /** Type value for management (layer-2) frames */
77 #define  IEEE80211_TYPE_MGMT     0x0000
78
79 /** Type value for control (layer-1, hardware-managed) frames */
80 #define  IEEE80211_TYPE_CTRL     0x0004
81
82 /** Type value for data frames */
83 #define  IEEE80211_TYPE_DATA     0x0008
84
85
86 /** 802.11 Frame Control field, Frame Subtype bitmask */
87 #define IEEE80211_FC_SUBTYPE    0x00F0
88
89 /** Subtype value for association-request management frames
90  *
91  * Association request frames are sent after authentication from the
92  * client to the Access Point to establish the client as part of the
93  * Access Point's network.
94  */
95 #define  IEEE80211_STYPE_ASSOC_REQ    0x0000
96
97 /** Subtype value for association-response management frames
98  *
99  * Association response frames are sent by the Access Point to confirm
100  * or deny the association requested in an association request frame.
101  */
102 #define  IEEE80211_STYPE_ASSOC_RESP   0x0010
103
104 /** Subtype value for reassociation-request management frames
105  *
106  * Reassociation request frames are sent by clients wishing to change
107  * from one Access Point to another while roaming within the same
108  * extended network (same ESSID).
109  */
110 #define  IEEE80211_STYPE_REASSOC_REQ  0x0020
111
112 /** Subtype value for reassociation-response management frames
113  *
114  * Reassociation response frames are sent by the Access Point to
115  * confirm or deny the swap requested in a reassociation request
116  * frame.
117  */
118 #define  IEEE80211_STYPE_REASSOC_RESP 0x0030
119
120 /** Subtype value for probe-request management frames
121  *
122  * Probe request frames are sent by clients to request that all Access
123  * Points on the sending channel, or all belonging to a particular
124  * ESSID, identify themselves by BSSID, supported transfer rates, RF
125  * configuration, and other capabilities.
126  */
127 #define  IEEE80211_STYPE_PROBE_REQ    0x0040
128
129 /** Subtype value for probe-response management frames
130  *
131  * Probe response frames are sent by Access Points in response to
132  * probe request frames, providing the requested information.
133  */
134 #define  IEEE80211_STYPE_PROBE_RESP   0x0050
135
136 /** Subtype value for beacon management frames
137  *
138  * Beacon frames are sent by Access Points at regular intervals,
139  * usually ten per second, on the channel on which they communicate.
140  * They can be used to probe passively for access points on a channel
141  * where local regulatory restrictions prohibit active scanning, or
142  * due to their regularity as a mechanism to determine the fraction of
143  * packets that are being dropped.
144  */
145 #define  IEEE80211_STYPE_BEACON       0x0080
146
147 /** Subtype value for disassociation management frames
148  *
149  * Disassociation frames are sent by either a client or an Access
150  * Point to unequivocally terminate the association between the two.
151  * They may be sent by clients upon leaving the network, or by an
152  * Access Point upon reconfiguration, among other reasons; they are
153  * usually more "polite" than deauthentication frames.
154  */
155 #define  IEEE80211_STYPE_DISASSOC     0x00A0
156
157 /** Subtype value for authentication management frames
158  *
159  * Authentication frames are exchanged between a client and an Access
160  * Point before association may be performed. Confusingly, in the most
161  * common authentication method (Open System) no security tokens are
162  * exchanged at all. Modern 802.11 security handshaking takes place
163  * after association.
164  */
165 #define  IEEE80211_STYPE_AUTH         0x00B0
166
167 /** Subtype value for deauthentication management frames
168  *
169  * Deauthentication frames are sent by either a client or an Access
170  * Point to terminate the authentication (and therefore also the
171  * association) between the two. They are generally more forceful than
172  * disassociation frames, sent for such reasons as a failure to
173  * set up security properly after associating.
174  */
175 #define  IEEE80211_STYPE_DEAUTH       0x00C0
176
177 /** Subtype value for action management frames
178  *
179  * Action frames are used to implement spectrum management and QoS
180  * features that gPXE currently does not support.
181  */
182 #define  IEEE80211_STYPE_ACTION       0x00D0
183
184
185 /** Subtype value for RTS (request to send) control frames */
186 #define  IEEE80211_STYPE_RTS          0x00B0
187
188 /** Subtype value for CTS (clear to send) control frames */
189 #define  IEEE80211_STYPE_CTS          0x00C0
190
191 /** Subtype value for ACK (acknowledgement) control frames */
192 #define  IEEE80211_STYPE_ACK          0x00D0
193
194
195 /** Subtype value for ordinary data frames, with no QoS or CF add-ons */
196 #define  IEEE80211_STYPE_DATA         0x0000
197
198 /** Subtype value for data frames containing no data */
199 #define  IEEE80211_STYPE_NODATA       0x0040
200
201
202 /** 802.11 Frame Control field: To Data System flag
203  *
204  * This is set on data frames sent to an Access Point.
205  */
206 #define IEEE80211_FC_TODS       0x0100
207
208 /** 802.11 Frame Control field: From Data System flag
209  *
210  * This is set on data frames sent from an Access Point.
211  */
212 #define IEEE80211_FC_FROMDS     0x0200
213
214 /** 802.11 Frame Control field: More Fragments flag */
215 #define IEEE80211_FC_MORE_FRAG  0x0400
216
217 /** 802.11 Frame Control field: Retransmission flag */
218 #define IEEE80211_FC_RETRY      0x0800
219
220 /** 802.11 Frame Control field: Power Managed flag
221  *
222  * This is set on any frame sent by a low-power station that will go
223  * into a power-saving mode immediately after this frame. Access
224  * Points are not allowed to act as low-power stations.
225  */
226 #define IEEE80211_FC_PWR_MGMT   0x1000
227
228 /** 802.11 Frame Control field: More Data flag
229  *
230  * This is set on any frame sent by a station that has more data
231  * queued to be sent than is in the frame.
232  */
233 #define IEEE80211_FC_MORE_DATA  0x2000
234
235 /** 802.11 Frame Control field: Protected flag
236  *
237  * This is set on frames in which data is encrypted (by any method).
238  */
239 #define IEEE80211_FC_PROTECTED  0x4000
240
241 /** 802.11 Frame Control field: Ordered flag [?] */
242 #define IEEE80211_FC_ORDER      0x8000
243
244
245 /* ---------- Sequence Control defines ---------- */
246
247 /** Extract sequence number from 802.11 Sequence Control field */
248 #define IEEE80211_SEQNR( seq )          ( ( seq ) >> 4 )
249
250 /** Extract fragment number from 802.11 Sequence Control field */
251 #define IEEE80211_FRAG( seq )           ( ( seq ) & 0x000F )
252
253 /** Make 802.11 Sequence Control field from sequence and fragment numbers */
254 #define IEEE80211_MAKESEQ( seqnr, frag )        \
255         ( ( ( ( seqnr ) & 0xFFF ) << 4 ) | ( ( frag ) & 0xF ) )
256
257
258 /* ---------- Frame header formats ---------- */
259
260 /** An 802.11 data or management frame without QoS or WDS header fields */
261 struct ieee80211_frame
262 {
263         u16 fc;                 /**< 802.11 Frame Control field */
264         u16 duration;           /**< Microseconds to reserve link */
265         u8 addr1[ETH_ALEN];     /**< Address 1 (immediate receiver) */
266         u8 addr2[ETH_ALEN];     /**< Address 2 (immediate sender) */
267         u8 addr3[ETH_ALEN];     /**< Address 3 (often "forward to") */
268         u16 seq;                /**< 802.11 Sequence Control field */
269         u8 data[0];             /**< Beginning of frame data */
270 } __attribute__((packed));
271
272 /** The 802.2 LLC/SNAP header sent before actual data in a data frame
273  *
274  * This header is not acknowledged in the 802.11 standard at all; it
275  * is treated just like data for MAC-layer purposes, including
276  * fragmentation and encryption. It is actually two headers
277  * concatenated: a three-byte 802.2 LLC header indicating Subnetwork
278  * Accesss Protocol (SNAP) in both source and destination Service
279  * Access Point (SAP) fields, and a five-byte SNAP header indicating a
280  * zero OUI and two-byte Ethernet protocol type field.
281  *
282  * Thus, an eight-byte header in which six of the bytes are redundant.
283  * Lovely, isn't it?
284  */
285 struct ieee80211_llc_snap_header
286 {
287         /* LLC part: */
288         u8 dsap;                /**< Destination SAP ID */
289         u8 ssap;                /**< Source SAP ID */
290         u8 ctrl;                /**< Control information */
291
292         /* SNAP part: */
293         u8 oui[3];              /**< Organization code, usually 0 */
294         u16 ethertype;          /**< Ethernet Type field */
295 } __attribute__((packed));
296
297 /** Value for DSAP field in 802.2 LLC header for 802.11 frames: SNAP */
298 #define IEEE80211_LLC_DSAP      0xAA
299
300 /** Value for SSAP field in 802.2 LLC header for 802.11 frames: SNAP */
301 #define IEEE80211_LLC_SSAP      0xAA
302
303 /** Value for control field in 802.2 LLC header for 802.11 frames
304  *
305  * "Unnumbered Information".
306  */
307 #define IEEE80211_LLC_CTRL      0x03
308
309
310 /** 16-byte RTS frame format, with abbreviated header */
311 struct ieee80211_rts
312 {
313         u16 fc;
314         u16 duration;
315         u8 addr1[ETH_ALEN];
316         u8 addr2[ETH_ALEN];
317 } __attribute__((packed));
318
319 /** Length of 802.11 RTS control frame */
320 #define IEEE80211_RTS_LEN       16
321
322 /** 10-byte CTS or ACK frame format, with abbreviated header */
323 struct ieee80211_cts_or_ack
324 {
325         u16 fc;
326         u16 duration;
327         u8 addr1[ETH_ALEN];
328 } __attribute__((packed));
329
330 #define ieee80211_cts ieee80211_cts_or_ack
331 #define ieee80211_ack ieee80211_cts_or_ack
332
333 /** Length of 802.11 CTS control frame */
334 #define IEEE80211_CTS_LEN       10
335
336 /** Length of 802.11 ACK control frame */
337 #define IEEE80211_ACK_LEN       10
338
339
340 /* ---------- Capability and status defines ---------- */
341
342 /** Management frame capability field: Set if using an Access Point */
343 #define IEEE80211_CAPAB_MANAGED       0x0001
344
345 /** Management frame capability field: Set if operating in IBSS (no-AP) mode */
346 #define IEEE80211_CAPAB_ADHOC         0x0002
347
348 /** Management frame capability field: Set if we support CF operation */
349 #define IEEE80211_CAPAB_CFPOLL        0x0004
350
351 /** Management frame capability field: Set if we wish to be CF-Polled */
352 #define IEEE80211_CAPAB_CFPR          0x0008
353
354 /** Management frame capability field: Set if the network is encrypted */
355 #define IEEE80211_CAPAB_PRIVACY       0x0010
356
357 /** Management frame capability field: Set if PHY supports short preambles */
358 #define IEEE80211_CAPAB_SHORT_PMBL    0x0020
359
360 /** Management frame capability field: Set if PHY supports PBCC modulation */
361 #define IEEE80211_CAPAB_PBCC          0x0040
362
363 /** Management frame capability field: Set if we support Channel Agility */
364 #define IEEE80211_CAPAB_CHAN_AGILITY  0x0080
365
366 /** Management frame capability field: Set if we support spectrum management */
367 #define IEEE80211_CAPAB_SPECTRUM_MGMT 0x0100
368
369 /** Management frame capability field: Set if we support Quality of Service */
370 #define IEEE80211_CAPAB_QOS           0x0200
371
372 /** Management frame capability field: Set if PHY supports short slot time */
373 #define IEEE80211_CAPAB_SHORT_SLOT    0x0400
374
375 /** Management frame capability field: Set if PHY supports APSD option */
376 #define IEEE80211_CAPAB_APSD          0x0800
377
378 /** Management frame capability field: Set if PHY supports DSSS/OFDM modulation */
379 #define IEEE80211_CAPAB_DSSS_OFDM     0x2000
380
381 /** Management frame capability field: Set if we support delayed block ACK */
382 #define IEEE80211_CAPAB_DELAYED_BACK  0x4000
383
384 /** Management frame capability field: Set if we support immediate block ACK */
385 #define IEEE80211_CAPAB_IMMED_BACK    0x8000
386
387
388 #define IEEE80211_STATUS_SUCCESS                  0
389 #define IEEE80211_STATUS_FAILURE                  1
390 #define IEEE80211_STATUS_CAPAB_UNSUPP             10
391 #define IEEE80211_STATUS_REASSOC_NO_ASSOC         11
392 #define IEEE80211_STATUS_ASSOC_DENIED             12
393 #define IEEE80211_STATUS_AUTH_ALGO_UNSUPP         13
394 #define IEEE80211_STATUS_AUTH_SEQ_INVALID         14
395 #define IEEE80211_STATUS_AUTH_CHALL_INVALID       15
396 #define IEEE80211_STATUS_AUTH_TIMEOUT             16
397 #define IEEE80211_STATUS_ASSOC_NO_ROOM            17
398 #define IEEE80211_STATUS_ASSOC_NEED_RATE          18
399 #define IEEE80211_STATUS_ASSOC_NEED_SHORT_PMBL    19
400 #define IEEE80211_STATUS_ASSOC_NEED_PBCC          20
401 #define IEEE80211_STATUS_ASSOC_NEED_CHAN_AGILITY  21
402 #define IEEE80211_STATUS_ASSOC_NEED_SPECTRUM_MGMT 22
403 #define IEEE80211_STATUS_ASSOC_BAD_POWER          23
404 #define IEEE80211_STATUS_ASSOC_BAD_CHANNELS       24
405 #define IEEE80211_STATUS_ASSOC_NEED_SHORT_SLOT    25
406 #define IEEE80211_STATUS_ASSOC_NEED_DSSS_OFDM     26
407 #define IEEE80211_STATUS_ASSOC_NEED_QOS           35
408 #define IEEE80211_STATUS_REQUEST_DECLINED         37
409 #define IEEE80211_STATUS_REQUEST_INVALID          38
410 #define IEEE80211_STATUS_IE_INVALID               40
411 #define IEEE80211_STATUS_GROUP_CIPHER_INVALID     41
412 #define IEEE80211_STATUS_PAIR_CIPHER_INVALID      42
413 #define IEEE80211_STATUS_AKMP_INVALID             43
414 #define IEEE80211_STATUS_RSN_IE_VERSION_UNSUPP    44
415 #define IEEE80211_STATUS_RSN_IE_INVALID           45
416 #define IEEE80211_STATUS_CIPHER_REJECTED          46
417 #define IEEE80211_STATUS_ASSOC_LISTEN_TOO_HIGH    51
418
419
420 /* ---------- Information element declarations ---------- */
421
422 /** Generic 802.11 information element
423  *
424  * Many management frames include a section that amounts to a
425  * concatenation of IEs, so that the sender can choose which
426  * information to send and the receiver can ignore the parts it
427  * doesn't understand. Each IE contains this two-byte header, followed
428  * by IE-specific data.
429  */
430 struct ieee80211_ie_header {
431         u8 id;                  /**< Information element ID */
432         u8 len;                 /**< Information element length */
433 } __attribute__ ((packed));
434
435
436 /** 802.11 SSID information element */
437 struct ieee80211_ie_ssid {
438         u8 id;                  /**< SSID ID: 0 */
439         u8 len;                 /**< SSID length */
440         char ssid[0];           /**< SSID data, not NUL-terminated */
441 } __attribute__ ((packed));
442
443 /** Information element ID for SSID information element */
444 #define IEEE80211_IE_SSID       0
445
446
447 /** 802.11 rates information element
448  *
449  * The first 8 rates go in an IE of type RATES (1), and any more rates
450  * go in one of type EXT_RATES (50). Each rate is a byte with the low
451  * 7 bits equal to the rate in units of 500 kbps, and the high bit set
452  * if and only if the rate is "basic" (must be supported by all
453  * connected stations).
454  */
455 struct ieee80211_ie_rates {
456         u8 id;                  /**< Rates ID: 1 or 50 */
457         u8 len;                 /**< Number of rates */
458         u8 rates[0];            /**< Rates data, one rate per byte */
459 } __attribute__ ((packed));
460
461 /** Information element ID for rates information element */
462 #define IEEE80211_IE_RATES      1
463
464 /** Information element ID for extended rates information element */
465 #define IEEE80211_IE_EXT_RATES  50
466
467
468 /** 802.11 Direct Spectrum parameter information element
469  *
470  * This just contains the channel number.
471  */
472 struct ieee80211_ie_ds_param {
473         u8 id;                  /**< DS parameter ID: 3 */
474         u8 len;                 /**< DS parameter length: 1 */
475         u8 current_channel;     /**< Current channel number, 1-14 */
476 } __attribute__ ((packed));
477
478 /** Information element ID for Direct Spectrum parameter information element */
479 #define IEEE80211_IE_DS_PARAM   3
480
481
482 /** 802.11 Country information element regulatory extension triplet */
483 struct ieee80211_ie_country_ext_triplet {
484         u8 reg_ext_id;          /**< Regulatory extension ID */
485         u8 reg_class_id;        /**< Regulatory class ID */
486         u8 coverage_class;      /**< Coverage class */
487 } __attribute__ ((packed));
488
489 /** 802.11 Country information element regulatory band triplet */
490 struct ieee80211_ie_country_band_triplet {
491         u8 first_channel;       /**< Channel number for first channel in band */
492         u8 nr_channels;         /**< Number of contiguous channels in band */
493         u8 max_txpower;         /**< Maximum TX power in dBm */
494 } __attribute__ ((packed));
495
496 /** 802.11 Country information element regulatory triplet
497  *
498  * It is a band triplet if the first byte is 200 or less, and a
499  * regulatory extension triplet otherwise.
500  */
501 union ieee80211_ie_country_triplet {
502         /** Differentiator between band and ext triplets */
503         u8 first;
504
505         /** Information about a band of channels */
506         struct ieee80211_ie_country_band_triplet band;
507
508         /** Regulatory extension information */
509         struct ieee80211_ie_country_ext_triplet ext;
510 };
511
512 /** 802.11 Country information element
513  *
514  * This contains some data about RF regulations.
515  */
516 struct ieee80211_ie_country {
517         u8 id;                  /**< Country information ID: 7 */
518         u8 len;                 /**< Country information length: varies */
519         char name[2];           /**< ISO Alpha2 country code */
520         char in_out;            /**< 'I' for indoor, 'O' for outdoor */
521
522         /** List of regulatory triplets */
523         union ieee80211_ie_country_triplet triplet[0];
524 } __attribute__ ((packed));
525
526 /** Information element ID for Country information element */
527 #define IEEE80211_IE_COUNTRY    7
528
529
530 /** 802.11 Request information element
531  *
532  * This contains a list of information element types we would like to
533  * be included in probe response frames.
534  */
535 struct ieee80211_ie_request {
536         u8 id;                  /**< Request ID: 10 */
537         u8 len;                 /**< Number of IEs requested */
538         u8 request[0];          /**< List of IEs requested */
539 } __attribute__ ((packed));
540
541 /** Information element ID for Request information element */
542 #define IEEE80211_IE_REQUEST    10
543
544
545 /** 802.11 Challenge Text information element
546  *
547  * This is used in authentication frames under Shared Key
548  * authentication.
549  */
550 struct ieee80211_ie_challenge_text {
551         u8 id;                  /**< Challenge Text ID: 16 */
552         u8 len;                 /**< Challenge Text length: usually 128 */
553         u8 challenge_text[0];   /**< Challenge Text data */
554 } __attribute__ ((packed));
555
556 /** Information element ID for Challenge Text information element */
557 #define IEEE80211_IE_CHALLENGE_TEXT     16
558
559
560 /** 802.11 Power Constraint information element
561  *
562  * This is used to specify an additional power limitation on top of
563  * the Country requirements.
564  */
565 struct ieee80211_ie_power_constraint {
566         u8 id;                  /**< Power Constraint ID: 52 */
567         u8 len;                 /**< Power Constraint length: 1 */
568         u8 power_constraint;    /**< Decrease in allowed TX power, dBm */
569 } __attribute__ ((packed));
570
571 /** Information element ID for Power Constraint information element */
572 #define IEEE80211_IE_POWER_CONSTRAINT   52
573
574
575 /** 802.11 Power Capability information element
576  *
577  * This is used in association request frames to indicate the extremes
578  * of our TX power abilities.
579  */
580 struct ieee80211_ie_power_capab {
581         u8 id;                  /**< Power Capability ID: 33 */
582         u8 len;                 /**< Power Capability length: 2 */
583         u8 min_txpower;         /**< Minimum possible TX power, dBm */
584         u8 max_txpower;         /**< Maximum possible TX power, dBm */
585 } __attribute__ ((packed));
586
587 /** Information element ID for Power Capability information element */
588 #define IEEE80211_IE_POWER_CAPAB        33
589
590
591 /** 802.11 Channels information element channel band tuple */
592 struct ieee80211_ie_channels_channel_band {
593         u8 first_channel;       /**< Channel number of first channel in band */
594         u8 nr_channels;         /**< Number of channels in band */
595 } __attribute__ ((packed));
596
597 /** 802.11 Channels information element
598  *
599  * This is used in association frames to indicate the channels we can
600  * use.
601  */
602 struct ieee80211_ie_channels {
603         u8 id;                  /**< Channels ID: 36 */
604         u8 len;                 /**< Channels length: 2 */
605
606         /** List of (start, length) channel bands we can use */
607         struct ieee80211_ie_channels_channel_band channels[0];
608 } __attribute__ ((packed));
609
610 /** Information element ID for Channels information element */
611 #define IEEE80211_IE_CHANNELS   36
612
613
614 /** 802.11 ERP Information information element
615  *
616  * This is used to communicate some PHY-level flags.
617  */
618 struct ieee80211_ie_erp_info {
619         u8 id;                  /**< ERP Information ID: 42 */
620         u8 len;                 /**< ERP Information length: 1 */
621         u8 erp_info;            /**< ERP flags */
622 } __attribute__ ((packed));
623
624 /** Information element ID for ERP Information information element */
625 #define IEEE80211_IE_ERP_INFO   42
626
627 /** ERP information element: Flag set if 802.11b stations are present */
628 #define  IEEE80211_ERP_NONERP_PRESENT   0x01
629
630 /** ERP information element: Flag set if CTS protection must be used */
631 #define  IEEE80211_ERP_USE_PROTECTION   0x02
632
633 /** ERP information element: Flag set if long preambles must be used */
634 #define  IEEE80211_ERP_BARKER_LONG      0x04
635
636
637 /** Information element ID for Robust Security Network information element */
638 #define IEEE80211_IE_RSN        48
639
640 /** 802.11 Robust Security Network ("WPA") information element
641  *
642  * Showing once again a striking clarity of design, the IEEE folks put
643  * dynamically-sized data in the middle of this structure. As such,
644  * the below structure definition is only a guideline; the
645  * @c IEEE80211_RSN_FIELD, @c IEEE80211_RSN_CIPHER, and
646  * @c IEEE80211_RSN_AUTHTYPE macros should be used to access any
647  * data.
648  *
649  * Also inspired was IEEE's choice of 16-bit fields to count the
650  * number of 4-byte elements in a structure with a maximum length of
651  * 255 bytes.
652  *
653  * Many fields reference a cipher or authentication-type ID; this is a
654  * three-byte OUI followed by one byte identifying the cipher with
655  * respect to that OUI. For all standard ciphers the OUI is 00:0F:AC.
656  *
657  * The authentication types referenced in this structure have nothing
658  * to do with 802.11 authentication frames or the @c algorithm field
659  * within them.
660  */
661 struct ieee80211_ie_rsn {
662         /** Information element ID */
663         u8 id;
664
665         /** Information element length */
666         u8 len;
667
668         /** RSN information element version */
669         u16 version;
670
671         /** Cipher ID for the cipher used in multicast/broadcast frames */
672         u8 group_cipher[4];
673         
674         /** Number of unicast ciphers supported */
675         u16 pairwise_count;
676
677         /** List of cipher IDs for supported unicast frame ciphers */
678         u8 pairwise_cipher[4];
679         
680         /** Number of authentication types supported */
681         u16 akm_count;
682
683         /** List of authentication type IDs for supported types */
684         u8 akm_list[4];
685         
686         /** Security capabilities field. */
687         u16 rsn_capab;
688
689         /** Number of PMKIDs included (present only in association frames) */
690         u16 pmkid_count;
691
692         /** List of PMKIDs included, each a 16-byte SHA1 hash */
693         u8 pmkid_list[0];
694 } __attribute__((packed));
695
696 /** Extract RSN IE version field */
697 #define  IEEE80211_RSN_FIELD_version( rsnp ) ( (rsnp)->version )
698
699 /** Extract RSN IE group_cipher field */
700 #define  IEEE80211_RSN_FIELD_group_cipher( rsnp ) ( (rsnp)->group_cipher )
701
702 /** Extract RSN IE pairwise_count field */
703 #define  IEEE80211_RSN_FIELD_pairwise_count( rsnp ) ( (rsnp)->pairwise_count )
704
705 /** Extract RSN IE akm_count field */
706 #define  IEEE80211_RSN_FIELD_akm_count( rsnp )                  \
707         ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \
708                 4*( ( rsnp )->pairwise_count - 1 ) ) )->akm_count )
709
710 /** Extract RSN IE rsn_capab field */
711 #define  IEEE80211_RSN_FIELD_rsn_capab( rsnp )                  \
712         ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \
713                 4*( ( rsnp )->pairwise_count - 1 ) +            \
714                 4*( ( rsnp )->akm_count - 1 ) ) )->rsn_capab )
715
716 /** Extract RSN IE pmkid_count field */
717 #define  IEEE80211_RSN_FIELD_pmkid_count( rsnp )                \
718         ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \
719                 4*( ( rsnp )->pairwise_count - 1 ) +            \
720                 4*( ( rsnp )->akm_count - 1 ) ) )->pmkid_count )
721
722 /** Extract field from RSN information element
723  *
724  * @v rsnp      Pointer to RSN information element
725  * @v field     Name of field to extract
726  * @ret val     Lvalue of the requested field
727  *
728  * You must fill the fields of the structure in order for this to work
729  * properly.
730  */
731 #define  IEEE80211_RSN_FIELD( rsnp, field ) IEEE80211_RSN_FIELD_ ## field ( rsnp )
732
733 /** Get pointer to pairwise cipher from RSN information element
734  *
735  * @v rsnp      Pointer to RSN information element
736  * @v cipher    Index of pairwise cipher to extract
737  * @ret ptr     Pointer to requested cipher
738  */
739 #define  IEEE80211_RSN_CIPHER( rsnp, cipher )   \
740         ( ( rsnp )->pairwise_cipher + 4 * ( cipher ) )
741
742 /** Get pointer to authentication type from RSN information element
743  *
744  * @v rsnp      Pointer to RSN information element
745  * @v akm       Index of authentication type to extract
746  * @ret ptr     Pointer to requested authentication type
747  *
748  * The @c pairwise_count field must be correct.
749  */
750 #define  IEEE80211_RSN_AUTHTYPE( rsnp, akm )    \
751     ( ( rsnp )->akm_list + 4 * ( ( rsnp )->pairwise_count - 1 ) + 4 * ( akm ) )
752
753 /** Get pointer to PMKID from RSN information element
754  *
755  * @v rsnp      Pointer to RSN information element
756  * @v idx       Index of PMKID to extract
757  * @ret ptr     Pointer to requested PMKID
758  *
759  * The @c pairwise_count and @c akm_count fields must be correct.
760  */
761 #define  IEEE80211_RSN_PMKID( rsnp, idx )       \
762         ( ( rsnp )->pmkid_list + 4 * ( ( rsnp )->pairwise_count - 1 ) + \
763                         4 * ( ( rsnp )->akm_count - 1 ) + 16 * ( idx ) )
764
765 /** Verify size of RSN information element
766  *
767  * @v rsnp      Pointer to RSN information element
768  * @ret ok      TRUE if count fields are consistent with length field
769  *
770  * It is important to drop any RSN IE that does not pass this function
771  * before using the @c IEEE80211_RSN_FIELD, @c IEEE80211_RSN_CIPHER,
772  * and @c IEEE80211_RSN_AUTHTYPE macros, to avoid potential security
773  * compromise due to a malformed RSN IE.
774  *
775  * This function does not consider the possibility of some PMKIDs
776  * included in the RSN IE, because PMKIDs are only included in RSN IEs
777  * sent in association request frames, and we should never receive an
778  * association request frame. Such RSN IEs will always fail this check.
779  */
780 static inline int ieee80211_rsn_check ( struct ieee80211_ie_rsn *rsnp ) {
781         if ( rsnp->len < 12 + 4 * rsnp->pairwise_count )        
782                 return 0;
783         return ( rsnp->len == 12 + 4 * ( rsnp->pairwise_count +
784                                 IEEE80211_RSN_FIELD ( rsnp, akm_count ) ) );
785 }
786
787 /** Calculate necessary size of RSN information element
788  *
789  * @v npair     Number of pairwise ciphers supported
790  * @v nauth     Number of authentication types supported
791  * @v npmkid    Number of PMKIDs to include
792  * @ret size    Necessary size of RSN IE, including header bytes
793  */
794 static inline size_t ieee80211_rsn_size ( int npair, int nauth, int npmkid ) {
795         return 16 + 4 * ( npair + nauth ) + 16 * npmkid;
796 }
797
798 /** 802.11 RSN IE: expected version number */
799 #define  IEEE80211_RSN_VERSION          1
800
801 /** 802.11 RSN IE: fourth byte of cipher type for 40-bit WEP */
802 #define  IEEE80211_RSN_CTYPE_WEP40      1
803
804 /** 802.11 RSN IE: fourth byte of cipher type for 104-bit WEP */
805 #define  IEEE80211_RSN_CTYPE_WEP104     5
806
807 /** 802.11 RSN IE: fourth byte of cipher type for TKIP ("WPA") */
808 #define  IEEE80211_RSN_CTYPE_TKIP       2
809
810 /** 802.11 RSN IE: fourth byte of cipher type for CCMP ("WPA2") */
811 #define  IEEE80211_RSN_CTYPE_CCMP       4
812
813 /** 802.11 RSN IE: fourth byte of cipher type for "use group"
814  *
815  * This can only appear as a pairwise cipher, and means unicast frames
816  * should be encrypted in the same way as broadcast/multicast frames.
817  */
818 #define  IEEE80211_RSN_CTYPE_USEGROUP   0
819
820 /** 802.11 RSN IE: fourth byte of auth method type for using an 802.1X server */
821 #define  IEEE80211_RSN_ATYPE_8021X      1
822
823 /** 802.11 RSN IE: fourth byte of auth method type for using a pre-shared key */
824 #define  IEEE80211_RSN_ATYPE_PSK        2
825
826 /** 802.11 RSN IE capabilities: AP supports pre-authentication */
827 #define  IEEE80211_RSN_CAPAB_PREAUTH    0x001
828
829 /** 802.11 RSN IE capabilities: Node has conflict between TKIP and WEP
830  *
831  * This is a legacy issue; APs always set it to 0, and gPXE sets it to
832  * 0.
833  */
834 #define  IEEE80211_RSN_CAPAB_NO_PAIRWISE 0x002
835
836 /** 802.11 RSN IE capabilities: Number of PTKSA replay counters
837  *
838  * A value of 0 means one replay counter, 1 means two, 2 means four,
839  * and 3 means sixteen.
840  */
841 #define  IEEE80211_RSN_CAPAB_PTKSA_REPLAY 0x00C
842
843 /** 802.11 RSN IE capabilities: Number of GTKSA replay counters
844  *
845  * A value of 0 means one replay counter, 1 means two, 2 means four,
846  * and 3 means sixteen.
847  */
848 #define  IEEE80211_RSN_CAPAB_GTKSA_REPLAY 0x030
849
850 /** 802.11 RSN IE capabilities: PeerKey Handshaking is suported */
851 #define  IEEE80211_RSN_CAPAB_PEERKEY    0x200
852
853
854
855 /** Any 802.11 information element
856  *
857  * This is formatted for ease of use, so IEs with complex structures
858  * get referenced in full, while those with only one byte of data or a
859  * simple array are pulled in to avoid a layer of indirection like
860  * ie->channels.channels[0].
861  */
862 union ieee80211_ie
863 {
864         /** Generic and simple information element info */
865         struct {
866                 u8 id;          /**< Information element ID */
867                 u8 len;         /**< Information element data length */
868                 union {
869                         char ssid[0];   /**< SSID text */
870                         u8 rates[0];    /**< Rates data */
871                         u8 request[0];  /**< Request list */
872                         u8 challenge_text[0]; /**< Challenge text data */
873                         u8 power_constraint; /**< Power constraint, dBm */
874                         u8 erp_info;    /**< ERP information flags */
875                         /** List of channels */
876                         struct ieee80211_ie_channels_channel_band channels[0];
877                 };
878         };
879
880         /** DS parameter set */
881         struct ieee80211_ie_ds_param ds_param;
882
883         /** Country information */
884         struct ieee80211_ie_country country;
885
886         /** Power capability */
887         struct ieee80211_ie_power_capab power_capab;
888
889         /** Security information */
890         struct ieee80211_ie_rsn rsn;
891 };
892
893 /** Advance to next 802.11 information element
894  *
895  * @v ie        Current information element pointer
896  * @v end       Pointer to first byte not in information element space
897  * @ret next    Pointer to next information element, or NULL if no more
898  *
899  * When processing received IEs, @a end should be set to the I/O
900  * buffer tail pointer; when marshalling IEs for sending, @a end
901  * should be NULL.
902  */
903 static inline union ieee80211_ie *ieee80211_next_ie ( union ieee80211_ie *ie,
904                                                       void *end ) 
905 {
906         void *next_ie_byte = ( void * ) ie + ie->len + 2;
907         union ieee80211_ie *next_ie = next_ie_byte;
908
909         if ( ! end )
910                 return next_ie;
911
912         if ( next_ie_byte < end && next_ie_byte + next_ie->len <= end )
913                 return next_ie;
914
915         return NULL;
916 }
917
918
919 /* ---------- Management frame data formats ---------- */
920
921 /** Beacon or probe response frame data */
922 struct ieee80211_beacon_or_probe_resp
923 {
924         /** 802.11 TSFT value at frame send */
925         u64 timestamp;
926
927         /** Beacons sent every beacon_interval*1024 us */
928         u16 beacon_interval;
929
930         /** Capability flags */
931         u16 capability;
932
933         /** List of information elements */
934         union ieee80211_ie info_element[0];
935 } __attribute__((packed));
936
937 #define ieee80211_beacon        ieee80211_beacon_or_probe_resp
938 #define ieee80211_probe_resp    ieee80211_beacon_or_probe_resp
939
940 /** Disassociation or deauthentication frame data */
941 struct ieee80211_disassoc_or_deauth
942 {
943         /** Reason code */
944         u16 reason;
945 } __attribute__((packed));
946
947 #define ieee80211_disassoc      ieee80211_disassoc_or_deauth
948 #define ieee80211_deauth        ieee80211_disassoc_or_deauth
949
950 /** Association request frame data */
951 struct ieee80211_assoc_req
952 {
953         /** Capability flags */
954         u16 capability;
955
956         /** Power-managed stations wake up every listen_interval beacons */
957         u16 listen_interval;
958
959         /** List of information elements */
960         union ieee80211_ie info_element[0];
961 } __attribute__((packed));
962
963 /** Association or reassociation response frame data */
964 struct ieee80211_assoc_or_reassoc_resp
965 {
966         /** Capability flags */
967         u16 capability;
968
969         /** Status code */
970         u16 status;
971
972         /** Association ID */
973         u16 aid;
974
975         /** List of information elements */
976         union ieee80211_ie info_element[0];
977 } __attribute__((packed));
978
979 #define ieee80211_assoc_resp    ieee80211_assoc_or_reassoc_resp
980 #define ieee80211_reassoc_resp  ieee80211_assoc_or_reassoc_resp
981
982 /** Reassociation request frame data */
983 struct ieee80211_reassoc_req
984 {
985         /** Capability flags */
986         u16 capability;
987
988         /** Power-managed stations wake up every listen_interval beacons */
989         u16 listen_interval;
990
991         /** MAC address of current Access Point */
992         u8 current_addr[ETH_ALEN];
993
994         /** List of information elements */
995         union ieee80211_ie info_element[0];
996 } __attribute__((packed));
997
998 /** Probe request frame data */
999 struct ieee80211_probe_req
1000 {
1001         /** List of information elements */
1002         union ieee80211_ie info_element[0];
1003 } __attribute__((packed));
1004
1005 /** Authentication frame data */
1006 struct ieee80211_auth
1007 {
1008         /** Authentication algorithm */
1009         u16 algorithm;
1010
1011         /** Sequence number of this frame; first from client to AP is 1 */
1012         u16 tx_seq;
1013
1014         /** Status code */
1015         u16 status;
1016
1017         /** List of information elements */
1018         union ieee80211_ie info_element[0];
1019 } __attribute__((packed));
1020
1021 /** Open System authentication algorithm */
1022 #define IEEE80211_AUTH_OPEN_SYSTEM  0
1023
1024 /** Shared Key authentication algorithm */
1025 #define IEEE80211_AUTH_SHARED_KEY   1
1026
1027
1028 #endif