From ca67b09c015d4af3ae3cce12aa72e60941dbb8b5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 18:29:52 +0200 Subject: Adding debian version 2.06-13+deb12u1. Signed-off-by: Daniel Baumann --- .../disabled/gpxe/src/include/gpxe/ieee80211.h | 1182 ++++++++++++++++++++ 1 file changed, 1182 insertions(+) create mode 100644 debian/grub-extras/disabled/gpxe/src/include/gpxe/ieee80211.h (limited to 'debian/grub-extras/disabled/gpxe/src/include/gpxe/ieee80211.h') diff --git a/debian/grub-extras/disabled/gpxe/src/include/gpxe/ieee80211.h b/debian/grub-extras/disabled/gpxe/src/include/gpxe/ieee80211.h new file mode 100644 index 0000000..0403f92 --- /dev/null +++ b/debian/grub-extras/disabled/gpxe/src/include/gpxe/ieee80211.h @@ -0,0 +1,1182 @@ +#ifndef _GPXE_IEEE80211_H +#define _GPXE_IEEE80211_H + +#include /* for ETH_ALEN */ + +/** @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 is only a guideline; the + * @c IEEE80211_RSN_FIELD, @c IEEE80211_RSN_CIPHER, and + * @c IEEE80211_RSN_AUTHTYPE macros should be used to access any + * data. + * + * 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. + * + * The authentication types referenced in this structure have nothing + * to do with 802.11 authentication frames or the @c algorithm field + * within them. + */ +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 */ + u8 group_cipher[4]; + + /** Number of unicast ciphers supported */ + u16 pairwise_count; + + /** List of cipher IDs for supported unicast frame ciphers */ + u8 pairwise_cipher[4]; + + /** Number of authentication types supported */ + u16 akm_count; + + /** List of authentication type IDs for supported types */ + u8 akm_list[4]; + + /** Security capabilities field. */ + 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 + +/** OUI for standard ciphers in RSN information element */ +#define IEEE80211_RSN_OUI "\x00\x0F\xAC" + +/** Extract RSN IE version field */ +#define IEEE80211_RSN_FIELD_version( rsnp ) ( (rsnp)->version ) + +/** Extract RSN IE group_cipher field */ +#define IEEE80211_RSN_FIELD_group_cipher( rsnp ) ( (rsnp)->group_cipher ) + +/** Extract RSN IE pairwise_count field */ +#define IEEE80211_RSN_FIELD_pairwise_count( rsnp ) ( (rsnp)->pairwise_count ) + +/** Extract RSN IE akm_count field */ +#define IEEE80211_RSN_FIELD_akm_count( rsnp ) \ + ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \ + 4*( ( rsnp )->pairwise_count - 1 ) ) )->akm_count ) + +/** Extract RSN IE rsn_capab field */ +#define IEEE80211_RSN_FIELD_rsn_capab( rsnp ) \ + ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \ + 4*( ( rsnp )->pairwise_count - 1 ) + \ + 4*( ( rsnp )->akm_count - 1 ) ) )->rsn_capab ) + +/** Extract RSN IE pmkid_count field */ +#define IEEE80211_RSN_FIELD_pmkid_count( rsnp ) \ + ( ( ( struct ieee80211_ie_rsn * ) ( ( void * ) ( rsnp ) + \ + 4*( ( rsnp )->pairwise_count - 1 ) + \ + 4*( ( rsnp )->akm_count - 1 ) ) )->pmkid_count ) + +/** Extract field from RSN information element + * + * @v rsnp Pointer to RSN information element + * @v field Name of field to extract + * @ret val Lvalue of the requested field + * + * You must fill the fields of the structure in order for this to work + * properly. + */ +#define IEEE80211_RSN_FIELD( rsnp, field ) \ + IEEE80211_RSN_FIELD_ ## field ( rsnp ) + +/** Get pointer to pairwise cipher from RSN information element + * + * @v rsnp Pointer to RSN information element + * @v cipher Index of pairwise cipher to extract + * @ret ptr Pointer to requested cipher + */ +#define IEEE80211_RSN_CIPHER( rsnp, cipher ) \ + ( ( rsnp )->pairwise_cipher + 4 * ( cipher ) ) + +/** Get pointer to authentication type from RSN information element + * + * @v rsnp Pointer to RSN information element + * @v akm Index of authentication type to extract + * @ret ptr Pointer to requested authentication type + * + * The @c pairwise_count field must be correct. + */ +#define IEEE80211_RSN_AUTHTYPE( rsnp, akm ) \ + ( ( rsnp )->akm_list + 4 * ( ( rsnp )->pairwise_count - 1 ) + 4 * ( akm ) ) + +/** Get pointer to PMKID from RSN information element + * + * @v rsnp Pointer to RSN information element + * @v idx Index of PMKID to extract + * @ret ptr Pointer to requested PMKID + * + * The @c pairwise_count and @c akm_count fields must be correct. + */ +#define IEEE80211_RSN_PMKID( rsnp, idx ) \ + ( ( rsnp )->pmkid_list + 4 * ( ( rsnp )->pairwise_count - 1 ) + \ + 4 * ( ( rsnp )->akm_count - 1 ) + 16 * ( idx ) ) + +/** Verify size of RSN information element + * + * @v rsnp Pointer to RSN information element + * @ret ok TRUE if count fields are consistent with length field + * + * It is important to drop any RSN IE that does not pass this function + * before using the @c IEEE80211_RSN_FIELD, @c IEEE80211_RSN_CIPHER, + * and @c IEEE80211_RSN_AUTHTYPE macros, to avoid potential security + * compromise due to a malformed RSN IE. + * + * This function does not consider the possibility of some PMKIDs + * included in the RSN IE, because PMKIDs are only included in RSN IEs + * sent in association request frames, and we should never receive an + * association request frame. An RSN IE that includes PMKIDs will + * always fail this check. + */ +static inline int ieee80211_rsn_check ( struct ieee80211_ie_rsn *rsnp ) { + if ( rsnp->len < 12 + 4 * rsnp->pairwise_count ) + return 0; + return ( rsnp->len == 12 + 4 * ( rsnp->pairwise_count + + IEEE80211_RSN_FIELD ( rsnp, akm_count ) ) ); +} + +/** 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 + * @ret size Necessary size of RSN IE, including header bytes + */ +static inline size_t ieee80211_rsn_size ( int npair, int nauth, int npmkid ) { + return 16 + 4 * ( npair + nauth ) + 16 * npmkid; +} + +/** 802.11 RSN IE: expected version number */ +#define IEEE80211_RSN_VERSION 1 + +/** 802.11 RSN IE: fourth byte of cipher type for 40-bit WEP */ +#define IEEE80211_RSN_CTYPE_WEP40 1 + +/** 802.11 RSN IE: fourth byte of cipher type for 104-bit WEP */ +#define IEEE80211_RSN_CTYPE_WEP104 5 + +/** 802.11 RSN IE: fourth byte of cipher type for TKIP ("WPA") */ +#define IEEE80211_RSN_CTYPE_TKIP 2 + +/** 802.11 RSN IE: fourth byte of cipher type for CCMP ("WPA2") */ +#define IEEE80211_RSN_CTYPE_CCMP 4 + +/** 802.11 RSN IE: fourth byte of 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 0 + +/** 802.11 RSN IE: fourth byte of auth method type for using an 802.1X server */ +#define IEEE80211_RSN_ATYPE_8021X 1 + +/** 802.11 RSN IE: fourth byte of auth method type for using a pre-shared key */ +#define IEEE80211_RSN_ATYPE_PSK 2 + +/** 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 + + + +/** 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; +}; + +/** 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 ( next_ie_byte < end && next_ie_byte + next_ie->len <= 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 -- cgit v1.2.3