diff options
author | sam <sam@FreeBSD.org> | 2008-04-20 20:35:46 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2008-04-20 20:35:46 +0000 |
commit | 3569e353ca63336d80ab0143dd9669b0b9e6b123 (patch) | |
tree | bc7985c57e7ecfa1ac03e48c406a25430dba634b /sys/net80211/ieee80211_scan.h | |
parent | 682b4ae9be70192e298129ada878af3486683aaf (diff) | |
download | FreeBSD-src-3569e353ca63336d80ab0143dd9669b0b9e6b123.zip FreeBSD-src-3569e353ca63336d80ab0143dd9669b0b9e6b123.tar.gz |
Multi-bss (aka vap) support for 802.11 devices.
Note this includes changes to all drivers and moves some device firmware
loading to use firmware(9) and a separate module (e.g. ral). Also there
no longer are separate wlan_scan* modules; this functionality is now
bundled into the wlan module.
Supported by: Hobnob and Marvell
Reviewed by: many
Obtained from: Atheros (some bits)
Diffstat (limited to 'sys/net80211/ieee80211_scan.h')
-rw-r--r-- | sys/net80211/ieee80211_scan.h | 147 |
1 files changed, 109 insertions, 38 deletions
diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h index fed5e0b..df6ce1f7 100644 --- a/sys/net80211/ieee80211_scan.h +++ b/sys/net80211/ieee80211_scan.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2005-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,18 +27,69 @@ #ifndef _NET80211_IEEE80211_SCAN_H_ #define _NET80211_IEEE80211_SCAN_H_ +/* + * 802.11 scanning support. + * + * Scanning is the procedure by which a station locates a bss to join + * (infrastructure/ibss mode), or a channel to use (when operating as + * an ap or ibss master). Scans are either "active" or "passive". An + * active scan causes one or more probe request frames to be sent on + * visiting each channel. A passive request causes each channel in the + * scan set to be visited but no frames to be transmitted; the station + * only listens for traffic. Note that active scanning may still need + * to listen for traffic before sending probe request frames depending + * on regulatory constraints; the 802.11 layer handles this by generating + * a callback when scanning on a ``passive channel'' when the + * IEEE80211_FEXT_PROBECHAN flag is set. + * + * A scan operation involves constructing a set of channels to inspec + * (the scan set), visiting each channel and collecting information + * (e.g. what bss are present), and then analyzing the results to make + * decisions like which bss to join. This process needs to be as fast + * as possible so we do things like intelligently construct scan sets + * and dwell on a channel only as long as necessary. The scan code also + * maintains a cache of recent scan results and uses it to bypass scanning + * whenever possible. The scan cache is also used to enable roaming + * between access points when operating in infrastructure mode. + * + * Scanning is handled with pluggable modules that implement "policy" + * per-operating mode. The core scanning support provides an + * instrastructure to support these modules and exports a common api + * to the rest of the 802.11 layer. Policy modules decide what + * channels to visit, what state to record to make decisions (e.g. ap + * mode scanning for auto channel selection keeps significantly less + * state than sta mode scanning for an ap to associate to), and selects + * the final station/channel to return as the result of a scan. + * + * Scanning is done synchronously when initially bringing a vap to an + * operational state and optionally in the background to maintain the + * scan cache for doing roaming and rogue ap monitoring. Scanning is + * not tied to the 802.11 state machine that governs vaps though there + * is linkage to the IEEE80211_SCAN state. Only one vap at a time may + * be scanning; this scheduling policy is handled in ieee80211_new_state + * and is invisible to the scanning code. +*/ #define IEEE80211_SCAN_MAX IEEE80211_CHAN_MAX -struct ieee80211_scanner; +struct ieee80211_scanner; /* scan policy state */ struct ieee80211_scan_ssid { - int len; /* length in bytes */ - uint8_t ssid[IEEE80211_NWID_LEN]; /* ssid contents */ + int len; /* length in bytes */ + uint8_t ssid[IEEE80211_NWID_LEN]; /* ssid contents */ }; -#define IEEE80211_SCAN_MAX_SSID 1 +#define IEEE80211_SCAN_MAX_SSID 1 /* max # ssid's to probe */ +/* + * Scan state visible to the 802.11 layer. Scan parameters and + * results are stored in this data structure. The ieee80211_scan_state + * structure is extended with space that is maintained private to + * the core scanning support. We allocate one instance and link it + * to the ieee80211com structure; then share it between all associated + * vaps. We could allocate multiple of these, e.g. to hold multiple + * scan results, but this is sufficient for current needs. + */ struct ieee80211_scan_state { - struct ieee80211com *ss_ic; + struct ieee80211vap *ss_vap; const struct ieee80211_scanner *ss_ops; /* policy hookup, see below */ void *ss_priv; /* scanner private state */ uint16_t ss_flags; @@ -47,6 +98,8 @@ struct ieee80211_scan_state { #define IEEE80211_SCAN_PICK1ST 0x0004 /* ``hey sailor'' mode */ #define IEEE80211_SCAN_BGSCAN 0x0008 /* bg scan, exit ps at end */ #define IEEE80211_SCAN_ONCE 0x0010 /* do one complete pass */ +#define IEEE80211_SCAN_NOBCAST 0x0020 /* no broadcast probe req */ +#define IEEE80211_SCAN_NOJOIN 0x0040 /* no auto-sequencing */ #define IEEE80211_SCAN_GOTPICK 0x1000 /* got candidate, can stop */ uint8_t ss_nssid; /* # ssid's to probe/match */ struct ieee80211_scan_ssid ss_ssid[IEEE80211_SCAN_MAX_SSID]; @@ -65,48 +118,64 @@ struct ieee80211_scan_state { * ss_flags. It might be better to split this stuff out into * a separate variable to avoid confusion. */ -#define IEEE80211_SCAN_FLUSH 0x10000 /* flush candidate table */ -#define IEEE80211_SCAN_NOSSID 0x20000 /* don't update ssid list */ +#define IEEE80211_SCAN_FLUSH 0x00010000 /* flush candidate table */ +#define IEEE80211_SCAN_NOSSID 0x80000000 /* don't update ssid list */ struct ieee80211com; void ieee80211_scan_attach(struct ieee80211com *); void ieee80211_scan_detach(struct ieee80211com *); +void ieee80211_scan_vattach(struct ieee80211vap *); +void ieee80211_scan_vdetach(struct ieee80211vap *); void ieee80211_scan_dump_channels(const struct ieee80211_scan_state *); -int ieee80211_scan_update(struct ieee80211com *); #define IEEE80211_SCAN_FOREVER 0x7fffffff -int ieee80211_start_scan(struct ieee80211com *, int flags, u_int duration, +int ieee80211_start_scan(struct ieee80211vap *, int flags, + u_int duration, u_int mindwell, u_int maxdwell, u_int nssid, const struct ieee80211_scan_ssid ssids[]); -int ieee80211_check_scan(struct ieee80211com *, int flags, u_int duration, +int ieee80211_check_scan(struct ieee80211vap *, int flags, + u_int duration, u_int mindwell, u_int maxdwell, u_int nssid, const struct ieee80211_scan_ssid ssids[]); -int ieee80211_bg_scan(struct ieee80211com *); -void ieee80211_cancel_scan(struct ieee80211com *); -void ieee80211_scan_next(struct ieee80211com *); -void ieee80211_scan_done(struct ieee80211com *); +int ieee80211_check_scan_current(struct ieee80211vap *); +int ieee80211_bg_scan(struct ieee80211vap *, int); +void ieee80211_cancel_scan(struct ieee80211vap *); +void ieee80211_cancel_anyscan(struct ieee80211vap *); +void ieee80211_scan_next(struct ieee80211vap *); +void ieee80211_scan_done(struct ieee80211vap *); +void ieee80211_probe_curchan(struct ieee80211vap *, int); +struct ieee80211_channel *ieee80211_scan_pickchannel(struct ieee80211com *, int); struct ieee80211_scanparams; -void ieee80211_add_scan(struct ieee80211com *, +void ieee80211_add_scan(struct ieee80211vap *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, int subtype, int rssi, int noise, int rstamp); void ieee80211_scan_timeout(struct ieee80211com *); -void ieee80211_scan_assoc_success(struct ieee80211com *, +void ieee80211_scan_assoc_success(struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN]); enum { IEEE80211_SCAN_FAIL_TIMEOUT = 1, /* no response to mgmt frame */ IEEE80211_SCAN_FAIL_STATUS = 2 /* negative response to " " */ }; -void ieee80211_scan_assoc_fail(struct ieee80211com *, +void ieee80211_scan_assoc_fail(struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN], int reason); -void ieee80211_scan_flush(struct ieee80211com *); +void ieee80211_scan_flush(struct ieee80211vap *); struct ieee80211_scan_entry; typedef void ieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *); -void ieee80211_scan_iterate(struct ieee80211com *, +void ieee80211_scan_iterate(struct ieee80211vap *, ieee80211_scan_iter_func, void *); +enum { + IEEE80211_BPARSE_BADIELEN = 0x01, /* ie len past end of frame */ + IEEE80211_BPARSE_RATES_INVALID = 0x02, /* invalid RATES ie */ + IEEE80211_BPARSE_XRATES_INVALID = 0x04, /* invalid XRATES ie */ + IEEE80211_BPARSE_SSID_INVALID = 0x08, /* invalid SSID ie */ + IEEE80211_BPARSE_CHAN_INVALID = 0x10, /* invalid FH/DSPARMS chan */ + IEEE80211_BPARSE_OFFCHAN = 0x20, /* DSPARMS chan != curchan */ + IEEE80211_BPARSE_BINTVAL_INVALID= 0x40, /* invalid beacon interval */ +}; /* * Parameters supplied when adding/updating an entry in a @@ -116,14 +185,17 @@ void ieee80211_scan_iterate(struct ieee80211com *, * All multi-byte values must be in host byte order. */ struct ieee80211_scanparams { - uint16_t capinfo; /* 802.11 capabilities */ - uint16_t fhdwell; /* FHSS dwell interval */ - struct ieee80211_channel *curchan; - uint8_t bchan; /* chan# advertised inside beacon */ + uint8_t status; /* bitmask of IEEE80211_BPARSE_* */ + uint8_t chan; /* channel # from FH/DSPARMS */ + uint8_t bchan; /* curchan's channel # */ uint8_t fhindex; - uint8_t erp; + uint16_t fhdwell; /* FHSS dwell interval */ + uint16_t capinfo; /* 802.11 capabilities */ + uint16_t erp; /* NB: 0x100 indicates ie present */ uint16_t bintval; uint8_t timoff; + uint8_t *ies; /* all captured ies */ + size_t ies_len; /* length of all captured ies */ uint8_t *tim; uint8_t *tstamp; uint8_t *country; @@ -146,13 +218,14 @@ struct ieee80211_scanparams { struct ieee80211_scan_entry { uint8_t se_macaddr[IEEE80211_ADDR_LEN]; uint8_t se_bssid[IEEE80211_ADDR_LEN]; + /* XXX can point inside se_ies */ uint8_t se_ssid[2+IEEE80211_NWID_LEN]; uint8_t se_rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t se_xrates[2+IEEE80211_RATE_MAXSIZE]; uint32_t se_rstamp; /* recv timestamp */ union { uint8_t data[8]; - uint64_t tsf; + u_int64_t tsf; } se_tstamp; /* from last rcv'd beacon */ uint16_t se_intval; /* beacon interval (host byte order) */ uint16_t se_capinfo; /* capabilities (host byte order) */ @@ -160,16 +233,12 @@ struct ieee80211_scan_entry { uint16_t se_timoff; /* byte offset to TIM ie */ uint16_t se_fhdwell; /* FH only (host byte order) */ uint8_t se_fhindex; /* FH only */ - uint8_t se_erp; /* ERP from beacon/probe resp */ + uint8_t se_dtimperiod; /* DTIM period */ + uint16_t se_erp; /* ERP from beacon/probe resp */ int8_t se_rssi; /* avg'd recv ssi */ int8_t se_noise; /* noise floor */ - uint8_t se_dtimperiod; /* DTIM period */ - uint8_t *se_wpa_ie; /* captured WPA ie */ - uint8_t *se_rsn_ie; /* captured RSN ie */ - uint8_t *se_wme_ie; /* captured WME ie */ - uint8_t *se_htcap_ie; /* captured HTP cap ie */ - uint8_t *se_htinfo_ie; /* captured HTP info ie */ - uint8_t *se_ath_ie; /* captured Atheros ie */ + uint8_t se_cc[2]; /* captured country code */ + struct ieee80211_ies se_ies; /* captured ie's */ u_int se_age; /* age of entry (0 on create) */ }; MALLOC_DECLARE(M_80211_SCAN); @@ -184,14 +253,16 @@ struct ieee80211_scanner { int (*scan_attach)(struct ieee80211_scan_state *); int (*scan_detach)(struct ieee80211_scan_state *); int (*scan_start)(struct ieee80211_scan_state *, - struct ieee80211com *); + struct ieee80211vap *); int (*scan_restart)(struct ieee80211_scan_state *, - struct ieee80211com *); + struct ieee80211vap *); int (*scan_cancel)(struct ieee80211_scan_state *, - struct ieee80211com *); + struct ieee80211vap *); int (*scan_end)(struct ieee80211_scan_state *, - struct ieee80211com *); + struct ieee80211vap *); int (*scan_flush)(struct ieee80211_scan_state *); + struct ieee80211_channel *(*scan_pickchan)( + struct ieee80211_scan_state *, int); /* add an entry to the cache */ int (*scan_add)(struct ieee80211_scan_state *, const struct ieee80211_scanparams *, |