ieee80211.h

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

Generated on Tue Apr 6 20:01:08 2010 for gPXE by  doxygen 1.5.7.1