19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Use is subject to license terms.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Copyright (c) 2001 Atsushi Onoe
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * All rights reserved.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Redistribution and use in source and binary forms, with or without
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * modification, are permitted provided that the following conditions
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * are met:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 1. Redistributions of source code must retain the above copyright
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * notice, this list of conditions and the following disclaimer.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 2. Redistributions in binary form must reproduce the above copyright
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * notice, this list of conditions and the following disclaimer in the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * documentation and/or other materials provided with the distribution.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 3. The name of the author may not be used to endorse or promote products
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * derived from this software without specific prior written permission.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Alternatively, this software may be distributed under the terms of the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * GNU General Public License ("GPL") version 2 as published by the Free
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Software Foundation.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Process received frame
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcstatic mblk_t *ieee80211_defrag(ieee80211com_t *, ieee80211_node_t *,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Process a received frame. The node associated with the sender
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * should be supplied. If nothing was found in the node table then
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the caller is assumed to supply a reference to ic_bss instead.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * The RSSI and a timestamp are also supplied. The RSSI data is used
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * during AP scanning to select a AP to associate with; it can have
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * any units so long as values have consistent units and higher values
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * mean ``better signal''. The receive timestamp is currently not used
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * by the 802.11 layer.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_input(ieee80211com_t *ic, mblk_t *mp, struct ieee80211_node *in,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Fastpath for A-MPDU reorder q resubmission. Frames
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * w/ M_AMPDU marked have already passed through here
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * but were received out of order and been held on the
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * reorder queue. When resubmitted they are marked
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * with the M_AMPDU flag and we can bypass most of the
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * normal processing.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang hdrspace = ieee80211_hdrspace(ic, wh); /* optimize */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* clear driver/net80211 flags before passing up */
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China in->in_inact = in->in_inact_reload;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Bit of a cheat here, we use a pointer for a 3-address
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * frame format but don't reference fields past outside
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * ieee80211_frame_min w/o first validating the data is
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * present.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: too short(2):"
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Data frame, validate the bssid.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* not interested in */
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: not to bss %s\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * For adhoc mode we cons up a node when it doesn't
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * exist. This should probably done after an ACL check.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Fake up a node for this newly
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * discovered member of the IBSS.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* NB: stat kept for alloc failure */
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China rxseq = LE_16(*(uint16_t *)wh->i_seq);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* duplicate, discard */
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: duplicate",
ff3124eff995e6cd8ebd8c6543648e0670920034ff "seqno <%u,%u> fragno <%u,%u> tid %u",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (type) {
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: data ",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * In IEEE802.11 network, multicast packet
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * sent from me is broadcasted from AP.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * It should be silently discarded for
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * SIMPLEX interface.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: multicast echo\n");
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: unknown dir 0x%x",
ff3124eff995e6cd8ebd8c6543648e0670920034ff "receive data, unknown opmode %u, skip\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Handle A-MPDU re-ordering. The station must be
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * associated and negotiated HT. The frame must be
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * a QoS frame (not QoS null data) and not previously
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * processed for A-MPDU re-ordering. If the frame is
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * to be processed directly then ieee80211_ampdu_reorder
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * will return 0; otherwise it has consumed the mbuf
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * and we should do nothing more with it.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Handle privacy requirements.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Discard encrypted frames when privacy off.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* NB: stats+msgs handled in crypto_decap */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Save QoS bits for use below--before we strip the header.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] :
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Next up, any fragmentation
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* Fragment dropped or frame not complete yet */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Next strip any MSDU crypto bits.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (key != NULL && !ieee80211_crypto_demic(ic, key, mp, 0)) {
ff3124eff995e6cd8ebd8c6543648e0670920034ff "data demic error\n");
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_dbg(IEEE80211_MSG_INPUT | IEEE80211_MSG_HT,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Only shared key auth frames with a challenge
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * should be encrypted, discard all others.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "%s WEP set but not permitted",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Discard encrypted frames when privacy off.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_input: "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "mgt WEP set but PRIVACY off");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* NB: stats+msgs handled in crypto_decap */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* should not come here */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * This function reassemble fragments.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * More fragments bit in the frame control means the packet is fragmented.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * While the sequence control field consists of 4-bit fragment number
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * field and a 12-bit sequence number field.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/* ARGSUSED */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_defrag(ieee80211com_t *ic, struct ieee80211_node *in, mblk_t *mp,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_frame *wh = (struct ieee80211_frame *)mp->b_rptr;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* Quick way out, if there's nothing to defragment */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (mp);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Remove frag to insure it doesn't get reaped by timer.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Should never happen. If the node is orphaned (not in
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the table) then input packets should not reach here.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Otherwise, a concurrent request that yanks the table
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * should be blocked by other interlocking and/or by first
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * shutting the driver down. Regardless, be defensive
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * here and just bail
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Validate new fragment is in order and
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * related to the previous ones.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Sequence control field contains 12-bit sequence no
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * and 4-bit fragment number. For fragemnts, the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * sequence no is not changed.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * NB: check seq # and frag together
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Unrelated fragment or no space for it,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * clear current fragments.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc } else { /* concatenate */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* track last seqnum and fragno */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Install received rate set information in the node's state block.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_setup_rates(struct ieee80211_node *in, const uint8_t *rates,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* skip 1 byte element ID and 1 byte length */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Tack on 11g extended supported rate element.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_setup_rates: %s",
ff3124eff995e6cd8ebd8c6543648e0670920034ff "[%s] extended rate set too large;"
ff3124eff995e6cd8ebd8c6543648e0670920034ff " only using %u of %u rates\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc bcopy(xrates + 2, rs->ir_rates + rs->ir_nrates, nxrates);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang return (ieee80211_fix_rate(in, &in->in_rates, flags));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Process open-system authentication response frame and start
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * association if the authentication request is accepted.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcstatic void
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_auth_open(ieee80211com_t *ic, struct ieee80211_frame *wh,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_node *in, uint16_t seq, uint16_t status)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (status != 0) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* i_fc[0] - frame control's type & subtype field */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_AUTH, "ieee80211_auth_open: "
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Allocate challenge text for use by shared-key authentication
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Return B_TRUE on success, B_FALST otherwise.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "[%s] shared key challenge alloc failed\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Process shared-key authentication response frames. If authentication
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * succeeds, start association; otherwise, restart scan.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcstatic void
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_auth_shared(ieee80211com_t *ic, struct ieee80211_frame *wh,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc uint8_t *frm, uint8_t *efrm, struct ieee80211_node *in, uint16_t seq,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Pre-shared key authentication is evil; accept
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * it only if explicitly configured (it is supported
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * mainly for compatibility with clients like OS X).
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_AUTH, "ieee80211_auth_shared: "
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Challenge text information element
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * frm[0] - element ID
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * frm[1] - length
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * frm[2]... - challenge text
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_auth_shared: ie %d%d too long\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (seq) {
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_auth_shared: no challenge\n");
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_auth_shared: bad challenge len %d\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (seq) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (status != 0) {
ff3124eff995e6cd8ebd8c6543648e0670920034ff "shared key auth failed (reason %d)\n",
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_auth_shared: bad opmode %u\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Kick the state machine. This short-circuits
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * using the mgt frame timeout to trigger the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * state transition.
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China bcopy(frm + 2, &c, 4);
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China return (frm[1] > 3 && LE_32(c) == ((WPA_OUI_TYPE << 24) | WPA_OUI));
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] << 8) | \
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (((uint8_t *)(p))[2] << 16) | (((uint8_t *)(p))[3] << 24)))
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] << 8))
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang return (frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI));
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang LE_READ_4(frm+2) == ((BCM_OUI_HTCAP<<24)|BCM_OUI));
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang LE_READ_4(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI));
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang/* ARGSUSED */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangieee80211_parse_wmeparams(struct ieee80211com *ic, uint8_t *frm,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (len < sizeof (struct ieee80211_wme_param) - 2) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_dbg(IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang return (-1);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang qosinfo = frm[offsetof(struct ieee80211_wme_param, wme_qosInfo)];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* do proper check for wraparound */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang frm += offsetof(struct ieee80211_wme_param, wme_acParams);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang for (i = 0; i < WME_NUM_AC; i++) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* NB: ACI not used */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Process a beacon/probe response frame.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * When the device is in station mode, create a node and add it
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * to the node database for a new ESS or update node info if it's
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * already there.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcstatic void
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_recv_beacon(ieee80211com_t *ic, mblk_t *mp, struct ieee80211_node *in,
216e0daa70a0058c5dc883bc667cd6925015df0aQuaker Fang ic->ic_beaconmiss = 0; /* clear beacon miss counter */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * We process beacon/probe response frames:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * o when scanning, or
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * o station mode when associated (to collect state
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * updates such as 802.11g slot time), or
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * o adhoc mode (to discover neighbors)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Frames otherwise received are discarded.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (ic->ic_opmode == IEEE80211_M_STA && in->in_associd != 0) ||
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * beacon/probe response frame format
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [8] time stamp
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] beacon interval
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] capability information
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] ssid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] supported rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] country information
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] parameter set (FH/DS)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] erp information
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] extended supported rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] WME
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] WPA or RSN
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [tlv] HT capabilities
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [tlv] HT information
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China scan.bintval = LE_16(*(uint16_t *)frm);
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China scan.capinfo = LE_16(*(uint16_t *)frm);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* Agere element in beacon */
ff3124eff995e6cd8ebd8c6543648e0670920034ff IEEE80211_VERIFY_LENGTH(_PTRDIFF(efrm, frm), frm[1], return);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (*frm) {
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: ignore %s, "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "invalid ERP element; "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "length %u, expecting 1\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang else if (ic->ic_flags_ext & IEEE80211_FEXT_HTCOMPAT) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Accept pre-draft HT ie's if the
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * standard ones have not been seen.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: ignore %s,"
ff3124eff995e6cd8ebd8c6543648e0670920034ff "unhandled id %u, len %u, totallen %u",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* frm[1] - component length */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE, return);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN, return);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: ignore %s ,"
ff3124eff995e6cd8ebd8c6543648e0670920034ff "invalid channel %u\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Frame was received on a channel different from the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * one indicated in the DS params element id;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * silently discard it.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * NB: this can happen due to signal leakage.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * But we should take it for FH phy because
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the rssi value should be correct even for
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * different hop pattern in FH.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: ignore %s ,"
ff3124eff995e6cd8ebd8c6543648e0670920034ff "phytype %u channel %u marked for %u\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: ignore %s ,"
ff3124eff995e6cd8ebd8c6543648e0670920034ff "bogus beacon interval %u\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Process HT ie's. This is complicated by our
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * accepting both the standard ie's and the pre-draft
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * vendor OUI ie's that some vendors still use/require.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * When operating in station mode, check for state updates.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Be careful to ignore beacons received while doing a
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * background scan. We consider only 11g/WMM stuff right now.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* record tsf of last beacon */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* count beacon frame for s/w bmiss handling */
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "[%s] cap change: before 0x%x, now 0x%x\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * NB: we assume short preamble doesn't
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * change dynamically
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Channel has been adjusted based on
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * negotiated HT parameters; force the
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * channel state to follow.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * If scanning, just pass information to the scan module.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_add_scan(ic, &scan, wh, subtype, rssi, rstamp);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China if (ic->ic_opmode == IEEE80211_M_IBSS &&
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China scan.capinfo & IEEE80211_CAPINFO_IBSS) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Create a new entry in the neighbor table.
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * Copy data from beacon to neighbor table.
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * Some of this information might change after
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * ieee80211_add_neighbor(), so we just copy
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * everything over to be safe.
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_init_neighbor(in, wh, &scan);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Perform input processing for 802.11 management frames.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * It's the default ic_recv_mgmt callback function for the interface
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * softc, ic. Tipically ic_recv_mgmt is called within ieee80211_input()
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_recv_mgmt(ieee80211com_t *ic, mblk_t *mp, struct ieee80211_node *in,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_recv_beacon(ic, mp, in, subtype, rssi, rstamp);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * prreq frame format
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] ssid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] supported rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] extended supported rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (*frm) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, break);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China if (xrates != NULL) {
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_VERIFY_ELEMENT(xrates,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_RATE_MAXSIZE - rates[1], break);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, break);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China if (ic->ic_flags & IEEE80211_F_HIDESSID) {
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China if (ssid == NULL || ssid[1] == 0) {
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_dbg(IEEE80211_MSG_INPUT,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "ieee80211_recv_mgmt: ignore %s, "
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "no ssid with ssid suppression enabled",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_SUBTYPE_NAME(subtype));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Cannot tell if the sender is operating
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * in ibss mode. But we need a new node to
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * send the response so blindly add them to the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * neighbor table.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ASSOC, "ieee80211_recv_mgmt: "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "[%s] recv probe req\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Adjust and check station's rate list with device's
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * supported rate. Send back response if there is at
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * least one rate or the fixed rate(if being set) is
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * supported by both station and the device
ff3124eff995e6cd8ebd8c6543648e0670920034ff "%s recv'd rate set invalid",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Temporary node created just to send a
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * response, reclaim immediately.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * auth frame format
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] algorithm
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] sequence
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] status
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv*] challenge
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China algo = LE_16(*(uint16_t *)frm);
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China seq = LE_16(*(uint16_t *)(frm + 2));
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China status = LE_16(*(uint16_t *)(frm + 4));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_AUTH, "ieee80211_recv_mgmt: "
ff3124eff995e6cd8ebd8c6543648e0670920034ff "[%s] recv auth frame with algorithm %d seq %d\n",
ff3124eff995e6cd8ebd8c6543648e0670920034ff "ieee80211_recv_mgmt: ignore auth, %s\n",
ff3124eff995e6cd8ebd8c6543648e0670920034ff "TKIP countermeasures enabled");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (algo) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * asresp frame format
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] capability information
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] status
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] association ID
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] supported rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] extended supported rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [tlv] WME
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [tlv] HT capabilities
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [tlv] HT info
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China capinfo = LE_16(*(uint16_t *)frm);
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China status = LE_16(*(uint16_t *)frm);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (status != 0) {
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China associd = LE_16(*(uint16_t *)frm);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Do not discard frames containing proprietary Agere
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * elements 128 and 129, as the reported element length
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * is often wrong. Skip rest of the frame, since we can
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * not rely on the given element length making it
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * impossible to know where the next element starts
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (*frm) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Accept pre-draft HT ie's if the
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * standard ones have not been seen.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, break);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Adjust and check AP's rate list with device's
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * supported rate. Re-start scan if no rate is or the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * fixed rate(if being set) cannot be supported by
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * either AP or the device.
ff3124eff995e6cd8ebd8c6543648e0670920034ff "assoc failed (rate set mismatch)\n");
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Setup HT state according to the negotiation.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Channel has been adjusted based on
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * negotiated HT parameters; force the
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * channel state to follow.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Configure state now that we are associated.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Honor ERP protection.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * NB: in_erp should zero for non-11g operation.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * check ic_curmode anyway
ff3124eff995e6cd8ebd8c6543648e0670920034ff "assoc success: %s preamble, %s slot time%s%s\n",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * deauth frame format
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] reason
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China status = LE_16(*(uint16_t *)frm);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * disassoc frame format
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * [2] reason
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China status = LE_16(*(uint16_t *)frm);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * action frame format:
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [1] category
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [1] action
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * [tlv] parameters
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang sizeof (struct ieee80211_action), break);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* verify frame payloads but defer processing */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* maybe push this to method */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang sizeof (struct ieee80211_action_ba_addbarequest),
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang sizeof (struct ieee80211_action_ba_addbaresponse),
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc } /* switch subtype */