ieee80211_node.h revision 139530
1326941Sdim/*- 2326941Sdim * Copyright (c) 2001 Atsushi Onoe 3353358Sdim * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4353358Sdim * All rights reserved. 5353358Sdim * 6326941Sdim * Redistribution and use in source and binary forms, with or without 7326941Sdim * modification, are permitted provided that the following conditions 8326941Sdim * are met: 9326941Sdim * 1. Redistributions of source code must retain the above copyright 10326941Sdim * notice, this list of conditions and the following disclaimer. 11326941Sdim * 2. Redistributions in binary form must reproduce the above copyright 12326941Sdim * notice, this list of conditions and the following disclaimer in the 13326941Sdim * documentation and/or other materials provided with the distribution. 14326941Sdim * 3. The name of the author may not be used to endorse or promote products 15326941Sdim * derived from this software without specific prior written permission. 16326941Sdim * 17326941Sdim * Alternatively, this software may be distributed under the terms of the 18326941Sdim * GNU General Public License ("GPL") version 2 as published by the Free 19326941Sdim * Software Foundation. 20326941Sdim * 21344779Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22326941Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23326941Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24326941Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25326941Sdim * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26326941Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27326941Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28326941Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29326941Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30326941Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31341825Sdim * 32341825Sdim * $FreeBSD: head/sys/net80211/ieee80211_node.h 139530 2004-12-31 22:42:38Z sam $ 33341825Sdim */ 34341825Sdim#ifndef _NET80211_IEEE80211_NODE_H_ 35341825Sdim#define _NET80211_IEEE80211_NODE_H_ 36341825Sdim 37326941Sdim#include <net80211/ieee80211_ioctl.h> /* for ieee80211_nodestats */ 38341825Sdim 39341825Sdim/* 40326941Sdim * Each ieee80211com instance has a single timer that fires once a 41344779Sdim * second. This is used to initiate various work depending on the 42344779Sdim * state of the instance: scanning (passive or active), ``transition'' 43341825Sdim * (waiting for a response to a management frame when operating 44344779Sdim * as a station), and node inactivity processing (when operating 45344779Sdim * as an AP). For inactivity processing each node has a timeout 46344779Sdim * set in it's ni_inact field that is decremented on each timeout 47344779Sdim * and the node is reclaimed when the counter goes to zero. We 48326941Sdim * use different inactivity timeout values depending on whether 49344779Sdim * the node is associated and authorized (either by 802.1x or 50344779Sdim * open/shared key authentication) or associated but yet to be 51344779Sdim * authorized. The latter timeout is shorter to more aggressively 52344779Sdim * reclaim nodes that leave part way through the 802.1x exchange. 53326941Sdim */ 54344779Sdim#define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */ 55344779Sdim#define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT) /* initial */ 56344779Sdim#define IEEE80211_INACT_AUTH (180/IEEE80211_INACT_WAIT) /* associated but not authorized */ 57344779Sdim#define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT) /* authorized */ 58341825Sdim#define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */ 59344779Sdim#define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */ 60344779Sdim 61344779Sdim#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */ 62344779Sdim 63341825Sdim#define IEEE80211_NODE_HASHSIZE 32 64344779Sdim/* simple hash is enough for variation of macaddr */ 65344779Sdim#define IEEE80211_NODE_HASH(addr) \ 66344779Sdim (((const u_int8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % \ 67341825Sdim IEEE80211_NODE_HASHSIZE) 68344779Sdim 69344779Sdimstruct ieee80211_rsnparms { 70344779Sdim u_int8_t rsn_mcastcipher; /* mcast/group cipher */ 71344779Sdim u_int8_t rsn_mcastkeylen; /* mcast key length */ 72341825Sdim u_int8_t rsn_ucastcipherset; /* unicast cipher set */ 73326941Sdim u_int8_t rsn_ucastcipher; /* selected unicast cipher */ 74326941Sdim u_int8_t rsn_ucastkeylen; /* unicast key length */ 75326941Sdim u_int8_t rsn_keymgmtset; /* key mangement algorithms */ 76326941Sdim u_int8_t rsn_keymgmt; /* selected key mgmt algo */ 77344779Sdim u_int16_t rsn_caps; /* capabilities */ 78344779Sdim}; 79344779Sdim 80344779Sdimstruct ieee80211_node_table; 81326941Sdimstruct ieee80211com; 82326941Sdim 83326941Sdim/* 84326941Sdim * Node specific information. Note that drivers are expected 85326941Sdim * to derive from this structure to add device-specific per-node 86326941Sdim * state. This is done by overriding the ic_node_* methods in 87326941Sdim * the ieee80211com structure. 88326941Sdim */ 89344779Sdimstruct ieee80211_node { 90326941Sdim struct ieee80211com *ni_ic; 91344779Sdim struct ieee80211_node_table *ni_table; 92341825Sdim TAILQ_ENTRY(ieee80211_node) ni_list; 93326941Sdim LIST_ENTRY(ieee80211_node) ni_hash; 94344779Sdim u_int ni_refcnt; 95326941Sdim u_int ni_scangen; /* gen# for timeout scan */ 96326941Sdim u_int8_t ni_authmode; /* authentication algorithm */ 97326941Sdim u_int16_t ni_flags; /* special-purpose state */ 98326941Sdim#define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */ 99326941Sdim#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */ 100326941Sdim#define IEEE80211_NODE_ERP 0x0004 /* ERP enabled */ 101326941Sdim/* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */ 102326941Sdim#define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */ 103326941Sdim u_int16_t ni_associd; /* assoc response */ 104326941Sdim u_int16_t ni_txpower; /* current transmit power */ 105326941Sdim u_int16_t ni_vlan; /* vlan tag */ 106326941Sdim u_int32_t *ni_challenge; /* shared-key challenge */ 107326941Sdim u_int8_t *ni_wpa_ie; /* captured WPA/RSN ie */ 108326941Sdim u_int8_t *ni_wme_ie; /* captured WME ie */ 109326941Sdim u_int16_t ni_txseqs[17]; /* tx seq per-tid */ 110326941Sdim u_int16_t ni_rxseqs[17]; /* rx seq previous per-tid*/ 111326941Sdim u_int32_t ni_rxfragstamp; /* time stamp of last rx frag */ 112326941Sdim struct mbuf *ni_rxfrag[3]; /* rx frag reassembly */ 113326941Sdim struct ieee80211_rsnparms ni_rsn; /* RSN/WPA parameters */ 114326941Sdim struct ieee80211_key ni_ucastkey; /* unicast key */ 115326941Sdim 116326941Sdim /* hardware */ 117326941Sdim u_int32_t ni_rstamp; /* recv timestamp */ 118326941Sdim u_int8_t ni_rssi; /* recv ssi */ 119326941Sdim 120326941Sdim /* header */ 121326941Sdim u_int8_t ni_macaddr[IEEE80211_ADDR_LEN]; 122326941Sdim u_int8_t ni_bssid[IEEE80211_ADDR_LEN]; 123326941Sdim 124326941Sdim /* beacon, probe response */ 125326941Sdim union { 126326941Sdim u_int8_t data[8]; 127326941Sdim u_int64_t tsf; 128326941Sdim } ni_tstamp; /* from last rcv'd beacon */ 129326941Sdim u_int16_t ni_intval; /* beacon interval */ 130326941Sdim u_int16_t ni_capinfo; /* capabilities */ 131326941Sdim u_int8_t ni_esslen; 132326941Sdim u_int8_t ni_essid[IEEE80211_NWID_LEN]; 133326941Sdim struct ieee80211_rateset ni_rates; /* negotiated rate set */ 134326941Sdim struct ieee80211_channel *ni_chan; 135326941Sdim u_int16_t ni_fhdwell; /* FH only */ 136326941Sdim u_int8_t ni_fhindex; /* FH only */ 137326941Sdim u_int8_t ni_erp; /* ERP from beacon/probe resp */ 138326941Sdim u_int16_t ni_timoff; /* byte offset to TIM ie */ 139326941Sdim 140326941Sdim /* others */ 141326941Sdim int ni_fails; /* failure count to associate */ 142326941Sdim short ni_inact; /* inactivity mark count */ 143326941Sdim short ni_inact_reload;/* inactivity reload value */ 144326941Sdim int ni_txrate; /* index to ni_rates[] */ 145326941Sdim struct ifqueue ni_savedq; /* ps-poll queue */ 146326941Sdim struct ieee80211_nodestats ni_stats; /* per-node statistics */ 147326941Sdim}; 148326941SdimMALLOC_DECLARE(M_80211_NODE); 149326941Sdim 150326941Sdim#define IEEE80211_NODE_AID(ni) IEEE80211_AID(ni->ni_associd) 151326941Sdim 152326941Sdim#define IEEE80211_NODE_STAT(ni,stat) (ni->ni_stats.ns_##stat++) 153326941Sdim#define IEEE80211_NODE_STAT_ADD(ni,stat,v) (ni->ni_stats.ns_##stat += v) 154326941Sdim#define IEEE80211_NODE_STAT_SET(ni,stat,v) (ni->ni_stats.ns_##stat = v) 155326941Sdim 156326941Sdimstatic __inline struct ieee80211_node * 157326941Sdimieee80211_ref_node(struct ieee80211_node *ni) 158326941Sdim{ 159326941Sdim ieee80211_node_incref(ni); 160326941Sdim return ni; 161326941Sdim} 162326941Sdim 163326941Sdimstatic __inline void 164326941Sdimieee80211_unref_node(struct ieee80211_node **ni) 165326941Sdim{ 166326941Sdim ieee80211_node_decref(*ni); 167326941Sdim *ni = NULL; /* guard against use */ 168326941Sdim} 169326941Sdim 170326941Sdimstruct ieee80211com; 171326941Sdim 172326941Sdimextern void ieee80211_node_attach(struct ieee80211com *); 173326941Sdimextern void ieee80211_node_lateattach(struct ieee80211com *); 174326941Sdimextern void ieee80211_node_detach(struct ieee80211com *); 175326941Sdim 176326941Sdimstatic __inline int 177326941Sdimieee80211_node_is_authorized(const struct ieee80211_node *ni) 178326941Sdim{ 179326941Sdim return (ni->ni_flags & IEEE80211_NODE_AUTH); 180326941Sdim} 181326941Sdim 182326941Sdimextern void ieee80211_node_authorize(struct ieee80211com *, 183326941Sdim struct ieee80211_node *); 184326941Sdimextern void ieee80211_node_unauthorize(struct ieee80211com *, 185326941Sdim struct ieee80211_node *); 186326941Sdim 187326941Sdimextern void ieee80211_begin_scan(struct ieee80211com *, int); 188326941Sdimextern int ieee80211_next_scan(struct ieee80211com *); 189326941Sdimextern void ieee80211_create_ibss(struct ieee80211com*, 190326941Sdim struct ieee80211_channel *); 191326941Sdimextern void ieee80211_reset_bss(struct ieee80211com *); 192326941Sdimextern void ieee80211_end_scan(struct ieee80211com *); 193341825Sdimextern int ieee80211_ibss_merge(struct ieee80211com *, 194341825Sdim struct ieee80211_node *); 195341825Sdimextern int ieee80211_sta_join(struct ieee80211com *, 196341825Sdim struct ieee80211_node *); 197341825Sdimextern void ieee80211_sta_leave(struct ieee80211com *, 198341825Sdim struct ieee80211_node *); 199341825Sdim 200341825Sdim/* 201341825Sdim * Table of ieee80211_node instances. Each ieee80211com 202341825Sdim * has at least one for holding the scan candidates. 203341825Sdim * When operating as an access point or in ibss mode there 204341825Sdim * is a second table for associated stations or neighbors. 205341825Sdim */ 206326941Sdimstruct ieee80211_node_table { 207326941Sdim struct ieee80211com *nt_ic; /* back reference */ 208326941Sdim ieee80211_node_lock_t nt_nodelock; /* on node table */ 209326941Sdim TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */ 210326941Sdim LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; 211326941Sdim const char *nt_name; /* for debugging */ 212326941Sdim ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */ 213326941Sdim u_int nt_scangen; /* gen# for timeout scan */ 214326941Sdim int nt_inact_timer; /* inactivity timer */ 215326941Sdim int nt_inact_init; /* initial node inact setting */ 216326941Sdim 217326941Sdim void (*nt_timeout)(struct ieee80211_node_table *); 218326941Sdim}; 219326941Sdimextern void ieee80211_node_table_reset(struct ieee80211_node_table *); 220326941Sdimextern void ieee80211_node_table_free(struct ieee80211_node_table *); 221326941Sdim 222326941Sdimextern struct ieee80211_node *ieee80211_alloc_node( 223326941Sdim struct ieee80211_node_table *, const u_int8_t *); 224326941Sdimextern struct ieee80211_node *ieee80211_dup_bss(struct ieee80211_node_table *, 225344779Sdim const u_int8_t *); 226344779Sdim#ifdef IEEE80211_DEBUG_REFCNT 227326941Sdimextern void ieee80211_free_node_debug(struct ieee80211_node *, 228326941Sdim const char *func, int line); 229341825Sdimextern struct ieee80211_node *ieee80211_find_node_debug( 230341825Sdim struct ieee80211_node_table *, const u_int8_t *, 231326941Sdim const char *func, int line); 232344779Sdimextern struct ieee80211_node * ieee80211_find_rxnode_debug( 233344779Sdim struct ieee80211com *, const struct ieee80211_frame_min *, 234344779Sdim const char *func, int line); 235344779Sdimextern struct ieee80211_node *ieee80211_find_txnode_debug( 236344779Sdim struct ieee80211com *, const u_int8_t *, 237344779Sdim const char *func, int line); 238344779Sdimextern struct ieee80211_node *ieee80211_find_node_with_channel_debug( 239326941Sdim struct ieee80211_node_table *, const u_int8_t *macaddr, 240344779Sdim struct ieee80211_channel *, const char *func, int line); 241326941Sdimextern struct ieee80211_node *ieee80211_find_node_with_ssid_debug( 242326941Sdim struct ieee80211_node_table *, const u_int8_t *macaddr, 243326941Sdim u_int ssidlen, const u_int8_t *ssid, 244326941Sdim const char *func, int line); 245326941Sdim#define ieee80211_free_node(ni) \ 246326941Sdim ieee80211_free_node_debug(ni, __func__, __LINE__) 247326941Sdim#define ieee80211_find_node(nt, mac) \ 248344779Sdim ieee80211_find_node_debug(nt, mac, __func__, __LINE__) 249344779Sdim#define ieee80211_find_rxnode(nt, wh) \ 250344779Sdim ieee80211_find_rxnode_debug(nt, wh, __func__, __LINE__) 251326941Sdim#define ieee80211_find_txnode(nt, mac) \ 252344779Sdim ieee80211_find_txnode_debug(nt, mac, __func__, __LINE__) 253344779Sdim#define ieee80211_find_node_with_channel(nt, mac, c) \ 254326941Sdim ieee80211_find_node_with_channel_debug(nt, mac, c, __func__, __LINE__) 255326941Sdim#define ieee80211_find_node_with_ssid(nt, mac, sl, ss) \ 256326941Sdim ieee80211_find_node_with_ssid_debug(nt, mac, sl, ss, __func__, __LINE__) 257326941Sdim#else 258326941Sdimextern void ieee80211_free_node(struct ieee80211_node *); 259326941Sdimextern struct ieee80211_node *ieee80211_find_node( 260344779Sdim struct ieee80211_node_table *, const u_int8_t *); 261344779Sdimextern struct ieee80211_node * ieee80211_find_rxnode( 262326941Sdim struct ieee80211com *, const struct ieee80211_frame_min *); 263326941Sdimextern struct ieee80211_node *ieee80211_find_txnode( 264326941Sdim struct ieee80211com *, const u_int8_t *); 265326941Sdimextern struct ieee80211_node *ieee80211_find_node_with_channel( 266326941Sdim struct ieee80211_node_table *, const u_int8_t *macaddr, 267326941Sdim struct ieee80211_channel *); 268326941Sdimextern struct ieee80211_node *ieee80211_find_node_with_ssid( 269326941Sdim struct ieee80211_node_table *, const u_int8_t *macaddr, 270326941Sdim u_int ssidlen, const u_int8_t *ssid); 271326941Sdim#endif 272326941Sdim 273326941Sdimtypedef void ieee80211_iter_func(void *, struct ieee80211_node *); 274326941Sdimextern void ieee80211_iterate_nodes(struct ieee80211_node_table *, 275326941Sdim ieee80211_iter_func *, void *); 276326941Sdim 277326941Sdimextern void ieee80211_dump_node(struct ieee80211_node_table *, 278326941Sdim struct ieee80211_node *); 279326941Sdimextern void ieee80211_dump_nodes(struct ieee80211_node_table *); 280326941Sdim 281326941Sdimextern struct ieee80211_node *ieee80211_fakeup_adhoc_node( 282326941Sdim struct ieee80211_node_table *nt, 283326941Sdim const u_int8_t macaddr[]); 284326941Sdimextern void ieee80211_node_join(struct ieee80211com *, 285326941Sdim struct ieee80211_node *, int); 286326941Sdimextern void ieee80211_node_leave(struct ieee80211com *, 287326941Sdim struct ieee80211_node *); 288344779Sdimextern u_int8_t ieee80211_getrssi(struct ieee80211com *ic); 289344779Sdim#endif /* _NET80211_IEEE80211_NODE_H_ */ 290344779Sdim