| #ifndef _GPXE_IEEE80211_H |
| #define _GPXE_IEEE80211_H |
| |
| #include <gpxe/if_ether.h> /* for ETH_ALEN */ |
| #include <endian.h> |
| |
| /** @file |
| * Constants and data structures defined in IEEE 802.11, subsetted |
| * according to what gPXE knows how to use. |
| */ |
| |
| FILE_LICENCE(GPL2_OR_LATER); |
| |
| /* ---------- Maximum lengths of things ---------- */ |
| |
| /** |
| * @defgroup ieee80211_maxlen Maximum lengths in the 802.11 protocol |
| * @{ |
| */ |
| |
| /** Maximum length of frame payload |
| * |
| * This does not include cryptographic overhead, which can be up to 20 |
| * bytes, but it DOES include the 802.2 LLC/SNAP headers that are used |
| * on data frames (but not management frames). |
| */ |
| #define IEEE80211_MAX_DATA_LEN 2304 |
| |
| /** Length of LLC/SNAP headers on data frames */ |
| #define IEEE80211_LLC_HEADER_LEN 8 |
| |
| /** Maximum cryptographic overhead before encrypted data */ |
| #define IEEE80211_MAX_CRYPTO_HEADER 8 |
| |
| /** Maximum cryptographic overhead after encrypted data |
| * |
| * This does not count the MIC in TKIP frames, since that is |
| * considered to be part of the MSDU and thus contributes to the size |
| * of the data field. |
| * |
| * It @e does count the MIC in CCMP frames, which is considered part |
| * of the MPDU (outside the data field). |
| */ |
| #define IEEE80211_MAX_CRYPTO_TRAILER 8 |
| |
| /** Total maximum cryptographic overhead */ |
| #define IEEE80211_MAX_CRYPTO_OVERHEAD 16 |
| |
| /** Bytes of network-layer data that can go into a regular data frame */ |
| #define IEEE80211_MAX_FRAME_DATA 2296 |
| |
| /** Frame header length for frames we might work with |
| * |
| * QoS adds a two-byte field on top of this, and APs communicating |
| * with each other in Wireless Distribution System (WDS) mode add an |
| * extra 6-byte MAC address field, but we do not work with such |
| * frames. |
| */ |
| #define IEEE80211_TYP_FRAME_HEADER_LEN 24 |
| |
| /** Theoretical maximum frame header length |
| * |
| * This includes the QoS and WDS Addr4 fields that we should never |
| * see. |
| */ |
| #define IEEE80211_MAX_FRAME_HEADER_LEN 32 |
| |
| /** Maximum combined frame length |
| * |
| * The biggest frame will include 32 frame header bytes, 16 bytes of |
| * crypto overhead, and 2304 data bytes. |
| */ |
| #define IEEE80211_MAX_FRAME_LEN 2352 |
| |
| /** Maximum length of an ESSID */ |
| #define IEEE80211_MAX_SSID_LEN 32 |
| |
| /** @} */ |
| |
| |
| /* ---------- Frame Control defines ---------- */ |
| |
| /** |
| * @defgroup ieee80211_fc 802.11 Frame Control field bits |
| * @{ |
| */ |
| |
| /** 802.11 Frame Control field, Version bitmask */ |
| #define IEEE80211_FC_VERSION 0x0003 |
| |
| /** Expected value of Version bits in Frame Control */ |
| #define IEEE80211_THIS_VERSION 0x0000 |
| |
| |
| /** 802.11 Frame Control field, Frame Type bitmask */ |
| #define IEEE80211_FC_TYPE 0x000C |
| |
| /** Type value for management (layer-2) frames */ |
| #define IEEE80211_TYPE_MGMT 0x0000 |
| |
| /** Type value for control (layer-1, hardware-managed) frames */ |
| #define IEEE80211_TYPE_CTRL 0x0004 |
| |
| /** Type value for data frames */ |
| #define IEEE80211_TYPE_DATA 0x0008 |
| |
| |
| /** 802.11 Frame Control field, Frame Subtype bitmask */ |
| #define IEEE80211_FC_SUBTYPE 0x00F0 |
| |
| /** Subtype value for association-request management frames |
| * |
| * Association request frames are sent after authentication from the |
| * client to the Access Point to establish the client as part of the |
| * Access Point's network. |
| */ |
| #define IEEE80211_STYPE_ASSOC_REQ 0x0000 |
| |
| /** Subtype value for association-response management frames |
| * |
| * Association response frames are sent by the Access Point to confirm |
| * or deny the association requested in an association request frame. |
| */ |
| #define IEEE80211_STYPE_ASSOC_RESP 0x0010 |
| |
| /** Subtype value for reassociation-request management frames |
| * |
| * Reassociation request frames are sent by clients wishing to change |
| * from one Access Point to another while roaming within the same |
| * extended network (same ESSID). |
| */ |
| #define IEEE80211_STYPE_REASSOC_REQ 0x0020 |
| |
| /** Subtype value for reassociation-response management frames |
| * |
| * Reassociation response frames are sent by the Access Point to |
| * confirm or deny the swap requested in a reassociation request |
| * frame. |
| */ |
| #define IEEE80211_STYPE_REASSOC_RESP 0x0030 |
| |
| /** Subtype value for probe-request management frames |
| * |
| * Probe request frames are sent by clients to request that all Access |
| * Points on the sending channel, or all belonging to a particular |
| * ESSID, identify themselves by BSSID, supported transfer rates, RF |
| * configuration, and other capabilities. |
| */ |
| #define IEEE80211_STYPE_PROBE_REQ 0x0040 |
| |
| /** Subtype value for probe-response management frames |
| * |
| * Probe response frames are sent by Access Points in response to |
| * probe request frames, providing the requested information. |
| */ |
| #define IEEE80211_STYPE_PROBE_RESP 0x0050 |
| |
| /** Subtype value for beacon management frames |
| * |
| * Beacon frames are sent by Access Points at regular intervals, |
| * usually ten per second, on the channel on which they communicate. |
| * They can be used to probe passively for access points on a channel |
| * where local regulatory restrictions prohibit active scanning, or |
| * due to their regularity as a mechanism to determine the fraction of |
| * packets that are being dropped. |
| */ |
| #define IEEE80211_STYPE_BEACON 0x0080 |
| |
| /** Subtype value for disassociation management frames |
| * |
| * Disassociation frames are sent by either a client or an Access |
| * Point to unequivocally terminate the association between the two. |
| * They may be sent by clients upon leaving the network, or by an |
| * Access Point upon reconfiguration, among other reasons; they are |
| * usually more "polite" than deauthentication frames. |
| */ |
| #define IEEE80211_STYPE_DISASSOC 0x00A0 |
| |
| /** Subtype value for authentication management frames |
| * |
| * Authentication frames are exchanged between a client and an Access |
| * Point before association may be performed. Confusingly, in the most |
| * common authentication method (Open System) no security tokens are |
| * exchanged at all. Modern 802.11 security handshaking takes place |
| * after association. |
| */ |
| #define IEEE80211_STYPE_AUTH 0x00B0 |
| |
| /** Subtype value for deauthentication management frames |
| * |
| * Deauthentication frames are sent by either a client or an Access |
| * Point to terminate the authentication (and therefore also the |
| * association) between the two. They are generally more forceful than |
| * disassociation frames, sent for such reasons as a failure to |
| * set up security properly after associating. |
| */ |
| #define IEEE80211_STYPE_DEAUTH 0x00C0 |
| |
| /** Subtype value for action management frames |
| * |
| * Action frames are used to implement spectrum management and QoS |
| * features that gPXE currently does not support. |
| */ |
| #define IEEE80211_STYPE_ACTION 0x00D0 |
| |
| |
| /** Subtype value for RTS (request to send) control frames */ |
| #define IEEE80211_STYPE_RTS 0x00B0 |
| |
| /** Subtype value for CTS (clear to send) control frames */ |
| #define IEEE80211_STYPE_CTS 0x00C0 |
| |
| /** Subtype value for ACK (acknowledgement) control frames */ |
| #define IEEE80211_STYPE_ACK 0x00D0 |
| |
| |
| /** Subtype value for ordinary data frames, with no QoS or CF add-ons */ |
| #define IEEE80211_STYPE_DATA 0x0000 |
| |
| /** Subtype value for data frames containing no data */ |
| #define IEEE80211_STYPE_NODATA 0x0040 |
| |
| |
| /** 802.11 Frame Control field: To Data System flag |
| * |
| * This is set on data frames sent to an Access Point. |
| */ |
| #define IEEE80211_FC_TODS 0x0100 |
| |
| /** 802.11 Frame Control field: From Data System flag |
| * |
| * This is set on data frames sent from an Access Point. If both TODS |
| * and FROMDS are set, the frame header is a 4-address format used for |
| * inter-Access Point communication. |
| */ |
| #define IEEE80211_FC_FROMDS 0x0200 |
| |
| /** 802.11 Frame Control field: More Fragments flag */ |
| #define IEEE80211_FC_MORE_FRAG 0x0400 |
| |
| /** 802.11 Frame Control field: Retransmission flag */ |
| #define IEEE80211_FC_RETRY 0x0800 |
| |
| /** 802.11 Frame Control field: Power Managed flag |
| * |
| * This is set on any frame sent by a low-power station that will go |
| * into a power-saving mode immediately after this frame. Access |
| * Points are not allowed to act as low-power stations. |
| */ |
| #define IEEE80211_FC_PWR_MGMT 0x1000 |
| |
| /** 802.11 Frame Control field: More Data flag |
| * |
| * This is set on any frame sent by a station that has more data |
| * queued to be sent than is in the frame. |
| */ |
| #define IEEE80211_FC_MORE_DATA 0x2000 |
| |
| /** 802.11 Frame Control field: Protected flag |
| * |
| * This is set on frames in which data is encrypted (by any method). |
| */ |
| #define IEEE80211_FC_PROTECTED 0x4000 |
| |
| /** 802.11 Frame Control field: Ordered flag [?] */ |
| #define IEEE80211_FC_ORDER 0x8000 |
| |
| /** @} */ |
| |
| |
| /* ---------- Sequence Control defines ---------- */ |
| |
| /** |
| * @defgroup ieee80211_seq 802.11 Sequence Control field handling |
| * @{ |
| */ |
| |
| /** Extract sequence number from 802.11 Sequence Control field */ |
| #define IEEE80211_SEQNR( seq ) ( ( seq ) >> 4 ) |
| |
| /** Extract fragment number from 802.11 Sequence Control field */ |
| #define IEEE80211_FRAG( seq ) ( ( seq ) & 0x000F ) |
| |
| /** Make 802.11 Sequence Control field from sequence and fragment numbers */ |
| #define IEEE80211_MAKESEQ( seqnr, frag ) \ |
| ( ( ( ( seqnr ) & 0xFFF ) << 4 ) | ( ( frag ) & 0xF ) ) |
| |
| /** @} */ |
| |
| |
| /* ---------- Frame header formats ---------- */ |
| |
| /** |
| * @defgroup ieee80211_hdr 802.11 frame header formats |
| * @{ |
| */ |
| |
| /** An 802.11 data or management frame without QoS or WDS header fields */ |
| struct ieee80211_frame |
| { |
| u16 fc; /**< 802.11 Frame Control field */ |
| u16 duration; /**< Microseconds to reserve link */ |
| u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */ |
| u8 addr2[ETH_ALEN]; /**< Address 2 (immediate sender) */ |
| u8 addr3[ETH_ALEN]; /**< Address 3 (often "forward to") */ |
| u16 seq; /**< 802.11 Sequence Control field */ |
| u8 data[0]; /**< Beginning of frame data */ |
| } __attribute__((packed)); |
| |
| /** The 802.2 LLC/SNAP header sent before actual data in a data frame |
| * |
| * This header is not acknowledged in the 802.11 standard at all; it |
| * is treated just like data for MAC-layer purposes, including |
| * fragmentation and encryption. It is actually two headers |
| * concatenated: a three-byte 802.2 LLC header indicating Subnetwork |
| * Accesss Protocol (SNAP) in both source and destination Service |
| * Access Point (SAP) fields, and a five-byte SNAP header indicating a |
| * zero OUI and two-byte Ethernet protocol type field. |
| * |
| * Thus, an eight-byte header in which six of the bytes are redundant. |
| * Lovely, isn't it? |
| */ |
| struct ieee80211_llc_snap_header |
| { |
| /* LLC part: */ |
| u8 dsap; /**< Destination SAP ID */ |
| u8 ssap; /**< Source SAP ID */ |
| u8 ctrl; /**< Control information */ |
| |
| /* SNAP part: */ |
| u8 oui[3]; /**< Organization code, usually 0 */ |
| u16 ethertype; /**< Ethernet Type field */ |
| } __attribute__((packed)); |
| |
| /** Value for DSAP field in 802.2 LLC header for 802.11 frames: SNAP */ |
| #define IEEE80211_LLC_DSAP 0xAA |
| |
| /** Value for SSAP field in 802.2 LLC header for 802.11 frames: SNAP */ |
| #define IEEE80211_LLC_SSAP 0xAA |
| |
| /** Value for control field in 802.2 LLC header for 802.11 frames |
| * |
| * "Unnumbered Information". |
| */ |
| #define IEEE80211_LLC_CTRL 0x03 |
| |
| |
| /** 16-byte RTS frame format, with abbreviated header */ |
| struct ieee80211_rts |
| { |
| u16 fc; /**< 802.11 Frame Control field */ |
| u16 duration; /**< Microseconds to reserve link */ |
| u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */ |
| u8 addr2[ETH_ALEN]; /**< Address 2 (immediate sender) */ |
| } __attribute__((packed)); |
| |
| /** Length of 802.11 RTS control frame */ |
| #define IEEE80211_RTS_LEN 16 |
| |
| /** 10-byte CTS or ACK frame format, with abbreviated header */ |
| struct ieee80211_cts_or_ack |
| { |
| u16 fc; /**< 802.11 Frame Control field */ |
| u16 duration; /**< Microseconds to reserve link */ |
| u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */ |
| } __attribute__((packed)); |
| |
| #define ieee80211_cts ieee80211_cts_or_ack |
| #define ieee80211_ack ieee80211_cts_or_ack |
| |
| /** Length of 802.11 CTS control frame */ |
| #define IEEE80211_CTS_LEN 10 |
| |
| /** Length of 802.11 ACK control frame */ |
| #define IEEE80211_ACK_LEN 10 |
| |
| /** @} */ |
| |
| |
| /* ---------- Capability bits, status and reason codes ---------- */ |
| |
| /** |
| * @defgroup ieee80211_capab 802.11 management frame capability field bits |
| * @{ |
| */ |
| |
| /** Set if using an Access Point (managed mode) */ |
| #define IEEE80211_CAPAB_MANAGED 0x0001 |
| |
| /** Set if operating in IBSS (no-AP, "Ad-Hoc") mode */ |
| #define IEEE80211_CAPAB_ADHOC 0x0002 |
| |
| /** Set if we support Contention-Free Period operation */ |
| #define IEEE80211_CAPAB_CFPOLL 0x0004 |
| |
| /** Set if we wish to be polled for Contention-Free operation */ |
| #define IEEE80211_CAPAB_CFPR 0x0008 |
| |
| /** Set if the network is encrypted (by any method) */ |
| #define IEEE80211_CAPAB_PRIVACY 0x0010 |
| |
| /** Set if PHY supports short preambles on 802.11b */ |
| #define IEEE80211_CAPAB_SHORT_PMBL 0x0020 |
| |
| /** Set if PHY supports PBCC modulation */ |
| #define IEEE80211_CAPAB_PBCC 0x0040 |
| |
| /** Set if we support Channel Agility */ |
| #define IEEE80211_CAPAB_CHAN_AGILITY 0x0080 |
| |
| /** Set if we support spectrum management (DFS and TPC) on the 5GHz band */ |
| #define IEEE80211_CAPAB_SPECTRUM_MGMT 0x0100 |
| |
| /** Set if we support Quality of Service enhancements */ |
| #define IEEE80211_CAPAB_QOS 0x0200 |
| |
| /** Set if PHY supports short slot time on 802.11g */ |
| #define IEEE80211_CAPAB_SHORT_SLOT 0x0400 |
| |
| /** Set if PHY supports APSD option */ |
| #define IEEE80211_CAPAB_APSD 0x0800 |
| |
| /** Set if PHY supports DSSS/OFDM modulation (one way of 802.11 b/g mixing) */ |
| #define IEEE80211_CAPAB_DSSS_OFDM 0x2000 |
| |
| /** Set if we support delayed block ACK */ |
| #define IEEE80211_CAPAB_DELAYED_BACK 0x4000 |
| |
| /** Set if we support immediate block ACK */ |
| #define IEEE80211_CAPAB_IMMED_BACK 0x8000 |
| |
| /** @} */ |
| |
| |
| /** |
| * @defgroup ieee80211_status 802.11 status codes |
| * |
| * These are returned to indicate an immediate denial of |
| * authentication or association. In gPXE, the lower 5 bits of the |
| * status code are encoded into the file-unique portion of an error |
| * code, the ERRFILE portion is always @c ERRFILE_net80211, and the |
| * POSIX error code is @c ECONNREFUSED for status 0-31 or @c |
| * EHOSTUNREACH for status 32-63. |
| * |
| * For a complete table with non-abbreviated error messages, see IEEE |
| * Std 802.11-2007, Table 7-23, p.94. |
| * |
| * @{ |
| */ |
| |
| #define IEEE80211_STATUS_SUCCESS 0 |
| #define IEEE80211_STATUS_FAILURE 1 |
| #define IEEE80211_STATUS_CAPAB_UNSUPP 10 |
| #define IEEE80211_STATUS_REASSOC_INVALID 11 |
| #define IEEE80211_STATUS_ASSOC_DENIED 12 |
| #define IEEE80211_STATUS_AUTH_ALGO_UNSUPP 13 |
| #define IEEE80211_STATUS_AUTH_SEQ_INVALID 14 |
| #define IEEE80211_STATUS_AUTH_CHALL_INVALID 15 |
| #define IEEE80211_STATUS_AUTH_TIMEOUT 16 |
| #define IEEE80211_STATUS_ASSOC_NO_ROOM 17 |
| #define IEEE80211_STATUS_ASSOC_NEED_RATE 18 |
| #define IEEE80211_STATUS_ASSOC_NEED_SHORT_PMBL 19 |
| #define IEEE80211_STATUS_ASSOC_NEED_PBCC 20 |
| #define IEEE80211_STATUS_ASSOC_NEED_CHAN_AGILITY 21 |
| #define IEEE80211_STATUS_ASSOC_NEED_SPECTRUM_MGMT 22 |
| #define IEEE80211_STATUS_ASSOC_BAD_POWER 23 |
| #define IEEE80211_STATUS_ASSOC_BAD_CHANNELS 24 |
| #define IEEE80211_STATUS_ASSOC_NEED_SHORT_SLOT 25 |
| #define IEEE80211_STATUS_ASSOC_NEED_DSSS_OFDM 26 |
| #define IEEE80211_STATUS_QOS_FAILURE 32 |
| #define IEEE80211_STATUS_QOS_NO_ROOM 33 |
| #define IEEE80211_STATUS_LINK_IS_HORRIBLE 34 |
| #define IEEE80211_STATUS_ASSOC_NEED_QOS 35 |
| #define IEEE80211_STATUS_REQUEST_DECLINED 37 |
| #define IEEE80211_STATUS_REQUEST_INVALID 38 |
| #define IEEE80211_STATUS_TS_NOT_CREATED_AGAIN 39 |
| #define IEEE80211_STATUS_INVALID_IE 40 |
| #define IEEE80211_STATUS_GROUP_CIPHER_INVALID 41 |
| #define IEEE80211_STATUS_PAIR_CIPHER_INVALID 42 |
| #define IEEE80211_STATUS_AKMP_INVALID 43 |
| #define IEEE80211_STATUS_RSN_VERSION_UNSUPP 44 |
| #define IEEE80211_STATUS_RSN_CAPAB_INVALID 45 |
| #define IEEE80211_STATUS_CIPHER_REJECTED 46 |
| #define IEEE80211_STATUS_TS_NOT_CREATED_WAIT 47 |
| #define IEEE80211_STATUS_DIRECT_LINK_FORBIDDEN 48 |
| #define IEEE80211_STATUS_DEST_NOT_PRESENT 49 |
| #define IEEE80211_STATUS_DEST_NOT_QOS 50 |
| #define IEEE80211_STATUS_ASSOC_LISTEN_TOO_HIGH 51 |
| |
| /** @} */ |
| |
| |
| |
| /** |
| * @defgroup ieee80211_reason 802.11 reason codes |
| * |
| * These are returned to indicate the reason for a deauthentication or |
| * disassociation sent (usually) after authentication or association |
| * had succeeded. In gPXE, the lower 5 bits of the reason code are |
| * encoded into the file-unique portion of an error code, the ERRFILE |
| * portion is always @c ERRFILE_net80211, and the POSIX error code is |
| * @c ECONNRESET for reason 0-31 or @c ENETRESET for reason 32-63. |
| * |
| * For a complete table with non-abbreviated error messages, see IEEE |
| * Std 802.11-2007, Table 7-22, p.92. |
| * |
| * @{ |
| */ |
| |
| #define IEEE80211_REASON_NONE 0 |
| #define IEEE80211_REASON_UNSPECIFIED 1 |
| #define IEEE80211_REASON_AUTH_NO_LONGER_VALID 2 |
| #define IEEE80211_REASON_LEAVING 3 |
| #define IEEE80211_REASON_INACTIVITY 4 |
| #define IEEE80211_REASON_OUT_OF_RESOURCES 5 |
| #define IEEE80211_REASON_NEED_AUTH 6 |
| #define IEEE80211_REASON_NEED_ASSOC 7 |
| #define IEEE80211_REASON_LEAVING_TO_ROAM 8 |
| #define IEEE80211_REASON_REASSOC_INVALID 9 |
| #define IEEE80211_REASON_BAD_POWER 10 |
| #define IEEE80211_REASON_BAD_CHANNELS 11 |
| #define IEEE80211_REASON_INVALID_IE 13 |
| #define IEEE80211_REASON_MIC_FAILURE 14 |
| #define IEEE80211_REASON_4WAY_TIMEOUT 15 |
| #define IEEE80211_REASON_GROUPKEY_TIMEOUT 16 |
| #define IEEE80211_REASON_4WAY_INVALID 17 |
| #define IEEE80211_REASON_GROUP_CIPHER_INVALID 18 |
| #define IEEE80211_REASON_PAIR_CIPHER_INVALID 19 |
| #define IEEE80211_REASON_AKMP_INVALID 20 |
| #define IEEE80211_REASON_RSN_VERSION_INVALID 21 |
| #define IEEE80211_REASON_RSN_CAPAB_INVALID 22 |
| #define IEEE80211_REASON_8021X_FAILURE 23 |
| #define IEEE80211_REASON_CIPHER_REJECTED 24 |
| #define IEEE80211_REASON_QOS_UNSPECIFIED 32 |
| #define IEEE80211_REASON_QOS_OUT_OF_RESOURCES 33 |
| #define IEEE80211_REASON_LINK_IS_HORRIBLE 34 |
| #define IEEE80211_REASON_INVALID_TXOP 35 |
| #define IEEE80211_REASON_REQUESTED_LEAVING 36 |
| #define IEEE80211_REASON_REQUESTED_NO_USE 37 |
| #define IEEE80211_REASON_REQUESTED_NEED_SETUP 38 |
| #define IEEE80211_REASON_REQUESTED_TIMEOUT 39 |
| #define IEEE80211_REASON_CIPHER_UNSUPPORTED 45 |
| |
| /** @} */ |
| |
| /* ---------- Information element declarations ---------- */ |
| |
| /** |
| * @defgroup ieee80211_ie 802.11 information elements |
| * |
| * Many management frames include a section that amounts to a |
| * concatenation of these information elements, so that the sender can |
| * choose which information to send and the receiver can ignore the |
| * parts it doesn't understand. Each IE contains a two-byte header, |
| * one byte ID and one byte length, followed by IE-specific data. The |
| * length does not include the two-byte header. Information elements |
| * are required to be sorted by ID, but gPXE does not require that in |
| * those it receives. |
| * |
| * This group also includes a few inline functions to simplify common |
| * tasks in IE processing. |
| * |
| * @{ |
| */ |
| |
| /** Generic 802.11 information element header */ |
| struct ieee80211_ie_header { |
| u8 id; /**< Information element ID */ |
| u8 len; /**< Information element length */ |
| } __attribute__ ((packed)); |
| |
| |
| /** 802.11 SSID information element */ |
| struct ieee80211_ie_ssid { |
| u8 id; /**< SSID ID: 0 */ |
| u8 len; /**< SSID length */ |
| char ssid[0]; /**< SSID data, not NUL-terminated */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for SSID information element */ |
| #define IEEE80211_IE_SSID 0 |
| |
| |
| /** 802.11 rates information element |
| * |
| * The first 8 rates go in an IE of type RATES (1), and any more rates |
| * go in one of type EXT_RATES (50). Each rate is a byte with the low |
| * 7 bits equal to the rate in units of 500 kbps, and the high bit set |
| * if and only if the rate is "basic" (must be supported by all |
| * connected stations). |
| */ |
| struct ieee80211_ie_rates { |
| u8 id; /**< Rates ID: 1 or 50 */ |
| u8 len; /**< Number of rates */ |
| u8 rates[0]; /**< Rates data, one rate per byte */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for rates information element */ |
| #define IEEE80211_IE_RATES 1 |
| |
| /** Information element ID for extended rates information element */ |
| #define IEEE80211_IE_EXT_RATES 50 |
| |
| |
| /** 802.11 Direct Spectrum parameter information element |
| * |
| * This just contains the channel number. It has the fancy name |
| * because IEEE 802.11 also defines a frequency-hopping PHY that |
| * changes channels at regular intervals following a predetermined |
| * pattern; in practice nobody uses the FH PHY. |
| */ |
| struct ieee80211_ie_ds_param { |
| u8 id; /**< DS parameter ID: 3 */ |
| u8 len; /**< DS parameter length: 1 */ |
| u8 current_channel; /**< Current channel number, 1-14 */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Direct Spectrum parameter information element */ |
| #define IEEE80211_IE_DS_PARAM 3 |
| |
| |
| /** 802.11 Country information element regulatory extension triplet */ |
| struct ieee80211_ie_country_ext_triplet { |
| u8 reg_ext_id; /**< Regulatory extension ID */ |
| u8 reg_class_id; /**< Regulatory class ID */ |
| u8 coverage_class; /**< Coverage class */ |
| } __attribute__ ((packed)); |
| |
| /** 802.11 Country information element regulatory band triplet */ |
| struct ieee80211_ie_country_band_triplet { |
| u8 first_channel; /**< Channel number for first channel in band */ |
| u8 nr_channels; /**< Number of contiguous channels in band */ |
| u8 max_txpower; /**< Maximum TX power in dBm */ |
| } __attribute__ ((packed)); |
| |
| /** 802.11 Country information element regulatory triplet |
| * |
| * It is a band triplet if the first byte is 200 or less, and a |
| * regulatory extension triplet otherwise. |
| */ |
| union ieee80211_ie_country_triplet { |
| /** Differentiator between band and ext triplets */ |
| u8 first; |
| |
| /** Information about a band of channels */ |
| struct ieee80211_ie_country_band_triplet band; |
| |
| /** Regulatory extension information */ |
| struct ieee80211_ie_country_ext_triplet ext; |
| }; |
| |
| /** 802.11 Country information element |
| * |
| * This contains some data about RF regulations. |
| */ |
| struct ieee80211_ie_country { |
| u8 id; /**< Country information ID: 7 */ |
| u8 len; /**< Country information length: varies */ |
| char name[2]; /**< ISO Alpha2 country code */ |
| char in_out; /**< 'I' for indoor, 'O' for outdoor */ |
| |
| /** List of regulatory triplets */ |
| union ieee80211_ie_country_triplet triplet[0]; |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Country information element */ |
| #define IEEE80211_IE_COUNTRY 7 |
| |
| |
| /** 802.11 Request information element |
| * |
| * This contains a list of information element types we would like to |
| * be included in probe response frames. |
| */ |
| struct ieee80211_ie_request { |
| u8 id; /**< Request ID: 10 */ |
| u8 len; /**< Number of IEs requested */ |
| u8 request[0]; /**< List of IEs requested */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Request information element */ |
| #define IEEE80211_IE_REQUEST 10 |
| |
| |
| /** 802.11 Challenge Text information element |
| * |
| * This is used in authentication frames under Shared Key |
| * authentication. |
| */ |
| struct ieee80211_ie_challenge_text { |
| u8 id; /**< Challenge Text ID: 16 */ |
| u8 len; /**< Challenge Text length: usually 128 */ |
| u8 challenge_text[0]; /**< Challenge Text data */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Challenge Text information element */ |
| #define IEEE80211_IE_CHALLENGE_TEXT 16 |
| |
| |
| /** 802.11 Power Constraint information element |
| * |
| * This is used to specify an additional power limitation on top of |
| * the Country requirements. |
| */ |
| struct ieee80211_ie_power_constraint { |
| u8 id; /**< Power Constraint ID: 52 */ |
| u8 len; /**< Power Constraint length: 1 */ |
| u8 power_constraint; /**< Decrease in allowed TX power, dBm */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Power Constraint information element */ |
| #define IEEE80211_IE_POWER_CONSTRAINT 52 |
| |
| |
| /** 802.11 Power Capability information element |
| * |
| * This is used in association request frames to indicate the extremes |
| * of our TX power abilities. It is required only if we indicate |
| * support for spectrum management. |
| */ |
| struct ieee80211_ie_power_capab { |
| u8 id; /**< Power Capability ID: 33 */ |
| u8 len; /**< Power Capability length: 2 */ |
| u8 min_txpower; /**< Minimum possible TX power, dBm */ |
| u8 max_txpower; /**< Maximum possible TX power, dBm */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Power Capability information element */ |
| #define IEEE80211_IE_POWER_CAPAB 33 |
| |
| |
| /** 802.11 Channels information element channel band tuple */ |
| struct ieee80211_ie_channels_channel_band { |
| u8 first_channel; /**< Channel number of first channel in band */ |
| u8 nr_channels; /**< Number of channels in band */ |
| } __attribute__ ((packed)); |
| |
| /** 802.11 Channels information element |
| * |
| * This is used in association frames to indicate the channels we can |
| * use. It is required only if we indicate support for spectrum |
| * management. |
| */ |
| struct ieee80211_ie_channels { |
| u8 id; /**< Channels ID: 36 */ |
| u8 len; /**< Channels length: 2 */ |
| |
| /** List of (start, length) channel bands we can use */ |
| struct ieee80211_ie_channels_channel_band channels[0]; |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Channels information element */ |
| #define IEEE80211_IE_CHANNELS 36 |
| |
| |
| /** 802.11 ERP Information information element |
| * |
| * This is used to communicate some PHY-level flags. |
| */ |
| struct ieee80211_ie_erp_info { |
| u8 id; /**< ERP Information ID: 42 */ |
| u8 len; /**< ERP Information length: 1 */ |
| u8 erp_info; /**< ERP flags */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for ERP Information information element */ |
| #define IEEE80211_IE_ERP_INFO 42 |
| |
| /** ERP information element: Flag set if 802.11b stations are present */ |
| #define IEEE80211_ERP_NONERP_PRESENT 0x01 |
| |
| /** ERP information element: Flag set if CTS protection must be used */ |
| #define IEEE80211_ERP_USE_PROTECTION 0x02 |
| |
| /** ERP information element: Flag set if long preambles must be used */ |
| #define IEEE80211_ERP_BARKER_LONG 0x04 |
| |
| |
| /** 802.11 Robust Security Network ("WPA") information element |
| * |
| * Showing once again a striking clarity of design, the IEEE folks put |
| * dynamically-sized data in the middle of this structure. As such, |
| * the below structure definition only works for IEs we create |
| * ourselves, which always have one pairwise cipher and one AKM; |
| * received IEs should be parsed piecemeal. |
| * |
| * Also inspired was IEEE's choice of 16-bit fields to count the |
| * number of 4-byte elements in a structure with a maximum length of |
| * 255 bytes. |
| * |
| * Many fields reference a cipher or authentication-type ID; this is a |
| * three-byte OUI followed by one byte identifying the cipher with |
| * respect to that OUI. For all standard ciphers the OUI is 00:0F:AC, |
| * except in old-style WPA IEs encapsulated in vendor-specific IEs, |
| * where it's 00:50:F2. |
| */ |
| struct ieee80211_ie_rsn { |
| /** Information element ID */ |
| u8 id; |
| |
| /** Information element length */ |
| u8 len; |
| |
| /** RSN information element version */ |
| u16 version; |
| |
| /** Cipher ID for the cipher used in multicast/broadcast frames */ |
| u32 group_cipher; |
| |
| /** Number of unicast ciphers supported */ |
| u16 pairwise_count; |
| |
| /** List of cipher IDs for supported unicast frame ciphers */ |
| u32 pairwise_cipher[1]; |
| |
| /** Number of authentication types supported */ |
| u16 akm_count; |
| |
| /** List of authentication type IDs for supported types */ |
| u32 akm_list[1]; |
| |
| /** Security capabilities field (RSN only) */ |
| u16 rsn_capab; |
| |
| /** Number of PMKIDs included (present only in association frames) */ |
| u16 pmkid_count; |
| |
| /** List of PMKIDs included, each a 16-byte SHA1 hash */ |
| u8 pmkid_list[0]; |
| } __attribute__((packed)); |
| |
| /** Information element ID for Robust Security Network information element */ |
| #define IEEE80211_IE_RSN 48 |
| |
| /** Calculate necessary size of RSN information element |
| * |
| * @v npair Number of pairwise ciphers supported |
| * @v nauth Number of authentication types supported |
| * @v npmkid Number of PMKIDs to include |
| * @v is_rsn If TRUE, calculate RSN IE size; if FALSE, calculate WPA IE size |
| * @ret size Necessary size of IE, including header bytes |
| */ |
| static inline size_t ieee80211_rsn_size ( int npair, int nauth, int npmkid, |
| int rsn_ie ) { |
| return 16 + 4 * ( npair + nauth ) + 16 * npmkid - 4 * ! rsn_ie; |
| } |
| |
| /** Make OUI plus type byte into 32-bit integer for easy comparison */ |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| #define _MKOUI( a, b, c, t ) \ |
| ( ( ( a ) << 24 ) | ( ( b ) << 16 ) | ( ( c ) << 8 ) | ( d ) ) |
| #define OUI_ORG_MASK 0xFFFFFF00 |
| #define OUI_TYPE_MASK 0x000000FF |
| #else |
| #define _MKOUI( a, b, c, t ) \ |
| ( ( ( t ) << 24 ) | ( ( c ) << 16 ) | ( ( b ) << 8 ) | ( a ) ) |
| #define OUI_ORG_MASK 0x00FFFFFF |
| #define OUI_TYPE_MASK 0xFF000000 |
| #endif |
| |
| /** Organization part for OUIs in standard RSN IE */ |
| #define IEEE80211_RSN_OUI _MKOUI ( 0x00, 0x0F, 0xAC, 0 ) |
| |
| /** Organization part for OUIs in old WPA IE */ |
| #define IEEE80211_WPA_OUI _MKOUI ( 0x00, 0x50, 0xF2, 0 ) |
| |
| /** Old vendor-type WPA IE OUI type + subtype */ |
| #define IEEE80211_WPA_OUI_VEN _MKOUI ( 0x00, 0x50, 0xF2, 0x01 ) |
| |
| |
| /** 802.11 RSN IE: expected version number */ |
| #define IEEE80211_RSN_VERSION 1 |
| |
| /** 802.11 RSN IE: cipher type for 40-bit WEP */ |
| #define IEEE80211_RSN_CTYPE_WEP40 _MKOUI ( 0, 0, 0, 0x01 ) |
| |
| /** 802.11 RSN IE: cipher type for 104-bit WEP */ |
| #define IEEE80211_RSN_CTYPE_WEP104 _MKOUI ( 0, 0, 0, 0x05 ) |
| |
| /** 802.11 RSN IE: cipher type for TKIP ("WPA") */ |
| #define IEEE80211_RSN_CTYPE_TKIP _MKOUI ( 0, 0, 0, 0x02 ) |
| |
| /** 802.11 RSN IE: cipher type for CCMP ("WPA2") */ |
| #define IEEE80211_RSN_CTYPE_CCMP _MKOUI ( 0, 0, 0, 0x04 ) |
| |
| /** 802.11 RSN IE: cipher type for "use group" |
| * |
| * This can only appear as a pairwise cipher, and means unicast frames |
| * should be encrypted in the same way as broadcast/multicast frames. |
| */ |
| #define IEEE80211_RSN_CTYPE_USEGROUP _MKOUI ( 0, 0, 0, 0x00 ) |
| |
| /** 802.11 RSN IE: auth method type for using an 802.1X server */ |
| #define IEEE80211_RSN_ATYPE_8021X _MKOUI ( 0, 0, 0, 0x01 ) |
| |
| /** 802.11 RSN IE: auth method type for using a pre-shared key */ |
| #define IEEE80211_RSN_ATYPE_PSK _MKOUI ( 0, 0, 0, 0x02 ) |
| |
| /** 802.11 RSN IE capabilities: AP supports pre-authentication */ |
| #define IEEE80211_RSN_CAPAB_PREAUTH 0x001 |
| |
| /** 802.11 RSN IE capabilities: Node has conflict between TKIP and WEP |
| * |
| * This is a legacy issue; APs always set it to 0, and gPXE sets it to |
| * 0. |
| */ |
| #define IEEE80211_RSN_CAPAB_NO_PAIRWISE 0x002 |
| |
| /** 802.11 RSN IE capabilities: Number of PTKSA replay counters |
| * |
| * A value of 0 means one replay counter, 1 means two, 2 means four, |
| * and 3 means sixteen. |
| */ |
| #define IEEE80211_RSN_CAPAB_PTKSA_REPLAY 0x00C |
| |
| /** 802.11 RSN IE capabilities: Number of GTKSA replay counters |
| * |
| * A value of 0 means one replay counter, 1 means two, 2 means four, |
| * and 3 means sixteen. |
| */ |
| #define IEEE80211_RSN_CAPAB_GTKSA_REPLAY 0x030 |
| |
| /** 802.11 RSN IE capabilities: PeerKey Handshaking is suported */ |
| #define IEEE80211_RSN_CAPAB_PEERKEY 0x200 |
| |
| |
| /** 802.11 RSN IE capabilities: One replay counter |
| * |
| * This should be AND'ed with @c IEEE80211_RSN_CAPAB_PTKSA_REPLAY or |
| * @c IEEE80211_RSN_CAPAB_GTKSA_REPLAY (or both) to produce a value |
| * which can be OR'ed into the capabilities field. |
| */ |
| #define IEEE80211_RSN_1_CTR 0x000 |
| |
| /** 802.11 RSN IE capabilities: Two replay counters */ |
| #define IEEE80211_RSN_2_CTR 0x014 |
| |
| /** 802.11 RSN IE capabilities: Four replay counters */ |
| #define IEEE80211_RSN_4_CTR 0x028 |
| |
| /** 802.11 RSN IE capabilities: 16 replay counters */ |
| #define IEEE80211_RSN_16_CTR 0x03C |
| |
| |
| /** 802.11 Vendor Specific information element |
| * |
| * One often sees the RSN IE masquerading as vendor-specific on |
| * devices that were produced prior to 802.11i (the WPA amendment) |
| * being finalized. |
| */ |
| struct ieee80211_ie_vendor { |
| u8 id; /**< Vendor-specific ID: 221 */ |
| u8 len; /**< Vendor-specific length: variable */ |
| u32 oui; /**< OUI and vendor-specific type byte */ |
| u8 data[0]; /**< Vendor-specific data */ |
| } __attribute__ ((packed)); |
| |
| /** Information element ID for Vendor Specific information element */ |
| #define IEEE80211_IE_VENDOR 221 |
| |
| |
| |
| |
| /** Any 802.11 information element |
| * |
| * This is formatted for ease of use, so IEs with complex structures |
| * get referenced in full, while those with only one byte of data or a |
| * simple array are pulled in to avoid a layer of indirection like |
| * ie->channels.channels[0]. |
| */ |
| union ieee80211_ie |
| { |
| /** Generic and simple information element info */ |
| struct { |
| u8 id; /**< Information element ID */ |
| u8 len; /**< Information element data length */ |
| union { |
| char ssid[0]; /**< SSID text */ |
| u8 rates[0]; /**< Rates data */ |
| u8 request[0]; /**< Request list */ |
| u8 challenge_text[0]; /**< Challenge text data */ |
| u8 power_constraint; /**< Power constraint, dBm */ |
| u8 erp_info; /**< ERP information flags */ |
| /** List of channels */ |
| struct ieee80211_ie_channels_channel_band channels[0]; |
| }; |
| }; |
| |
| /** DS parameter set */ |
| struct ieee80211_ie_ds_param ds_param; |
| |
| /** Country information */ |
| struct ieee80211_ie_country country; |
| |
| /** Power capability */ |
| struct ieee80211_ie_power_capab power_capab; |
| |
| /** Security information */ |
| struct ieee80211_ie_rsn rsn; |
| |
| /** Vendor-specific */ |
| struct ieee80211_ie_vendor vendor; |
| }; |
| |
| /** Check that 802.11 information element is bounded by buffer |
| * |
| * @v ie Information element |
| * @v end End of buffer in which information element is stored |
| * @ret ok TRUE if the IE is completely contained within the buffer |
| */ |
| static inline int ieee80211_ie_bound ( union ieee80211_ie *ie, void *end ) |
| { |
| void *iep = ie; |
| return ( iep + 2 <= end && iep + 2 + ie->len <= end ); |
| } |
| |
| /** Advance to next 802.11 information element |
| * |
| * @v ie Current information element pointer |
| * @v end Pointer to first byte not in information element space |
| * @ret next Pointer to next information element, or NULL if no more |
| * |
| * When processing received IEs, @a end should be set to the I/O |
| * buffer tail pointer; when marshalling IEs for sending, @a end |
| * should be NULL. |
| */ |
| static inline union ieee80211_ie * ieee80211_next_ie ( union ieee80211_ie *ie, |
| void *end ) |
| { |
| void *next_ie_byte = ( void * ) ie + ie->len + 2; |
| union ieee80211_ie *next_ie = next_ie_byte; |
| |
| if ( ! end ) |
| return next_ie; |
| |
| if ( ieee80211_ie_bound ( next_ie, end ) ) |
| return next_ie; |
| |
| return NULL; |
| } |
| |
| /** @} */ |
| |
| |
| /* ---------- Management frame data formats ---------- */ |
| |
| /** |
| * @defgroup ieee80211_mgmt_data Management frame data payloads |
| * @{ |
| */ |
| |
| /** Beacon or probe response frame data */ |
| struct ieee80211_beacon_or_probe_resp |
| { |
| /** 802.11 TSFT value at frame send */ |
| u64 timestamp; |
| |
| /** Interval at which beacons are sent, in units of 1024 us */ |
| u16 beacon_interval; |
| |
| /** Capability flags */ |
| u16 capability; |
| |
| /** List of information elements */ |
| union ieee80211_ie info_element[0]; |
| } __attribute__((packed)); |
| |
| #define ieee80211_beacon ieee80211_beacon_or_probe_resp |
| #define ieee80211_probe_resp ieee80211_beacon_or_probe_resp |
| |
| /** Disassociation or deauthentication frame data */ |
| struct ieee80211_disassoc_or_deauth |
| { |
| /** Reason code */ |
| u16 reason; |
| } __attribute__((packed)); |
| |
| #define ieee80211_disassoc ieee80211_disassoc_or_deauth |
| #define ieee80211_deauth ieee80211_disassoc_or_deauth |
| |
| /** Association request frame data */ |
| struct ieee80211_assoc_req |
| { |
| /** Capability flags */ |
| u16 capability; |
| |
| /** Interval at which we wake up, in units of the beacon interval */ |
| u16 listen_interval; |
| |
| /** List of information elements */ |
| union ieee80211_ie info_element[0]; |
| } __attribute__((packed)); |
| |
| /** Association or reassociation response frame data */ |
| struct ieee80211_assoc_or_reassoc_resp |
| { |
| /** Capability flags */ |
| u16 capability; |
| |
| /** Status code */ |
| u16 status; |
| |
| /** Association ID */ |
| u16 aid; |
| |
| /** List of information elements */ |
| union ieee80211_ie info_element[0]; |
| } __attribute__((packed)); |
| |
| #define ieee80211_assoc_resp ieee80211_assoc_or_reassoc_resp |
| #define ieee80211_reassoc_resp ieee80211_assoc_or_reassoc_resp |
| |
| /** Reassociation request frame data */ |
| struct ieee80211_reassoc_req |
| { |
| /** Capability flags */ |
| u16 capability; |
| |
| /** Interval at which we wake up, in units of the beacon interval */ |
| u16 listen_interval; |
| |
| /** MAC address of current Access Point */ |
| u8 current_addr[ETH_ALEN]; |
| |
| /** List of information elements */ |
| union ieee80211_ie info_element[0]; |
| } __attribute__((packed)); |
| |
| /** Probe request frame data */ |
| struct ieee80211_probe_req |
| { |
| /** List of information elements */ |
| union ieee80211_ie info_element[0]; |
| } __attribute__((packed)); |
| |
| /** Authentication frame data */ |
| struct ieee80211_auth |
| { |
| /** Authentication algorithm (Open System or Shared Key) */ |
| u16 algorithm; |
| |
| /** Sequence number of this frame; first from client to AP is 1 */ |
| u16 tx_seq; |
| |
| /** Status code */ |
| u16 status; |
| |
| /** List of information elements */ |
| union ieee80211_ie info_element[0]; |
| } __attribute__((packed)); |
| |
| /** Open System authentication algorithm */ |
| #define IEEE80211_AUTH_OPEN_SYSTEM 0 |
| |
| /** Shared Key authentication algorithm */ |
| #define IEEE80211_AUTH_SHARED_KEY 1 |
| |
| /** @} */ |
| |
| #endif |