iPXE
ieee80211.h
Go to the documentation of this file.
00001 #ifndef _IPXE_IEEE80211_H
00002 #define _IPXE_IEEE80211_H
00003 
00004 #include <stddef.h>
00005 #include <ipxe/if_ether.h>      /* for ETH_ALEN */
00006 #include <endian.h>
00007 
00008 /** @file
00009  * Constants and data structures defined in IEEE 802.11, subsetted
00010  * according to what iPXE knows how to use.
00011  */
00012 
00013 FILE_LICENCE(GPL2_OR_LATER);
00014 
00015 /* ---------- Maximum lengths of things ---------- */
00016 
00017 /**
00018  * @defgroup ieee80211_maxlen Maximum lengths in the 802.11 protocol
00019  * @{
00020  */
00021 
00022 /** Maximum length of frame payload
00023  *
00024  * This does not include cryptographic overhead, which can be up to 20
00025  * bytes, but it DOES include the 802.2 LLC/SNAP headers that are used
00026  * on data frames (but not management frames).
00027  */
00028 #define IEEE80211_MAX_DATA_LEN          2304
00029 
00030 /** Length of LLC/SNAP headers on data frames */
00031 #define IEEE80211_LLC_HEADER_LEN        8
00032 
00033 /** Maximum cryptographic overhead before encrypted data */
00034 #define IEEE80211_MAX_CRYPTO_HEADER     8
00035 
00036 /** Maximum cryptographic overhead after encrypted data
00037  *
00038  * This does not count the MIC in TKIP frames, since that is
00039  * considered to be part of the MSDU and thus contributes to the size
00040  * of the data field.
00041  *
00042  * It @e does count the MIC in CCMP frames, which is considered part
00043  * of the MPDU (outside the data field).
00044  */
00045 #define IEEE80211_MAX_CRYPTO_TRAILER    8
00046 
00047 /** Total maximum cryptographic overhead */
00048 #define IEEE80211_MAX_CRYPTO_OVERHEAD   16
00049 
00050 /** Bytes of network-layer data that can go into a regular data frame */
00051 #define IEEE80211_MAX_FRAME_DATA        2296
00052 
00053 /** Frame header length for frames we might work with
00054  *
00055  * QoS adds a two-byte field on top of this, and APs communicating
00056  * with each other in Wireless Distribution System (WDS) mode add an
00057  * extra 6-byte MAC address field, but we do not work with such
00058  * frames.
00059  */
00060 #define IEEE80211_TYP_FRAME_HEADER_LEN  24
00061 
00062 /** Theoretical maximum frame header length
00063  *
00064  * This includes the QoS and WDS Addr4 fields that we should never
00065  * see.
00066  */
00067 #define IEEE80211_MAX_FRAME_HEADER_LEN  32
00068 
00069 /** Maximum combined frame length
00070  *
00071  * The biggest frame will include 32 frame header bytes, 16 bytes of
00072  * crypto overhead, and 2304 data bytes.
00073  */
00074 #define IEEE80211_MAX_FRAME_LEN         2352
00075 
00076 /** Maximum length of an ESSID */
00077 #define IEEE80211_MAX_SSID_LEN          32
00078 
00079 /** @} */
00080 
00081 
00082 /* ---------- Frame Control defines ---------- */
00083 
00084 /**
00085  * @defgroup ieee80211_fc 802.11 Frame Control field bits
00086  * @{
00087  */
00088 
00089 /** 802.11 Frame Control field, Version bitmask */
00090 #define IEEE80211_FC_VERSION    0x0003
00091 
00092 /** Expected value of Version bits in Frame Control */
00093 #define  IEEE80211_THIS_VERSION  0x0000
00094 
00095 
00096 /** 802.11 Frame Control field, Frame Type bitmask */
00097 #define IEEE80211_FC_TYPE       0x000C
00098 
00099 /** Type value for management (layer-2) frames */
00100 #define  IEEE80211_TYPE_MGMT     0x0000
00101 
00102 /** Type value for control (layer-1, hardware-managed) frames */
00103 #define  IEEE80211_TYPE_CTRL     0x0004
00104 
00105 /** Type value for data frames */
00106 #define  IEEE80211_TYPE_DATA     0x0008
00107 
00108 
00109 /** 802.11 Frame Control field, Frame Subtype bitmask */
00110 #define IEEE80211_FC_SUBTYPE    0x00F0
00111 
00112 /** Subtype value for association-request management frames
00113  *
00114  * Association request frames are sent after authentication from the
00115  * client to the Access Point to establish the client as part of the
00116  * Access Point's network.
00117  */
00118 #define  IEEE80211_STYPE_ASSOC_REQ    0x0000
00119 
00120 /** Subtype value for association-response management frames
00121  *
00122  * Association response frames are sent by the Access Point to confirm
00123  * or deny the association requested in an association request frame.
00124  */
00125 #define  IEEE80211_STYPE_ASSOC_RESP   0x0010
00126 
00127 /** Subtype value for reassociation-request management frames
00128  *
00129  * Reassociation request frames are sent by clients wishing to change
00130  * from one Access Point to another while roaming within the same
00131  * extended network (same ESSID).
00132  */
00133 #define  IEEE80211_STYPE_REASSOC_REQ  0x0020
00134 
00135 /** Subtype value for reassociation-response management frames
00136  *
00137  * Reassociation response frames are sent by the Access Point to
00138  * confirm or deny the swap requested in a reassociation request
00139  * frame.
00140  */
00141 #define  IEEE80211_STYPE_REASSOC_RESP 0x0030
00142 
00143 /** Subtype value for probe-request management frames
00144  *
00145  * Probe request frames are sent by clients to request that all Access
00146  * Points on the sending channel, or all belonging to a particular
00147  * ESSID, identify themselves by BSSID, supported transfer rates, RF
00148  * configuration, and other capabilities.
00149  */
00150 #define  IEEE80211_STYPE_PROBE_REQ    0x0040
00151 
00152 /** Subtype value for probe-response management frames
00153  *
00154  * Probe response frames are sent by Access Points in response to
00155  * probe request frames, providing the requested information.
00156  */
00157 #define  IEEE80211_STYPE_PROBE_RESP   0x0050
00158 
00159 /** Subtype value for beacon management frames
00160  *
00161  * Beacon frames are sent by Access Points at regular intervals,
00162  * usually ten per second, on the channel on which they communicate.
00163  * They can be used to probe passively for access points on a channel
00164  * where local regulatory restrictions prohibit active scanning, or
00165  * due to their regularity as a mechanism to determine the fraction of
00166  * packets that are being dropped.
00167  */
00168 #define  IEEE80211_STYPE_BEACON       0x0080
00169 
00170 /** Subtype value for disassociation management frames
00171  *
00172  * Disassociation frames are sent by either a client or an Access
00173  * Point to unequivocally terminate the association between the two.
00174  * They may be sent by clients upon leaving the network, or by an
00175  * Access Point upon reconfiguration, among other reasons; they are
00176  * usually more "polite" than deauthentication frames.
00177  */
00178 #define  IEEE80211_STYPE_DISASSOC     0x00A0
00179 
00180 /** Subtype value for authentication management frames
00181  *
00182  * Authentication frames are exchanged between a client and an Access
00183  * Point before association may be performed. Confusingly, in the most
00184  * common authentication method (Open System) no security tokens are
00185  * exchanged at all. Modern 802.11 security handshaking takes place
00186  * after association.
00187  */
00188 #define  IEEE80211_STYPE_AUTH         0x00B0
00189 
00190 /** Subtype value for deauthentication management frames
00191  *
00192  * Deauthentication frames are sent by either a client or an Access
00193  * Point to terminate the authentication (and therefore also the
00194  * association) between the two. They are generally more forceful than
00195  * disassociation frames, sent for such reasons as a failure to
00196  * set up security properly after associating.
00197  */
00198 #define  IEEE80211_STYPE_DEAUTH       0x00C0
00199 
00200 /** Subtype value for action management frames
00201  *
00202  * Action frames are used to implement spectrum management and QoS
00203  * features that iPXE currently does not support.
00204  */
00205 #define  IEEE80211_STYPE_ACTION       0x00D0
00206 
00207 
00208 /** Subtype value for RTS (request to send) control frames */
00209 #define  IEEE80211_STYPE_RTS          0x00B0
00210 
00211 /** Subtype value for CTS (clear to send) control frames */
00212 #define  IEEE80211_STYPE_CTS          0x00C0
00213 
00214 /** Subtype value for ACK (acknowledgement) control frames */
00215 #define  IEEE80211_STYPE_ACK          0x00D0
00216 
00217 
00218 /** Subtype value for ordinary data frames, with no QoS or CF add-ons */
00219 #define  IEEE80211_STYPE_DATA         0x0000
00220 
00221 /** Subtype value for data frames containing no data */
00222 #define  IEEE80211_STYPE_NODATA       0x0040
00223 
00224 
00225 /** 802.11 Frame Control field: To Data System flag
00226  *
00227  * This is set on data frames sent to an Access Point.
00228  */
00229 #define IEEE80211_FC_TODS       0x0100
00230 
00231 /** 802.11 Frame Control field: From Data System flag
00232  *
00233  * This is set on data frames sent from an Access Point. If both TODS
00234  * and FROMDS are set, the frame header is a 4-address format used for
00235  * inter-Access Point communication.
00236  */
00237 #define IEEE80211_FC_FROMDS     0x0200
00238 
00239 /** 802.11 Frame Control field: More Fragments flag */
00240 #define IEEE80211_FC_MORE_FRAG  0x0400
00241 
00242 /** 802.11 Frame Control field: Retransmission flag */
00243 #define IEEE80211_FC_RETRY      0x0800
00244 
00245 /** 802.11 Frame Control field: Power Managed flag
00246  *
00247  * This is set on any frame sent by a low-power station that will go
00248  * into a power-saving mode immediately after this frame. Access
00249  * Points are not allowed to act as low-power stations.
00250  */
00251 #define IEEE80211_FC_PWR_MGMT   0x1000
00252 
00253 /** 802.11 Frame Control field: More Data flag
00254  *
00255  * This is set on any frame sent by a station that has more data
00256  * queued to be sent than is in the frame.
00257  */
00258 #define IEEE80211_FC_MORE_DATA  0x2000
00259 
00260 /** 802.11 Frame Control field: Protected flag
00261  *
00262  * This is set on frames in which data is encrypted (by any method).
00263  */
00264 #define IEEE80211_FC_PROTECTED  0x4000
00265 
00266 /** 802.11 Frame Control field: Ordered flag [?] */
00267 #define IEEE80211_FC_ORDER      0x8000
00268 
00269 /** @} */
00270 
00271 
00272 /* ---------- Sequence Control defines ---------- */
00273 
00274 /**
00275  * @defgroup ieee80211_seq 802.11 Sequence Control field handling
00276  * @{
00277  */
00278 
00279 /** Extract sequence number from 802.11 Sequence Control field */
00280 #define IEEE80211_SEQNR( seq )          ( ( seq ) >> 4 )
00281 
00282 /** Extract fragment number from 802.11 Sequence Control field */
00283 #define IEEE80211_FRAG( seq )           ( ( seq ) & 0x000F )
00284 
00285 /** Make 802.11 Sequence Control field from sequence and fragment numbers */
00286 #define IEEE80211_MAKESEQ( seqnr, frag )        \
00287         ( ( ( ( seqnr ) & 0xFFF ) << 4 ) | ( ( frag ) & 0xF ) )
00288 
00289 /** @} */
00290 
00291 
00292 /* ---------- Frame header formats ---------- */
00293 
00294 /**
00295  * @defgroup ieee80211_hdr 802.11 frame header formats
00296  * @{
00297  */
00298 
00299 /** An 802.11 data or management frame without QoS or WDS header fields */
00300 struct ieee80211_frame
00301 {
00302         u16 fc;                 /**< 802.11 Frame Control field */
00303         u16 duration;           /**< Microseconds to reserve link */
00304         u8 addr1[ETH_ALEN];     /**< Address 1 (immediate receiver) */
00305         u8 addr2[ETH_ALEN];     /**< Address 2 (immediate sender) */
00306         u8 addr3[ETH_ALEN];     /**< Address 3 (often "forward to") */
00307         u16 seq;                /**< 802.11 Sequence Control field */
00308         u8 data[0];             /**< Beginning of frame data */
00309 } __attribute__((packed));
00310 
00311 /** The 802.2 LLC/SNAP header sent before actual data in a data frame
00312  *
00313  * This header is not acknowledged in the 802.11 standard at all; it
00314  * is treated just like data for MAC-layer purposes, including
00315  * fragmentation and encryption. It is actually two headers
00316  * concatenated: a three-byte 802.2 LLC header indicating Subnetwork
00317  * Accesss Protocol (SNAP) in both source and destination Service
00318  * Access Point (SAP) fields, and a five-byte SNAP header indicating a
00319  * zero OUI and two-byte Ethernet protocol type field.
00320  *
00321  * Thus, an eight-byte header in which six of the bytes are redundant.
00322  * Lovely, isn't it?
00323  */
00324 struct ieee80211_llc_snap_header
00325 {
00326         /* LLC part: */
00327         u8 dsap;                /**< Destination SAP ID */
00328         u8 ssap;                /**< Source SAP ID */
00329         u8 ctrl;                /**< Control information */
00330 
00331         /* SNAP part: */
00332         u8 oui[3];              /**< Organization code, usually 0 */
00333         u16 ethertype;          /**< Ethernet Type field */
00334 } __attribute__((packed));
00335 
00336 /** Value for DSAP field in 802.2 LLC header for 802.11 frames: SNAP */
00337 #define IEEE80211_LLC_DSAP      0xAA
00338 
00339 /** Value for SSAP field in 802.2 LLC header for 802.11 frames: SNAP */
00340 #define IEEE80211_LLC_SSAP      0xAA
00341 
00342 /** Value for control field in 802.2 LLC header for 802.11 frames
00343  *
00344  * "Unnumbered Information".
00345  */
00346 #define IEEE80211_LLC_CTRL      0x03
00347 
00348 
00349 /** 16-byte RTS frame format, with abbreviated header */
00350 struct ieee80211_rts
00351 {
00352         u16 fc;                 /**< 802.11 Frame Control field */
00353         u16 duration;           /**< Microseconds to reserve link */
00354         u8 addr1[ETH_ALEN];     /**< Address 1 (immediate receiver) */
00355         u8 addr2[ETH_ALEN];     /**< Address 2 (immediate sender) */
00356 } __attribute__((packed));
00357 
00358 /** Length of 802.11 RTS control frame */
00359 #define IEEE80211_RTS_LEN       16
00360 
00361 /** 10-byte CTS or ACK frame format, with abbreviated header */
00362 struct ieee80211_cts_or_ack
00363 {
00364         u16 fc;                 /**< 802.11 Frame Control field */
00365         u16 duration;           /**< Microseconds to reserve link */
00366         u8 addr1[ETH_ALEN];     /**< Address 1 (immediate receiver) */
00367 } __attribute__((packed));
00368 
00369 #define ieee80211_cts ieee80211_cts_or_ack
00370 #define ieee80211_ack ieee80211_cts_or_ack
00371 
00372 /** Length of 802.11 CTS control frame */
00373 #define IEEE80211_CTS_LEN       10
00374 
00375 /** Length of 802.11 ACK control frame */
00376 #define IEEE80211_ACK_LEN       10
00377 
00378 /** @} */
00379 
00380 
00381 /* ---------- Capability bits, status and reason codes ---------- */
00382 
00383 /**
00384  * @defgroup ieee80211_capab 802.11 management frame capability field bits
00385  * @{
00386  */
00387 
00388 /** Set if using an Access Point (managed mode) */
00389 #define IEEE80211_CAPAB_MANAGED       0x0001
00390 
00391 /** Set if operating in IBSS (no-AP, "Ad-Hoc") mode */
00392 #define IEEE80211_CAPAB_ADHOC         0x0002
00393 
00394 /** Set if we support Contention-Free Period operation */
00395 #define IEEE80211_CAPAB_CFPOLL        0x0004
00396 
00397 /** Set if we wish to be polled for Contention-Free operation */
00398 #define IEEE80211_CAPAB_CFPR          0x0008
00399 
00400 /** Set if the network is encrypted (by any method) */
00401 #define IEEE80211_CAPAB_PRIVACY       0x0010
00402 
00403 /** Set if PHY supports short preambles on 802.11b */
00404 #define IEEE80211_CAPAB_SHORT_PMBL    0x0020
00405 
00406 /** Set if PHY supports PBCC modulation */
00407 #define IEEE80211_CAPAB_PBCC          0x0040
00408 
00409 /** Set if we support Channel Agility */
00410 #define IEEE80211_CAPAB_CHAN_AGILITY  0x0080
00411 
00412 /** Set if we support spectrum management (DFS and TPC) on the 5GHz band */
00413 #define IEEE80211_CAPAB_SPECTRUM_MGMT 0x0100
00414 
00415 /** Set if we support Quality of Service enhancements */
00416 #define IEEE80211_CAPAB_QOS           0x0200
00417 
00418 /** Set if PHY supports short slot time on 802.11g */
00419 #define IEEE80211_CAPAB_SHORT_SLOT    0x0400
00420 
00421 /** Set if PHY supports APSD option */
00422 #define IEEE80211_CAPAB_APSD          0x0800
00423 
00424 /** Set if PHY supports DSSS/OFDM modulation (one way of 802.11 b/g mixing) */
00425 #define IEEE80211_CAPAB_DSSS_OFDM     0x2000
00426 
00427 /** Set if we support delayed block ACK */
00428 #define IEEE80211_CAPAB_DELAYED_BACK  0x4000
00429 
00430 /** Set if we support immediate block ACK */
00431 #define IEEE80211_CAPAB_IMMED_BACK    0x8000
00432 
00433 /** @} */
00434 
00435 
00436 /**
00437  * @defgroup ieee80211_status 802.11 status codes
00438  *
00439  * These are returned to indicate an immediate denial of
00440  * authentication or association. In iPXE, the lower 5 bits of the
00441  * status code are encoded into the file-unique portion of an error
00442  * code, the ERRFILE portion is always @c ERRFILE_net80211, and the
00443  * POSIX error code is @c ECONNREFUSED for status 0-31 or @c
00444  * EHOSTUNREACH for status 32-63.
00445  *
00446  * For a complete table with non-abbreviated error messages, see IEEE
00447  * Std 802.11-2007, Table 7-23, p.94.
00448  *
00449  * @{
00450  */
00451 
00452 #define IEEE80211_STATUS_SUCCESS                0
00453 #define IEEE80211_STATUS_FAILURE                1
00454 #define IEEE80211_STATUS_CAPAB_UNSUPP           10
00455 #define IEEE80211_STATUS_REASSOC_INVALID        11
00456 #define IEEE80211_STATUS_ASSOC_DENIED           12
00457 #define IEEE80211_STATUS_AUTH_ALGO_UNSUPP       13
00458 #define IEEE80211_STATUS_AUTH_SEQ_INVALID       14
00459 #define IEEE80211_STATUS_AUTH_CHALL_INVALID     15
00460 #define IEEE80211_STATUS_AUTH_TIMEOUT           16
00461 #define IEEE80211_STATUS_ASSOC_NO_ROOM          17
00462 #define IEEE80211_STATUS_ASSOC_NEED_RATE        18
00463 #define IEEE80211_STATUS_ASSOC_NEED_SHORT_PMBL  19
00464 #define IEEE80211_STATUS_ASSOC_NEED_PBCC        20
00465 #define IEEE80211_STATUS_ASSOC_NEED_CHAN_AGILITY 21
00466 #define IEEE80211_STATUS_ASSOC_NEED_SPECTRUM_MGMT 22
00467 #define IEEE80211_STATUS_ASSOC_BAD_POWER        23
00468 #define IEEE80211_STATUS_ASSOC_BAD_CHANNELS     24
00469 #define IEEE80211_STATUS_ASSOC_NEED_SHORT_SLOT  25
00470 #define IEEE80211_STATUS_ASSOC_NEED_DSSS_OFDM   26
00471 #define IEEE80211_STATUS_QOS_FAILURE            32
00472 #define IEEE80211_STATUS_QOS_NO_ROOM            33
00473 #define IEEE80211_STATUS_LINK_IS_HORRIBLE       34
00474 #define IEEE80211_STATUS_ASSOC_NEED_QOS         35
00475 #define IEEE80211_STATUS_REQUEST_DECLINED       37
00476 #define IEEE80211_STATUS_REQUEST_INVALID        38
00477 #define IEEE80211_STATUS_TS_NOT_CREATED_AGAIN   39
00478 #define IEEE80211_STATUS_INVALID_IE             40
00479 #define IEEE80211_STATUS_GROUP_CIPHER_INVALID   41
00480 #define IEEE80211_STATUS_PAIR_CIPHER_INVALID    42
00481 #define IEEE80211_STATUS_AKMP_INVALID           43
00482 #define IEEE80211_STATUS_RSN_VERSION_UNSUPP     44
00483 #define IEEE80211_STATUS_RSN_CAPAB_INVALID      45
00484 #define IEEE80211_STATUS_CIPHER_REJECTED        46
00485 #define IEEE80211_STATUS_TS_NOT_CREATED_WAIT    47
00486 #define IEEE80211_STATUS_DIRECT_LINK_FORBIDDEN  48
00487 #define IEEE80211_STATUS_DEST_NOT_PRESENT       49
00488 #define IEEE80211_STATUS_DEST_NOT_QOS           50
00489 #define IEEE80211_STATUS_ASSOC_LISTEN_TOO_HIGH  51
00490 
00491 /** @} */
00492 
00493 
00494 
00495 /**
00496  * @defgroup ieee80211_reason 802.11 reason codes
00497  *
00498  * These are returned to indicate the reason for a deauthentication or
00499  * disassociation sent (usually) after authentication or association
00500  * had succeeded.  In iPXE, the lower 5 bits of the reason code are
00501  * encoded into the file-unique portion of an error code, the ERRFILE
00502  * portion is always @c ERRFILE_net80211, and the POSIX error code is
00503  * @c ECONNRESET for reason 0-31 or @c ENETRESET for reason 32-63.
00504  *
00505  * For a complete table with non-abbreviated error messages, see IEEE
00506  * Std 802.11-2007, Table 7-22, p.92.
00507  *
00508  * @{
00509  */
00510 
00511 #define IEEE80211_REASON_NONE                   0
00512 #define IEEE80211_REASON_UNSPECIFIED            1
00513 #define IEEE80211_REASON_AUTH_NO_LONGER_VALID   2
00514 #define IEEE80211_REASON_LEAVING                3
00515 #define IEEE80211_REASON_INACTIVITY             4
00516 #define IEEE80211_REASON_OUT_OF_RESOURCES       5
00517 #define IEEE80211_REASON_NEED_AUTH              6
00518 #define IEEE80211_REASON_NEED_ASSOC             7
00519 #define IEEE80211_REASON_LEAVING_TO_ROAM        8
00520 #define IEEE80211_REASON_REASSOC_INVALID        9
00521 #define IEEE80211_REASON_BAD_POWER              10
00522 #define IEEE80211_REASON_BAD_CHANNELS           11
00523 #define IEEE80211_REASON_INVALID_IE             13
00524 #define IEEE80211_REASON_MIC_FAILURE            14
00525 #define IEEE80211_REASON_4WAY_TIMEOUT           15
00526 #define IEEE80211_REASON_GROUPKEY_TIMEOUT       16
00527 #define IEEE80211_REASON_4WAY_INVALID           17
00528 #define IEEE80211_REASON_GROUP_CIPHER_INVALID   18
00529 #define IEEE80211_REASON_PAIR_CIPHER_INVALID    19
00530 #define IEEE80211_REASON_AKMP_INVALID           20
00531 #define IEEE80211_REASON_RSN_VERSION_INVALID    21
00532 #define IEEE80211_REASON_RSN_CAPAB_INVALID      22
00533 #define IEEE80211_REASON_8021X_FAILURE          23
00534 #define IEEE80211_REASON_CIPHER_REJECTED        24
00535 #define IEEE80211_REASON_QOS_UNSPECIFIED        32
00536 #define IEEE80211_REASON_QOS_OUT_OF_RESOURCES   33
00537 #define IEEE80211_REASON_LINK_IS_HORRIBLE       34
00538 #define IEEE80211_REASON_INVALID_TXOP           35
00539 #define IEEE80211_REASON_REQUESTED_LEAVING      36
00540 #define IEEE80211_REASON_REQUESTED_NO_USE       37
00541 #define IEEE80211_REASON_REQUESTED_NEED_SETUP   38
00542 #define IEEE80211_REASON_REQUESTED_TIMEOUT      39
00543 #define IEEE80211_REASON_CIPHER_UNSUPPORTED     45
00544 
00545 /** @} */
00546 
00547 /* ---------- Information element declarations ---------- */
00548 
00549 /**
00550  * @defgroup ieee80211_ie 802.11 information elements
00551  *
00552  * Many management frames include a section that amounts to a
00553  * concatenation of these information elements, so that the sender can
00554  * choose which information to send and the receiver can ignore the
00555  * parts it doesn't understand. Each IE contains a two-byte header,
00556  * one byte ID and one byte length, followed by IE-specific data. The
00557  * length does not include the two-byte header. Information elements
00558  * are required to be sorted by ID, but iPXE does not require that in
00559  * those it receives.
00560  *
00561  * This group also includes a few inline functions to simplify common
00562  * tasks in IE processing.
00563  *
00564  * @{
00565  */
00566 
00567 /** Generic 802.11 information element header */
00568 struct ieee80211_ie_header {
00569         u8 id;                  /**< Information element ID */
00570         u8 len;                 /**< Information element length */
00571 } __attribute__ ((packed));
00572 
00573 
00574 /** 802.11 SSID information element */
00575 struct ieee80211_ie_ssid {
00576         u8 id;                  /**< SSID ID: 0 */
00577         u8 len;                 /**< SSID length */
00578         char ssid[0];           /**< SSID data, not NUL-terminated */
00579 } __attribute__ ((packed));
00580 
00581 /** Information element ID for SSID information element */
00582 #define IEEE80211_IE_SSID       0
00583 
00584 
00585 /** 802.11 rates information element
00586  *
00587  * The first 8 rates go in an IE of type RATES (1), and any more rates
00588  * go in one of type EXT_RATES (50). Each rate is a byte with the low
00589  * 7 bits equal to the rate in units of 500 kbps, and the high bit set
00590  * if and only if the rate is "basic" (must be supported by all
00591  * connected stations).
00592  */
00593 struct ieee80211_ie_rates {
00594         u8 id;                  /**< Rates ID: 1 or 50 */
00595         u8 len;                 /**< Number of rates */
00596         u8 rates[0];            /**< Rates data, one rate per byte */
00597 } __attribute__ ((packed));
00598 
00599 /** Information element ID for rates information element */
00600 #define IEEE80211_IE_RATES      1
00601 
00602 /** Information element ID for extended rates information element */
00603 #define IEEE80211_IE_EXT_RATES  50
00604 
00605 
00606 /** 802.11 Direct Spectrum parameter information element
00607  *
00608  * This just contains the channel number. It has the fancy name
00609  * because IEEE 802.11 also defines a frequency-hopping PHY that
00610  * changes channels at regular intervals following a predetermined
00611  * pattern; in practice nobody uses the FH PHY.
00612  */
00613 struct ieee80211_ie_ds_param {
00614         u8 id;                  /**< DS parameter ID: 3 */
00615         u8 len;                 /**< DS parameter length: 1 */
00616         u8 current_channel;     /**< Current channel number, 1-14 */
00617 } __attribute__ ((packed));
00618 
00619 /** Information element ID for Direct Spectrum parameter information element */
00620 #define IEEE80211_IE_DS_PARAM   3
00621 
00622 
00623 /** 802.11 Country information element regulatory extension triplet */
00624 struct ieee80211_ie_country_ext_triplet {
00625         u8 reg_ext_id;          /**< Regulatory extension ID */
00626         u8 reg_class_id;        /**< Regulatory class ID */
00627         u8 coverage_class;      /**< Coverage class */
00628 } __attribute__ ((packed));
00629 
00630 /** 802.11 Country information element regulatory band triplet */
00631 struct ieee80211_ie_country_band_triplet {
00632         u8 first_channel;       /**< Channel number for first channel in band */
00633         u8 nr_channels;         /**< Number of contiguous channels in band */
00634         u8 max_txpower;         /**< Maximum TX power in dBm */
00635 } __attribute__ ((packed));
00636 
00637 /** 802.11 Country information element regulatory triplet
00638  *
00639  * It is a band triplet if the first byte is 200 or less, and a
00640  * regulatory extension triplet otherwise.
00641  */
00642 union ieee80211_ie_country_triplet {
00643         /** Differentiator between band and ext triplets */
00644         u8 first;
00645 
00646         /** Information about a band of channels */
00647         struct ieee80211_ie_country_band_triplet band;
00648 
00649         /** Regulatory extension information */
00650         struct ieee80211_ie_country_ext_triplet ext;
00651 };
00652 
00653 /** 802.11 Country information element
00654  *
00655  * This contains some data about RF regulations.
00656  */
00657 struct ieee80211_ie_country {
00658         u8 id;                  /**< Country information ID: 7 */
00659         u8 len;                 /**< Country information length: varies */
00660         char name[2];           /**< ISO Alpha2 country code */
00661         char in_out;            /**< 'I' for indoor, 'O' for outdoor */
00662 
00663         /** List of regulatory triplets */
00664         union ieee80211_ie_country_triplet triplet[0];
00665 } __attribute__ ((packed));
00666 
00667 /** Information element ID for Country information element */
00668 #define IEEE80211_IE_COUNTRY    7
00669 
00670 
00671 /** 802.11 Request information element
00672  *
00673  * This contains a list of information element types we would like to
00674  * be included in probe response frames.
00675  */
00676 struct ieee80211_ie_request {
00677         u8 id;                  /**< Request ID: 10 */
00678         u8 len;                 /**< Number of IEs requested */
00679         u8 request[0];          /**< List of IEs requested */
00680 } __attribute__ ((packed));
00681 
00682 /** Information element ID for Request information element */
00683 #define IEEE80211_IE_REQUEST    10
00684 
00685 
00686 /** 802.11 Challenge Text information element
00687  *
00688  * This is used in authentication frames under Shared Key
00689  * authentication.
00690  */
00691 struct ieee80211_ie_challenge_text {
00692         u8 id;                  /**< Challenge Text ID: 16 */
00693         u8 len;                 /**< Challenge Text length: usually 128 */
00694         u8 challenge_text[0];   /**< Challenge Text data */
00695 } __attribute__ ((packed));
00696 
00697 /** Information element ID for Challenge Text information element */
00698 #define IEEE80211_IE_CHALLENGE_TEXT     16
00699 
00700 
00701 /** 802.11 Power Constraint information element
00702  *
00703  * This is used to specify an additional power limitation on top of
00704  * the Country requirements.
00705  */
00706 struct ieee80211_ie_power_constraint {
00707         u8 id;                  /**< Power Constraint ID: 52 */
00708         u8 len;                 /**< Power Constraint length: 1 */
00709         u8 power_constraint;    /**< Decrease in allowed TX power, dBm */
00710 } __attribute__ ((packed));
00711 
00712 /** Information element ID for Power Constraint information element */
00713 #define IEEE80211_IE_POWER_CONSTRAINT   52
00714 
00715 
00716 /** 802.11 Power Capability information element
00717  *
00718  * This is used in association request frames to indicate the extremes
00719  * of our TX power abilities. It is required only if we indicate
00720  * support for spectrum management.
00721  */
00722 struct ieee80211_ie_power_capab {
00723         u8 id;                  /**< Power Capability ID: 33 */
00724         u8 len;                 /**< Power Capability length: 2 */
00725         u8 min_txpower;         /**< Minimum possible TX power, dBm */
00726         u8 max_txpower;         /**< Maximum possible TX power, dBm */
00727 } __attribute__ ((packed));
00728 
00729 /** Information element ID for Power Capability information element */
00730 #define IEEE80211_IE_POWER_CAPAB        33
00731 
00732 
00733 /** 802.11 Channels information element channel band tuple */
00734 struct ieee80211_ie_channels_channel_band {
00735         u8 first_channel;       /**< Channel number of first channel in band */
00736         u8 nr_channels;         /**< Number of channels in band */
00737 } __attribute__ ((packed));
00738 
00739 /** 802.11 Channels information element
00740  *
00741  * This is used in association frames to indicate the channels we can
00742  * use. It is required only if we indicate support for spectrum
00743  * management.
00744  */
00745 struct ieee80211_ie_channels {
00746         u8 id;                  /**< Channels ID: 36 */
00747         u8 len;                 /**< Channels length: 2 */
00748 
00749         /** List of (start, length) channel bands we can use */
00750         struct ieee80211_ie_channels_channel_band channels[0];
00751 } __attribute__ ((packed));
00752 
00753 /** Information element ID for Channels information element */
00754 #define IEEE80211_IE_CHANNELS   36
00755 
00756 
00757 /** 802.11 ERP Information information element
00758  *
00759  * This is used to communicate some PHY-level flags.
00760  */
00761 struct ieee80211_ie_erp_info {
00762         u8 id;                  /**< ERP Information ID: 42 */
00763         u8 len;                 /**< ERP Information length: 1 */
00764         u8 erp_info;            /**< ERP flags */
00765 } __attribute__ ((packed));
00766 
00767 /** Information element ID for ERP Information information element */
00768 #define IEEE80211_IE_ERP_INFO   42
00769 
00770 /** ERP information element: Flag set if 802.11b stations are present */
00771 #define  IEEE80211_ERP_NONERP_PRESENT   0x01
00772 
00773 /** ERP information element: Flag set if CTS protection must be used */
00774 #define  IEEE80211_ERP_USE_PROTECTION   0x02
00775 
00776 /** ERP information element: Flag set if long preambles must be used */
00777 #define  IEEE80211_ERP_BARKER_LONG      0x04
00778 
00779 
00780 /** 802.11 Robust Security Network ("WPA") information element
00781  *
00782  * Showing once again a striking clarity of design, the IEEE folks put
00783  * dynamically-sized data in the middle of this structure. As such,
00784  * the below structure definition only works for IEs we create
00785  * ourselves, which always have one pairwise cipher and one AKM;
00786  * received IEs should be parsed piecemeal.
00787  *
00788  * Also inspired was IEEE's choice of 16-bit fields to count the
00789  * number of 4-byte elements in a structure with a maximum length of
00790  * 255 bytes.
00791  *
00792  * Many fields reference a cipher or authentication-type ID; this is a
00793  * three-byte OUI followed by one byte identifying the cipher with
00794  * respect to that OUI. For all standard ciphers the OUI is 00:0F:AC,
00795  * except in old-style WPA IEs encapsulated in vendor-specific IEs,
00796  * where it's 00:50:F2.
00797  */
00798 struct ieee80211_ie_rsn {
00799         /** Information element ID */
00800         u8 id;
00801 
00802         /** Information element length */
00803         u8 len;
00804 
00805         /** RSN information element version */
00806         u16 version;
00807 
00808         /** Cipher ID for the cipher used in multicast/broadcast frames */
00809         u32 group_cipher;
00810 
00811         /** Number of unicast ciphers supported */
00812         u16 pairwise_count;
00813 
00814         /** List of cipher IDs for supported unicast frame ciphers */
00815         u32 pairwise_cipher[1];
00816 
00817         /** Number of authentication types supported */
00818         u16 akm_count;
00819 
00820         /** List of authentication type IDs for supported types */
00821         u32 akm_list[1];
00822 
00823         /** Security capabilities field (RSN only) */
00824         u16 rsn_capab;
00825 
00826         /** Number of PMKIDs included (present only in association frames) */
00827         u16 pmkid_count;
00828 
00829         /** List of PMKIDs included, each a 16-byte SHA1 hash */
00830         u8 pmkid_list[0];
00831 } __attribute__((packed));
00832 
00833 /** Information element ID for Robust Security Network information element */
00834 #define IEEE80211_IE_RSN        48
00835 
00836 /** Calculate necessary size of RSN information element
00837  *
00838  * @v npair     Number of pairwise ciphers supported
00839  * @v nauth     Number of authentication types supported
00840  * @v npmkid    Number of PMKIDs to include
00841  * @v is_rsn    If TRUE, calculate RSN IE size; if FALSE, calculate WPA IE size
00842  * @ret size    Necessary size of IE, including header bytes
00843  */
00844 static inline size_t ieee80211_rsn_size ( int npair, int nauth, int npmkid,
00845                                           int rsn_ie ) {
00846         return 16 + 4 * ( npair + nauth ) + 16 * npmkid - 4 * ! rsn_ie;
00847 }
00848 
00849 /** Make OUI plus type byte into 32-bit integer for easy comparison */
00850 #if __BYTE_ORDER == __BIG_ENDIAN
00851 #define _MKOUI( a, b, c, t )    \
00852                 ( ( ( a ) << 24 ) | ( ( b ) << 16 ) | ( ( c ) << 8 ) | ( d ) )
00853 #define  OUI_ORG_MASK           0xFFFFFF00
00854 #define  OUI_TYPE_MASK          0x000000FF
00855 #else
00856 #define _MKOUI( a, b, c, t )    \
00857                 ( ( ( t ) << 24 ) | ( ( c ) << 16 ) | ( ( b ) << 8 ) | ( a ) )
00858 #define  OUI_ORG_MASK           0x00FFFFFF
00859 #define  OUI_TYPE_MASK          0xFF000000
00860 #endif
00861 
00862 /** Organization part for OUIs in standard RSN IE */
00863 #define  IEEE80211_RSN_OUI      _MKOUI ( 0x00, 0x0F, 0xAC, 0 )
00864 
00865 /** Organization part for OUIs in old WPA IE */
00866 #define  IEEE80211_WPA_OUI      _MKOUI ( 0x00, 0x50, 0xF2, 0 )
00867 
00868 /** Old vendor-type WPA IE OUI type + subtype */
00869 #define  IEEE80211_WPA_OUI_VEN  _MKOUI ( 0x00, 0x50, 0xF2, 0x01 )
00870 
00871 
00872 /** 802.11 RSN IE: expected version number */
00873 #define  IEEE80211_RSN_VERSION          1
00874 
00875 /** 802.11 RSN IE: cipher type for 40-bit WEP */
00876 #define  IEEE80211_RSN_CTYPE_WEP40      _MKOUI ( 0, 0, 0, 0x01 )
00877 
00878 /** 802.11 RSN IE: cipher type for 104-bit WEP */
00879 #define  IEEE80211_RSN_CTYPE_WEP104     _MKOUI ( 0, 0, 0, 0x05 )
00880 
00881 /** 802.11 RSN IE: cipher type for TKIP ("WPA") */
00882 #define  IEEE80211_RSN_CTYPE_TKIP       _MKOUI ( 0, 0, 0, 0x02 )
00883 
00884 /** 802.11 RSN IE: cipher type for CCMP ("WPA2") */
00885 #define  IEEE80211_RSN_CTYPE_CCMP       _MKOUI ( 0, 0, 0, 0x04 )
00886 
00887 /** 802.11 RSN IE: cipher type for "use group"
00888  *
00889  * This can only appear as a pairwise cipher, and means unicast frames
00890  * should be encrypted in the same way as broadcast/multicast frames.
00891  */
00892 #define  IEEE80211_RSN_CTYPE_USEGROUP   _MKOUI ( 0, 0, 0, 0x00 )
00893 
00894 /** 802.11 RSN IE: auth method type for using an 802.1X server */
00895 #define  IEEE80211_RSN_ATYPE_8021X      _MKOUI ( 0, 0, 0, 0x01 )
00896 
00897 /** 802.11 RSN IE: auth method type for using a pre-shared key */
00898 #define  IEEE80211_RSN_ATYPE_PSK        _MKOUI ( 0, 0, 0, 0x02 )
00899 
00900 /** 802.11 RSN IE capabilities: AP supports pre-authentication */
00901 #define  IEEE80211_RSN_CAPAB_PREAUTH    0x001
00902 
00903 /** 802.11 RSN IE capabilities: Node has conflict between TKIP and WEP
00904  *
00905  * This is a legacy issue; APs always set it to 0, and iPXE sets it to
00906  * 0.
00907  */
00908 #define  IEEE80211_RSN_CAPAB_NO_PAIRWISE 0x002
00909 
00910 /** 802.11 RSN IE capabilities: Number of PTKSA replay counters
00911  *
00912  * A value of 0 means one replay counter, 1 means two, 2 means four,
00913  * and 3 means sixteen.
00914  */
00915 #define  IEEE80211_RSN_CAPAB_PTKSA_REPLAY 0x00C
00916 
00917 /** 802.11 RSN IE capabilities: Number of GTKSA replay counters
00918  *
00919  * A value of 0 means one replay counter, 1 means two, 2 means four,
00920  * and 3 means sixteen.
00921  */
00922 #define  IEEE80211_RSN_CAPAB_GTKSA_REPLAY 0x030
00923 
00924 /** 802.11 RSN IE capabilities: PeerKey Handshaking is suported */
00925 #define  IEEE80211_RSN_CAPAB_PEERKEY    0x200
00926 
00927 
00928 /** 802.11 RSN IE capabilities: One replay counter
00929  *
00930  * This should be AND'ed with @c IEEE80211_RSN_CAPAB_PTKSA_REPLAY or
00931  * @c IEEE80211_RSN_CAPAB_GTKSA_REPLAY (or both) to produce a value
00932  * which can be OR'ed into the capabilities field.
00933  */
00934 #define IEEE80211_RSN_1_CTR             0x000
00935 
00936 /** 802.11 RSN IE capabilities: Two replay counters */
00937 #define IEEE80211_RSN_2_CTR             0x014
00938 
00939 /** 802.11 RSN IE capabilities: Four replay counters */
00940 #define IEEE80211_RSN_4_CTR             0x028
00941 
00942 /** 802.11 RSN IE capabilities: 16 replay counters */
00943 #define IEEE80211_RSN_16_CTR            0x03C
00944 
00945 
00946 /** 802.11 Vendor Specific information element
00947  *
00948  * One often sees the RSN IE masquerading as vendor-specific on
00949  * devices that were produced prior to 802.11i (the WPA amendment)
00950  * being finalized.
00951  */
00952 struct ieee80211_ie_vendor {
00953         u8 id;                  /**< Vendor-specific ID: 221 */
00954         u8 len;                 /**< Vendor-specific length: variable */
00955         u32 oui;                /**< OUI and vendor-specific type byte */
00956         u8 data[0];             /**< Vendor-specific data */
00957 } __attribute__ ((packed));
00958 
00959 /** Information element ID for Vendor Specific information element */
00960 #define IEEE80211_IE_VENDOR     221
00961 
00962 
00963 
00964 
00965 /** Any 802.11 information element
00966  *
00967  * This is formatted for ease of use, so IEs with complex structures
00968  * get referenced in full, while those with only one byte of data or a
00969  * simple array are pulled in to avoid a layer of indirection like
00970  * ie->channels.channels[0].
00971  */
00972 union ieee80211_ie
00973 {
00974         /** Generic and simple information element info */
00975         struct {
00976                 u8 id;          /**< Information element ID */
00977                 u8 len;         /**< Information element data length */
00978                 union {
00979                         char ssid[0];   /**< SSID text */
00980                         u8 rates[0];    /**< Rates data */
00981                         u8 request[0];  /**< Request list */
00982                         u8 challenge_text[0]; /**< Challenge text data */
00983                         u8 power_constraint; /**< Power constraint, dBm */
00984                         u8 erp_info;    /**< ERP information flags */
00985                         /** List of channels */
00986                         struct ieee80211_ie_channels_channel_band channels[0];
00987                 };
00988         };
00989 
00990         /** DS parameter set */
00991         struct ieee80211_ie_ds_param ds_param;
00992 
00993         /** Country information */
00994         struct ieee80211_ie_country country;
00995 
00996         /** Power capability */
00997         struct ieee80211_ie_power_capab power_capab;
00998 
00999         /** Security information */
01000         struct ieee80211_ie_rsn rsn;
01001 
01002         /** Vendor-specific */
01003         struct ieee80211_ie_vendor vendor;
01004 };
01005 
01006 /** Check that 802.11 information element is bounded by buffer
01007  *
01008  * @v ie        Information element
01009  * @v end       End of buffer in which information element is stored
01010  * @ret ok      TRUE if the IE is completely contained within the buffer
01011  */
01012 static inline int ieee80211_ie_bound ( union ieee80211_ie *ie, void *end )
01013 {
01014         void *iep = ie;
01015         return ( iep + 2 <= end && iep + 2 + ie->len <= end );
01016 }
01017 
01018 /** Advance to next 802.11 information element
01019  *
01020  * @v ie        Current information element pointer
01021  * @v end       Pointer to first byte not in information element space
01022  * @ret next    Pointer to next information element, or NULL if no more
01023  *
01024  * When processing received IEs, @a end should be set to the I/O
01025  * buffer tail pointer; when marshalling IEs for sending, @a end
01026  * should be NULL.
01027  */
01028 static inline union ieee80211_ie * ieee80211_next_ie ( union ieee80211_ie *ie,
01029                                                        void *end )
01030 {
01031         void *next_ie_byte = ( void * ) ie + ie->len + 2;
01032         union ieee80211_ie *next_ie = next_ie_byte;
01033 
01034         if ( ! end )
01035                 return next_ie;
01036 
01037         if ( ieee80211_ie_bound ( next_ie, end ) )
01038                 return next_ie;
01039 
01040         return NULL;
01041 }
01042 
01043 /** @} */
01044 
01045 
01046 /* ---------- Management frame data formats ---------- */
01047 
01048 /**
01049  * @defgroup ieee80211_mgmt_data Management frame data payloads
01050  * @{
01051  */
01052 
01053 /** Beacon or probe response frame data */
01054 struct ieee80211_beacon_or_probe_resp
01055 {
01056         /** 802.11 TSFT value at frame send */
01057         u64 timestamp;
01058 
01059         /** Interval at which beacons are sent, in units of 1024 us */
01060         u16 beacon_interval;
01061 
01062         /** Capability flags */
01063         u16 capability;
01064 
01065         /** List of information elements */
01066         union ieee80211_ie info_element[0];
01067 } __attribute__((packed));
01068 
01069 #define ieee80211_beacon        ieee80211_beacon_or_probe_resp
01070 #define ieee80211_probe_resp    ieee80211_beacon_or_probe_resp
01071 
01072 /** Disassociation or deauthentication frame data */
01073 struct ieee80211_disassoc_or_deauth
01074 {
01075         /** Reason code */
01076         u16 reason;
01077 } __attribute__((packed));
01078 
01079 #define ieee80211_disassoc      ieee80211_disassoc_or_deauth
01080 #define ieee80211_deauth        ieee80211_disassoc_or_deauth
01081 
01082 /** Association request frame data */
01083 struct ieee80211_assoc_req
01084 {
01085         /** Capability flags */
01086         u16 capability;
01087 
01088         /** Interval at which we wake up, in units of the beacon interval */
01089         u16 listen_interval;
01090 
01091         /** List of information elements */
01092         union ieee80211_ie info_element[0];
01093 } __attribute__((packed));
01094 
01095 /** Association or reassociation response frame data */
01096 struct ieee80211_assoc_or_reassoc_resp
01097 {
01098         /** Capability flags */
01099         u16 capability;
01100 
01101         /** Status code */
01102         u16 status;
01103 
01104         /** Association ID */
01105         u16 aid;
01106 
01107         /** List of information elements */
01108         union ieee80211_ie info_element[0];
01109 } __attribute__((packed));
01110 
01111 #define ieee80211_assoc_resp    ieee80211_assoc_or_reassoc_resp
01112 #define ieee80211_reassoc_resp  ieee80211_assoc_or_reassoc_resp
01113 
01114 /** Reassociation request frame data */
01115 struct ieee80211_reassoc_req
01116 {
01117         /** Capability flags */
01118         u16 capability;
01119 
01120         /** Interval at which we wake up, in units of the beacon interval */
01121         u16 listen_interval;
01122 
01123         /** MAC address of current Access Point */
01124         u8 current_addr[ETH_ALEN];
01125 
01126         /** List of information elements */
01127         union ieee80211_ie info_element[0];
01128 } __attribute__((packed));
01129 
01130 /** Probe request frame data */
01131 struct ieee80211_probe_req
01132 {
01133         /** List of information elements */
01134         union ieee80211_ie info_element[0];
01135 } __attribute__((packed));
01136 
01137 /** Authentication frame data */
01138 struct ieee80211_auth
01139 {
01140         /** Authentication algorithm (Open System or Shared Key) */
01141         u16 algorithm;
01142 
01143         /** Sequence number of this frame; first from client to AP is 1 */
01144         u16 tx_seq;
01145 
01146         /** Status code */
01147         u16 status;
01148 
01149         /** List of information elements */
01150         union ieee80211_ie info_element[0];
01151 } __attribute__((packed));
01152 
01153 /** Open System authentication algorithm */
01154 #define IEEE80211_AUTH_OPEN_SYSTEM  0
01155 
01156 /** Shared Key authentication algorithm */
01157 #define IEEE80211_AUTH_SHARED_KEY   1
01158 
01159 /** @} */
01160 
01161 #endif