diff options
| author | Joshua Oreman | 2009-07-21 20:16:38 +0200 |
|---|---|---|
| committer | Michael Brown | 2009-08-01 20:00:32 +0200 |
| commit | ce64398f87230d14a62b2ff153a67b851a125d2e (patch) | |
| tree | 8acc9c2ed28a23100b98626a25a67b09e2dbd2c0 /src/include/gpxe | |
| parent | [hermon] Add support for RC queue pairs (diff) | |
| download | ipxe-ce64398f87230d14a62b2ff153a67b851a125d2e.tar.gz ipxe-ce64398f87230d14a62b2ff153a67b851a125d2e.tar.xz ipxe-ce64398f87230d14a62b2ff153a67b851a125d2e.zip | |
[802.11] Add support for 802.11 devices with software MAC layer
This is required for all modern 802.11 devices, and allows drivers
to be written for them with minimally more effort than is required
for a wired NIC.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Modified-by: Michael Brown <mcb30@etherboot.org>
Diffstat (limited to 'src/include/gpxe')
| -rw-r--r-- | src/include/gpxe/errfile.h | 1 | ||||
| -rw-r--r-- | src/include/gpxe/ieee80211.h | 1174 | ||||
| -rw-r--r-- | src/include/gpxe/net80211.h | 983 | ||||
| -rw-r--r-- | src/include/gpxe/rc80211.h | 19 |
4 files changed, 2177 insertions, 0 deletions
diff --git a/src/include/gpxe/errfile.h b/src/include/gpxe/errfile.h index d31553240..e777ecb18 100644 --- a/src/include/gpxe/errfile.h +++ b/src/include/gpxe/errfile.h @@ -148,6 +148,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_ib_pathrec ( ERRFILE_NET | 0x001c0000 ) #define ERRFILE_ib_mcast ( ERRFILE_NET | 0x001d0000 ) #define ERRFILE_ib_cm ( ERRFILE_NET | 0x001e0000 ) +#define ERRFILE_net80211 ( ERRFILE_NET | 0x001f0000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) diff --git a/src/include/gpxe/ieee80211.h b/src/include/gpxe/ieee80211.h new file mode 100644 index 000000000..e2d251914 --- /dev/null +++ b/src/include/gpxe/ieee80211.h @@ -0,0 +1,1174 @@ +#ifndef _GPXE_IEEE80211_H +#define _GPXE_IEEE80211_H + +#include <gpxe/if_ether.h> /* 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 */ +#define IEEE80211_MAX_CRYPTO_TRAILER 12 + +/** Total maximum cryptographic overhead */ +#define IEEE80211_MAX_CRYPTO_OVERHEAD 20 + +/** 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, 20 bytes of + * crypto overhead, and 2304 data bytes. + */ +#define IEEE80211_MAX_FRAME_LEN 2356 + +/** 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 diff --git a/src/include/gpxe/net80211.h b/src/include/gpxe/net80211.h new file mode 100644 index 000000000..a1bddd5db --- /dev/null +++ b/src/include/gpxe/net80211.h @@ -0,0 +1,983 @@ +#ifndef _GPXE_NET80211_H +#define _GPXE_NET80211_H + +#include <gpxe/process.h> +#include <gpxe/ieee80211.h> +#include <gpxe/iobuf.h> +#include <gpxe/netdevice.h> +#include <gpxe/rc80211.h> + +/** @file + * + * The gPXE 802.11 MAC layer. + */ + +/* + * Major things NOT YET supported: + * - any type of security + * - 802.11n + * + * Major things that probably will NEVER be supported, barring a + * compelling use case and/or corporate sponsorship: + * - QoS + * - 802.1X authentication ("WPA Enterprise") + * - Contention-free periods + * - "ad-hoc" networks (IBSS), monitor mode, host AP mode + * - hidden networks on the 5GHz band due to regulatory issues + * - spectrum management on the 5GHz band (TPC and DFS), as required + * in some non-US regulatory domains + * - Clause 14 PHYs (Frequency-Hopping Spread Spectrum on 2.4GHz) + * and Clause 16 PHYs (infrared) - I'm not aware of any real-world + * use of these. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/* All 802.11 devices are handled using a generic "802.11 device" + net_device, with a link in its `priv' field to a net80211_device + which we use to handle 802.11-specific details. */ + + +/** @defgroup net80211_band RF bands on which an 802.11 device can transmit */ +/** @{ */ + +/** The 2.4 GHz ISM band, unlicensed in most countries */ +#define NET80211_BAND_2GHZ (1 << 0) +/** The band from 4.9 GHz to 5.7 GHz, which tends to be more restricted */ +#define NET80211_BAND_5GHZ (1 << 1) + +/** @} */ + + +/** @defgroup net80211_mode 802.11 operation modes supported by hardware */ +/** @{ */ + +/** 802.11a: 54 Mbps operation using OFDM signaling on the 5GHz band */ +#define NET80211_MODE_A (1 << 0) + +/** 802.11b: 1-11 Mbps operation using DSSS/CCK signaling on the 2.4GHz band */ +#define NET80211_MODE_B (1 << 1) + +/** 802.11g: 54 Mbps operation using ERP/OFDM signaling on the 2.4GHz band */ +#define NET80211_MODE_G (1 << 2) + +/** 802.11n: High-rate operation using MIMO technology on 2.4GHz or 5GHz */ +#define NET80211_MODE_N (1 << 3) + +/** @} */ + + +/** @defgroup net80211_cfg Constants for the net80211 config callback */ +/** @{ */ + +/** Channel choice (@c dev->channel) or regulatory parameters have changed */ +#define NET80211_CFG_CHANNEL (1 << 0) + +/** Requested transmission rate (@c dev->rate) has changed */ +#define NET80211_CFG_RATE (1 << 1) + +/** Association has been established with a new BSS (@c dev->bssid) */ +#define NET80211_CFG_ASSOC (1 << 2) + +/** Low-level link parameters (short preamble, protection, etc) have changed */ +#define NET80211_CFG_PHY_PARAMS (1 << 3) + +/** @} */ + + +/** An 802.11 security handshaking protocol */ +enum net80211_security_proto { + /** No security handshaking + * + * This might be used with an open network or with WEP, as + * WEP does not have a cryptographic handshaking phase. + */ + NET80211_SECPROT_NONE = 0, + + /** Pre-shared key handshaking + * + * This implements the "WPA Personal" handshake. 802.1X + * authentication is not performed -- the user supplies a + * pre-shared key directly -- but there is a 4-way handshake + * between client and AP to verify that both have the same key + * without revealing the contents of that key. + */ + NET80211_SECPROT_PSK = 1, + + /** Full EAP 802.1X handshaking + * + * This implements the "WPA Enterprise" handshake, connecting + * to an 802.1X authentication server to provide credentials + * and receive a pairwise master key (PMK), which is then used + * in the same 4-way handshake as the PSK method. + */ + NET80211_SECPROT_EAP = 2, +}; + + +/** An 802.11 data encryption algorithm */ +enum net80211_crypto_alg { + /** No security, an "Open" network */ + NET80211_CRYPT_NONE = 0, + + /** Network protected with WEP (awful RC4-based system) + * + * WEP uses a naive application of RC4, with a monotonically + * increasing initialization vector that is prepended to the + * key to initialize the RC4 keystream. It is highly insecure + * and can be completely cracked or subverted using automated, + * robust, freely available tools (aircrack-ng) in minutes. + * + * 40-bit and 104-bit WEP are differentiated only by the size + * of the key. They may be advertised as 64-bit and 128-bit, + * counting the non-random IV as part of the key bits. + */ + NET80211_CRYPT_WEP = 1, + + /** Network protected with TKIP (better RC4-based system) + * + * Usually known by its trade name of WPA (Wi-Fi Protected + * Access), TKIP implements a message integrity code (MIC) + * called Michael, a timestamp counter for replay prevention, + * and a key mixing function that together remove almost all + * the security problems with WEP. Countermeasures are + * implemented to prevent high data-rate attacks. + * + * There exists one known attack on TKIP, that allows one to + * send between 7 and 15 arbitrary short data packets on a + * QoS-enabled network given about an hour of data + * gathering. Since gPXE does not support QoS for 802.11 + * networks, this is not a threat to us. The only other method + * is a brute-force passphrase attack. + */ + NET80211_CRYPT_TKIP = 2, + + /** Network protected with CCMP (AES-based system) + * + * Often called WPA2 in commerce, or RSNA (Robust Security + * Network Architecture) in the 802.11 standard, CCMP is + * highly secure and does not have any known attack vectors. + * Since it is based on a block cipher, the statistical + * correlation and "chopchop" attacks used with great success + * against WEP and minor success against TKIP fail. + */ + NET80211_CRYPT_CCMP = 3, +}; + + +/** @defgroup net80211_state Bits for the 802.11 association state field */ +/** @{ */ + +/** An error code indicating the failure mode, or 0 if successful */ +#define NET80211_STATUS_MASK 0x7F + +/** Whether the error code provided is a "reason" code, not a "status" code */ +#define NET80211_IS_REASON 0x80 + +/** Whether we have found the network we will be associating with */ +#define NET80211_PROBED (1 << 8) + +/** Whether we have successfully authenticated with the network + * + * This usually has nothing to do with actual security; it is a + * holdover from older 802.11 implementation ideas. + */ +#define NET80211_AUTHENTICATED (1 << 9) + +/** Whether we have successfully associated with the network */ +#define NET80211_ASSOCIATED (1 << 10) + +/** Whether we have completed security handshaking with the network + * + * Once this is set, we can send data packets. For that reason this + * bit is set even in cases where no security handshaking is + * required. + */ +#define NET80211_CRYPTO_SYNCED (1 << 11) + +/** Whether the auto-association task is running */ +#define NET80211_WORKING (1 << 12) + +/** Whether the auto-association task is waiting for a reply from the AP */ +#define NET80211_WAITING (1 << 13) + +/** Whether the auto-association task should be suppressed + * + * This is set by the `iwlist' command so that it can open the device + * without starting another probe process that will interfere with its + * own. + */ +#define NET80211_NO_ASSOC (1 << 14) + +/** Whether this association was performed using a broadcast SSID + * + * If the user opened this device without netX/ssid set, the device's + * SSID will be set to that of the network it chooses to associate + * with, but the netX/ssid setting will remain blank. If we don't + * remember that we started from no specified SSID, it will appear + * every time settings are updated (e.g. after DHCP) that we need to + * reassociate due to the difference between the set SSID and our own. + */ +#define NET80211_AUTO_SSID (1 << 15) + + +/** @} */ + + +/** @defgroup net80211_phy 802.11 physical layer flags */ +/** @{ */ + +/** Whether to use RTS/CTS or CTS-to-self protection for transmissions + * + * Since the RTS or CTS is transmitted using 802.11b signaling, and + * includes a field indicating the amount of time that will be used by + * transmission of the following packet, this serves as an effective + * protection mechanism to avoid 802.11b clients interfering with + * 802.11g clients on mixed networks. + */ +#define NET80211_PHY_USE_PROTECTION (1 << 1) + +/** Whether to use 802.11b short preamble operation + * + * Short-preamble operation can moderately increase throughput on + * 802.11b networks operating between 2Mbps and 11Mbps. It is + * irrelevant for 802.11g data rates, since they use a different + * modulation scheme. + */ +#define NET80211_PHY_USE_SHORT_PREAMBLE (1 << 2) + +/** Whether to use 802.11g short slot operation + * + * This affects a low-level timing parameter of 802.11g transmissions. + */ +#define NET80211_PHY_USE_SHORT_SLOT (1 << 3) + +/** @} */ + + +/** The maximum number of TX rates we allow to be configured simultaneously */ +#define NET80211_MAX_RATES 16 + +/** The maximum number of channels we allow to be configured simultaneously */ +#define NET80211_MAX_CHANNELS 32 + +/** Seconds we'll wait to get all fragments of a packet */ +#define NET80211_FRAG_TIMEOUT 2 + +/** The number of fragments we can receive at once + * + * The 802.11 standard requires that this be at least 3. + */ +#define NET80211_NR_CONCURRENT_FRAGS 3 + +/** Maximum TX power to allow (dBm), if we don't get a regulatory hint */ +#define NET80211_REG_TXPOWER 20 + + +struct net80211_device; + +/** Operations that must be implemented by an 802.11 driver */ +struct net80211_device_operations { + /** Open 802.11 device + * + * @v dev 802.11 device + * @ret rc Return status code + * + * This method should allocate RX I/O buffers and enable the + * hardware to start transmitting and receiving packets on the + * channels its net80211_register() call indicated it could + * handle. It does not need to tune the antenna to receive + * packets on any particular channel. + */ + int ( * open ) ( struct net80211_device *dev ); + + /** Close 802.11 network device + * + * @v dev 802.11 device + * + * This method should stop the flow of packets, and call + * net80211_tx_complete() for any packets remaining in the + * device's TX queue. + */ + void ( * close ) ( struct net80211_device *dev ); + + /** Transmit packet on 802.11 network device + * + * @v dev 802.11 device + * @v iobuf I/O buffer + * @ret rc Return status code + * + * This method should cause the hardware to initiate + * transmission of the I/O buffer, using the channel and rate + * most recently indicated by an appropriate call to the + * @c config callback. The 802.11 layer guarantees that said + * channel and rate will be the same as those currently + * reflected in the fields of @a dev. + * + * If this method returns success, the I/O buffer remains + * owned by the network layer's TX queue, and the driver must + * eventually call net80211_tx_complete() to free the buffer + * whether transmission succeeded or not. If this method + * returns failure, it will be interpreted as "failure to + * enqueue buffer" and the I/O buffer will be immediately + * released. + * + * This method is guaranteed to be called only when the device + * is open. + */ + int ( * transmit ) ( struct net80211_device *dev, + struct io_buffer *iobuf ); + + /** Poll for completed and received packets + * + * @v dev 802.11 device + * + * This method should cause the hardware to check for + * completed transmissions and received packets. Any received + * packets should be delivered via net80211_rx(), and + * completed transmissions should be indicated using + * net80211_tx_complete(). + * + * This method is guaranteed to be called only when the device + * is open. + */ + void ( * poll ) ( struct net80211_device *dev ); + + /** Enable or disable interrupts + * + * @v dev 802.11 device + * @v enable If TRUE, interrupts should be enabled + */ + void ( * irq ) ( struct net80211_device *dev, int enable ); + + /** Update hardware state to match 802.11 layer state + * + * @v dev 802.11 device + * @v changed Set of flags indicating what may have changed + * @ret rc Return status code + * + * This method should cause the hardware state to be + * reinitialized from the state indicated in fields of + * net80211_device, in the areas indicated by bits set in + * @a changed. If the hardware is unable to do so, this method + * may return an appropriate error indication. + * + * This method is guaranteed to be called only when the device + * is open. + */ + int ( * config ) ( struct net80211_device *dev, int changed ); +}; + +/** An 802.11 RF channel. */ +struct net80211_channel +{ + /** The band with which this channel is associated */ + u8 band; + + /** A channel number interpreted according to the band + * + * The 2.4GHz band uses channel numbers from 1-13 at 5MHz + * intervals such that channel 1 is 2407 MHz; channel 14, + * legal for use only in Japan, is defined separately as 2484 + * MHz. Adjacent channels will overlap, since 802.11 + * transmissions use a 20 MHz (4-channel) bandwidth. Most + * commonly, channels 1, 6, and 11 are used. + * + * The 5GHz band uses channel numbers derived directly from + * the frequency; channel 0 is 5000 MHz, and channels are + * always spaced 5 MHz apart. Channel numbers over 180 are + * relative to 4GHz instead of 5GHz, but these are rarely + * seen. Most channels are not legal for use. + */ + u8 channel_nr; + + /** The center frequency for this channel + * + * Currently a bandwidth of 20 MHz is assumed. + */ + u16 center_freq; + + /** Maximum allowable transmit power, in dBm + * + * This should be interpreted as EIRP, the power supplied to + * an ideal isotropic antenna in order to achieve the same + * average signal intensity as the real hardware at a + * particular distance. + * + * Currently no provision is made for directional antennas. + */ + u8 maxpower; +}; + +/** Information on the capabilities of an 802.11 hardware device + * + * In its probe callback, an 802.11 driver must read hardware + * registers to determine the appropriate contents of this structure, + * fill it, and pass it to net80211_register() so that the 802.11 + * layer knows how to treat the hardware and what to advertise as + * supported to access points. + */ +struct net80211_hw_info +{ + /** Default hardware MAC address. + * + * The user may change this by setting the @c netX/mac setting + * before the driver's open function is called; in that case + * the driver must set the hardware MAC address to the address + * contained in the wrapping net_device's ll_addr field, or if + * that is impossible, set that ll_addr field back to the + * unchangeable hardware MAC address. + */ + u8 hwaddr[ETH_ALEN]; + + /** A bitwise OR of the 802.11x modes supported by this device */ + int modes; + + /** A bitwise OR of the bands on which this device can communicate */ + int bands; + + /** A set of flags indicating peculiarities of this device. */ + enum { + /** Received frames include a frame check sequence. */ + NET80211_HW_RX_HAS_FCS = (1 << 1), + + /** Hardware doesn't support 2.4GHz short preambles + * + * This is only relevant for 802.11b operation above + * 2Mbps. All 802.11g devices support short preambles. + */ + NET80211_HW_NO_SHORT_PREAMBLE = (1 << 2), + + /** Hardware doesn't support 802.11g short slot operation */ + NET80211_HW_NO_SHORT_SLOT = (1 << 3), + } flags; + + /** Signal strength information that can be provided by the device + * + * Signal strength is passed to net80211_rx(), primarily to + * allow determination of the closest access point for a + * multi-AP network. The units are provided for completeness + * of status displays. + */ + enum { + /** No signal strength information supported */ + NET80211_SIGNAL_NONE = 0, + /** Signal strength in arbitrary units */ + NET80211_SIGNAL_ARBITRARY, + /** Signal strength in decibels relative to arbitrary base */ + NET80211_SIGNAL_DB, + /** Signal strength in decibels relative to 1mW */ + NET80211_SIGNAL_DBM, + } signal_type; + + /** Maximum signal in arbitrary cases + * + * If signal_type is NET80211_SIGNAL_ARBITRARY or + * NET80211_SIGNAL_DB, the driver should report it on a scale + * from 0 to signal_max. + */ + unsigned signal_max; + + /** List of transmission rates supported by the card + * + * Rates should be in 100kbps increments (e.g. 11 Mbps would + * be represented as the number 110). + */ + u16 supported_rates[NET80211_MAX_RATES]; + + /** Number of supported rates */ + int nr_supported_rates; + + /** Estimate of the time required to change channels, in microseconds + * + * If this is not known, a guess on the order of a few + * milliseconds (value of 1000-5000) is reasonable. + */ + unsigned channel_change_time; +}; + +/** Structure tracking received fragments for a packet + * + * We set up a fragment cache entry when we receive a packet marked as + * fragment 0 with the "more fragments" bit set in its frame control + * header. We are required by the 802.11 standard to track 3 + * fragmented packets arriving simultaneously; if we receive more we + * may drop some. Upon receipt of a new fragment-0 packet, if no entry + * is available or expired, we take over the most @e recent entry for + * the new packet, since we don't want to starve old entries from ever + * finishing at all. If we get a fragment after the zeroth with no + * cache entry for its packet, we drop it. + */ +struct net80211_frag_cache +{ + /** Whether this cache entry is in use */ + u8 in_use; + + /** Sequence number of this MSDU (packet) */ + u16 seqnr; + + /** Timestamp from point at which first fragment was collected */ + u32 start_ticks; + + /** Buffers for each fragment */ + struct io_buffer *iob[16]; +}; + +/** Interface to an 802.11 cryptographic algorithm + * + * Cryptographic algorithms define a net80211_crypto structure + * statically, using a gPXE linker table to make it available to the + * 802.11 layer. When the algorithm needs to be used, the 802.11 code + * will allocate a copy of the static definition plus whatever space + * the algorithm has requested for private state, and point + * net80211_device::crypto at it. + */ +struct net80211_crypto +{ + /** The cryptographic algorithm implemented */ + enum net80211_crypto_alg algorithm; + + /** Initialize cryptographic algorithm using a given key + * + * @v crypto 802.11 cryptographic algorithm + * @v key Pointer to key bytes + * @v keylen Number of key bytes + * @ret rc Return status code + * + * This method is passed the communication key provided by the + * security handshake handler, which will already be in the + * low-level form required. + */ + int ( * initialize ) ( struct net80211_crypto *crypto, u8 *key, + int keylen ); + + /** Encrypt a frame using the cryptographic algorithm + * + * @v crypto 802.11 cryptographic algorithm + * @v iob I/O buffer + * @ret eiob Newly allocated I/O buffer with encrypted packet + * + * This method is called to encrypt a single frame. It is + * guaranteed that initialize() will have completed + * successfully before this method is called. + * + * The frame passed already has an 802.11 header prepended, + * but the PROTECTED bit in the frame control field will not + * be set; this method is responsible for setting it. The + * returned I/O buffer should contain a complete copy of @a + * iob, including the 802.11 header, but with the PROTECTED + * bit set, the data encrypted, and whatever encryption + * headers/trailers are necessary added. + * + * This method should never free the passed I/O buffer. + * + * Return NULL if the packet could not be encrypted, due to + * memory limitations or otherwise. + */ + struct io_buffer * ( * encrypt ) ( struct net80211_crypto *crypto, + struct io_buffer *iob ); + + /** Decrypt a frame using the cryptographic algorithm + * + * @v crypto 802.11 cryptographic algorithm + * @v eiob Encrypted I/O buffer + * @ret iob Newly allocated I/O buffer with decrypted packet + * + * This method is called to decrypt a single frame. It is + * guaranteed that initialize() will have completed + * successfully before this method is called. + * + * Decryption follows the reverse of the pattern used for + * encryption: this method must copy the 802.11 header into + * the returned packet, decrypt the data stream, remove any + * encryption header or trailer, and clear the PROTECTED bit + * in the frame control header. + * + * This method should never free the passed I/O buffer. + * + * Return NULL if memory was not available for decryption, if + * a consistency or integrity check on the decrypted frame + * failed, or if the decrypted frame should not be processed + * by the network stack for any other reason. + */ + struct io_buffer * ( * decrypt ) ( struct net80211_crypto *crypto, + struct io_buffer *iob ); + + /** Length of private data requested to be allocated */ + int priv_len; + + /** Private data for the algorithm to store key and state info */ + void *priv; +}; + + +struct net80211_probe_ctx; +struct net80211_assoc_ctx; + + +/** Structure encapsulating the complete state of an 802.11 device + * + * An 802.11 device is always wrapped by a network device, and this + * network device is always pointed to by the @a netdev field. In + * general, operations should never be performed by 802.11 code using + * netdev functions directly. It is usually the case that the 802.11 + * layer might need to do some processing or bookkeeping on top of + * what the netdevice code will do. + */ +struct net80211_device +{ + /** The net_device that wraps us. */ + struct net_device *netdev; + + /** List of 802.11 devices. */ + struct list_head list; + + /** 802.11 device operations */ + struct net80211_device_operations *op; + + /** Driver private data */ + void *priv; + + /** Information about the hardware, provided to net80211_register() */ + struct net80211_hw_info *hw; + + /* ---------- Channel and rate fields ---------- */ + + /** A list of all possible channels we might use */ + struct net80211_channel channels[NET80211_MAX_CHANNELS]; + + /** The number of channels in the channels array */ + u8 nr_channels; + + /** The channel currently in use, as an index into the channels array */ + u8 channel; + + /** A list of all possible TX rates we might use + * + * Rates are in units of 100 kbps. + */ + u16 rates[NET80211_MAX_RATES]; + + /** The number of transmission rates in the rates array */ + u8 nr_rates; + + /** The rate currently in use, as an index into the rates array */ + u8 rate; + + /** The rate to use for RTS/CTS transmissions + * + * This is always the fastest basic rate that is not faster + * than the data rate in use. Also an index into the rates array. + */ + u8 rtscts_rate; + + /** Bitmask of basic rates + * + * If bit N is set in this value, with the LSB considered to + * be bit 0, then rate N in the rates array is a "basic" rate. + * + * We don't decide which rates are "basic"; our AP does, and + * we respect its wishes. We need to be able to identify basic + * rates in order to calculate the duration of a CTS packet + * used for 802.11 g/b interoperability. + */ + u32 basic_rates; + + /* ---------- Association fields ---------- */ + + /** The asynchronous association process. + * + * When an 802.11 netdev is opened, or when the user changes + * the SSID setting on an open 802.11 device, an + * autoassociation task is started by net80211_autoassocate() + * to associate with the new best network. The association is + * asynchronous, but no packets can be transmitted until it is + * complete. If it is successful, the wrapping net_device is + * set as "link up". If it fails, @c assoc_rc will be set with + * an error indication. + */ + struct process proc_assoc; + + /** Network with which we are associating + * + * This will be NULL when we are not actively in the process + * of associating with a network we have already successfully + * probed for. + */ + struct net80211_wlan *associating; + + /** Context for the association process + * + * This is a probe_ctx if the @c PROBED flag is not set in @c + * state, and an assoc_ctx otherwise. + */ + union { + struct net80211_probe_ctx *probe; + struct net80211_assoc_ctx *assoc; + } ctx; + + /** State of our association to the network + * + * Since the association process happens asynchronously, it's + * necessary to have some channel of communication so the + * driver can say "I got an association reply and we're OK" or + * similar. This variable provides that link. It is a bitmask + * of any of NET80211_PROBED, NET80211_AUTHENTICATED, + * NET80211_ASSOCIATED, NET80211_CRYPTO_SYNCED to indicate how + * far along in associating we are; NET80211_WORKING if the + * association task is running; and NET80211_WAITING if a + * packet has been sent that we're waiting for a reply to. We + * can only be crypto-synced if we're associated, we can + * only be associated if we're authenticated, we can only be + * authenticated if we've probed. + * + * If an association process fails (that is, we receive a + * packet with an error indication), the error code is copied + * into bits 6-0 of this variable and bit 7 is set to specify + * what type of error code it is. An AP can provide either a + * "status code" (0-51 are defined) explaining why it refused + * an association immediately, or a "reason code" (0-45 are + * defined) explaining why it canceled an association after it + * had originally OK'ed it. Status and reason codes serve + * similar functions, but they use separate error message + * tables. A gPXE-formatted return status code (negative) is + * placed in @c assoc_rc. + * + * If the failure to associate is indicated by a status code, + * the NET80211_IS_REASON bit will be clear; if it is + * indicated by a reason code, the bit will be set. If we were + * successful, both zero status and zero reason mean success, + * so there is no ambiguity. + * + * To prevent association when opening the device, user code + * can set the NET80211_NO_ASSOC bit. The final bit in this + * variable, NET80211_AUTO_SSID, is used to remember whether + * we picked our SSID through automated probing as opposed to + * user specification; the distinction becomes relevant in the + * settings applicator. + */ + u16 state; + + /** Return status code associated with @c state */ + int assoc_rc; + + /* ---------- Parameters of currently associated network ---------- */ + + /** 802.11 cryptographic algorithm for our current network + * + * For an open network, this will be set to NULL. + */ + struct net80211_crypto *crypto; + + /** MAC address of the access point most recently associated */ + u8 bssid[ETH_ALEN]; + + /** SSID of the access point we are or will be associated with + * + * Although the SSID field in 802.11 packets is generally not + * NUL-terminated, here and in net80211_wlan we add a NUL for + * convenience. + */ + char essid[IEEE80211_MAX_SSID_LEN+1]; + + /** Association ID given to us by the AP */ + u16 aid; + + /** TSFT value for last beacon received, microseconds */ + u64 last_beacon_timestamp; + + /** Time between AP sending beacons, microseconds */ + u32 tx_beacon_interval; + + /** Smoothed average time between beacons, microseconds */ + u32 rx_beacon_interval; + + /* ---------- Physical layer information ---------- */ + + /** Physical layer options + * + * These control the use of CTS protection, short preambles, + * and short-slot operation. + */ + int phy_flags; + + /** Signal strength of last received packet */ + int last_signal; + + /** Rate control state */ + struct rc80211_ctx *rctl; + + /* ---------- Packet handling state ---------- */ + + /** Fragment reassembly state */ + struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]; + + /** The sequence number of the last packet we sent */ + u16 last_tx_seqnr; + + /** Packet duplication elimination state + * + * We are only required to handle immediate duplicates for + * each direct sender, and since we can only have one direct + * sender (the AP), we need only keep the sequence control + * field from the most recent packet we've received. Thus, + * this field stores the last sequence control field we've + * received for a packet from the AP. + */ + u16 last_rx_seq; + + /** RX management packet queue + * + * Sometimes we want to keep probe, beacon, and action packets + * that we receive, such as when we're scanning for networks. + * Ordinarily we drop them because they are sent at a large + * volume (ten beacons per second per AP, broadcast) and we + * have no need of them except when we're scanning. + * + * When keep_mgmt is TRUE, received probe, beacon, and action + * management packets will be stored in this queue. + */ + struct list_head mgmt_queue; + + /** RX management packet info queue + * + * We need to keep track of the signal strength for management + * packets we're keeping, because that provides the only way + * to distinguish between multiple APs for the same network. + * Since we can't extend io_buffer to store signal, this field + * heads a linked list of "RX packet info" structures that + * contain that signal strength field. Its entries always + * parallel the entries in mgmt_queue, because the two queues + * are always added to or removed from in parallel. + */ + struct list_head mgmt_info_queue; + + /** Whether to store management packets + * + * Received beacon, probe, and action packets will be added to + * mgmt_queue (and their signal strengths added to + * mgmt_info_queue) only when this variable is TRUE. It should + * be set by net80211_keep_mgmt() (which returns the old + * value) only when calling code is prepared to poll the + * management queue frequently, because packets will otherwise + * pile up and exhaust memory. + */ + int keep_mgmt; +}; + +/** Structure representing a probed network. + * + * This is returned from the net80211_probe_finish functions and + * passed to the low-level association functions. At least essid, + * bssid, channel, beacon, and security must be filled in if you want + * to build this structure manually. + */ +struct net80211_wlan +{ + /** The human-readable ESSID (network name) + * + * Although the 802.11 SSID field is generally not + * NUL-terminated, the gPXE code adds an extra NUL (and + * expects one in this structure) for convenience. + */ + char essid[IEEE80211_MAX_SSID_LEN+1]; + + /** MAC address of the strongest-signal access point for this ESSID */ + u8 bssid[ETH_ALEN]; + + /** Signal strength of beacon frame from that access point */ + int signal; + + /** The channel on which that access point communicates + * + * This is a raw channel number (net80211_channel::channel_nr), + * so that it will not be affected by reconfiguration of the + * device channels array. + */ + int channel; + + /** The complete beacon or probe-response frame received */ + struct io_buffer *beacon; + + /** Security handshaking method used on the network */ + enum net80211_security_proto handshaking; + + /** Cryptographic algorithm used on the network */ + enum net80211_crypto_alg crypto; + + /** Link to allow chaining multiple structures into a list to + be returned from net80211_probe_finish_all(). */ + struct list_head list; +}; + + +/** + * @defgroup net80211_probe 802.11 network location API + * @{ + */ +int net80211_prepare_probe ( struct net80211_device *dev, int band, + int active ); +struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev, + const char *essid, + int active ); +int net80211_probe_step ( struct net80211_probe_ctx *ctx ); +struct net80211_wlan * +net80211_probe_finish_best ( struct net80211_probe_ctx *ctx ); +struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx ); + +void net80211_free_wlan ( struct net80211_wlan *wlan ); +void net80211_free_wlanlist ( struct list_head *list ); +/** @} */ + + +/** + * @defgroup net80211_mgmt 802.11 network management API + * @{ + */ +struct net80211_device * net80211_get ( struct net_device *netdev ); +void net80211_autoassociate ( struct net80211_device *dev ); + +int net80211_change_channel ( struct net80211_device *dev, int channel ); +void net80211_set_rate_idx ( struct net80211_device *dev, int rate ); + +int net80211_keep_mgmt ( struct net80211_device *dev, int enable ); +struct io_buffer * net80211_mgmt_dequeue ( struct net80211_device *dev, + int *signal ); +int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc, + u8 bssid[ETH_ALEN], struct io_buffer *iob ); +/** @} */ + + +/** + * @defgroup net80211_assoc 802.11 network association API + * @{ + */ +int net80211_prepare_assoc ( struct net80211_device *dev, + struct net80211_wlan *wlan ); +int net80211_send_auth ( struct net80211_device *dev, + struct net80211_wlan *wlan, int method ); +int net80211_send_assoc ( struct net80211_device *dev, + struct net80211_wlan *wlan ); +/** @} */ + + +/** + * @defgroup net80211_driver 802.11 driver interface API + * @{ + */ +struct net80211_device *net80211_alloc ( size_t priv_size ); +int net80211_register ( struct net80211_device *dev, + struct net80211_device_operations *ops, + struct net80211_hw_info *hw ); +void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob, + int signal, u16 rate ); +void net80211_rx_err ( struct net80211_device *dev, + struct io_buffer *iob, int rc ); +void net80211_tx_complete ( struct net80211_device *dev, + struct io_buffer *iob, int retries, int rc ); +void net80211_unregister ( struct net80211_device *dev ); +void net80211_free ( struct net80211_device *dev ); +/** @} */ + + +#endif diff --git a/src/include/gpxe/rc80211.h b/src/include/gpxe/rc80211.h new file mode 100644 index 000000000..0856896c8 --- /dev/null +++ b/src/include/gpxe/rc80211.h @@ -0,0 +1,19 @@ +#ifndef _GPXE_RC80211_H +#define _GPXE_RC80211_H + +/** @file + * + * Rate-control algorithm prototype for 802.11. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct net80211_device; +struct rc80211_ctx; + +struct rc80211_ctx * rc80211_init ( struct net80211_device *dev ); +void rc80211_update_tx ( struct net80211_device *dev, int retries, int rc ); +void rc80211_update_rx ( struct net80211_device *dev, int retry, u16 rate ); +void rc80211_free ( struct rc80211_ctx *ctx ); + +#endif /* _GPXE_RC80211_H */ |
