📄 ieee80211_beacon.c
字号:
/*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: ieee80211_beacon.c 1575 2006-05-19 20:42:19Z dyqith $ */#ifndef EXPORT_SYMTAB#define EXPORT_SYMTAB#endif/* * IEEE 802.11 beacon handling routines */#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/if_vlan.h>#include "if_media.h"#include <net80211/ieee80211_var.h>/* * XXX: Include an intra-module function from ieee80211_input.c. * When we move regdomain code out to separate .h/.c files * this should go to that .h file. */struct ieee80211_channel *ieee80211_doth_findchan(struct ieee80211vap *, u_int8_t);static u_int8_t *ieee80211_beacon_init(struct ieee80211_node *ni, struct ieee80211_beacon_offsets *bo, u_int8_t *frm){ struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; u_int16_t capinfo; struct ieee80211_rateset *rs = &ni->ni_rates; KASSERT(ic->ic_bsschan != IEEE80211_CHAN_ANYC, ("no bss chan")); /* XXX timestamp is set by hardware/driver */ memset(frm, 0, 8); frm += 8; /* beacon interval */ *(u_int16_t *)frm = htole16(ni->ni_intval); frm += 2; /* capability information */ if (vap->iv_opmode == IEEE80211_M_IBSS) capinfo = IEEE80211_CAPINFO_IBSS; else capinfo = IEEE80211_CAPINFO_ESS; if (vap->iv_flags & IEEE80211_F_PRIVACY) capinfo |= IEEE80211_CAPINFO_PRIVACY; if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && IEEE80211_IS_CHAN_2GHZ(ic->ic_bsschan)) capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; if (ic->ic_flags & IEEE80211_F_SHSLOT) capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; if (ic->ic_flags & IEEE80211_F_DOTH) capinfo |= IEEE80211_CAPINFO_SPECTRUM_MGMT; bo->bo_caps = (u_int16_t *)frm; *(u_int16_t *)frm = htole16(capinfo); frm += 2; /* ssid */ *frm++ = IEEE80211_ELEMID_SSID; if ((vap->iv_flags & IEEE80211_F_HIDESSID) == 0) { *frm++ = ni->ni_esslen; memcpy(frm, ni->ni_essid, ni->ni_esslen); frm += ni->ni_esslen; } else *frm++ = 0; /* supported rates */ frm = ieee80211_add_rates(frm, rs); /* XXX: better way to check this? */ /* XXX: how about DS ? */ if (!IEEE80211_IS_CHAN_FHSS(ic->ic_bsschan)) { *frm++ = IEEE80211_ELEMID_DSPARMS; *frm++ = 1; *frm++ = ieee80211_chan2ieee(ic, ic->ic_bsschan); } bo->bo_tim = frm; /* IBSS/TIM */ if (vap->iv_opmode == IEEE80211_M_IBSS) { *frm++ = IEEE80211_ELEMID_IBSSPARMS; *frm++ = 2; *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ bo->bo_tim_len = 0; } else { struct ieee80211_tim_ie *tie = (struct ieee80211_tim_ie *) frm; tie->tim_ie = IEEE80211_ELEMID_TIM; tie->tim_len = 4; /* length */ tie->tim_count = 0; /* DTIM count */ tie->tim_period = vap->iv_dtim_period; /* DTIM period */ tie->tim_bitctl = 0; /* bitmap control */ tie->tim_bitmap[0] = 0; /* Partial Virtual Bitmap */ frm += sizeof(struct ieee80211_tim_ie); bo->bo_tim_len = 1; } bo->bo_tim_trailer = frm; /* country */ if ((ic->ic_flags & IEEE80211_F_DOTH) || (ic->ic_flags_ext & IEEE80211_FEXT_COUNTRYIE)) { frm = ieee80211_add_country(frm, ic); } /* power constraint */ if (ic->ic_flags & IEEE80211_F_DOTH) { *frm++ = IEEE80211_ELEMID_PWRCNSTR; *frm++ = 1; *frm++ = IEEE80211_PWRCONSTRAINT_VAL(ic); } /* XXX: channel switch announcement ? */ bo->bo_chanswitch = frm; /* ERP */ if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) { bo->bo_erp = frm; frm = ieee80211_add_erp(frm, ic); } /* Ext. Supp. Rates */ frm = ieee80211_add_xrates(frm, rs); /* WME */ if (vap->iv_flags & IEEE80211_F_WME) { bo->bo_wme = frm; frm = ieee80211_add_wme_param(frm, &ic->ic_wme, IEEE80211_VAP_UAPSD_ENABLED(vap)); vap->iv_flags &= ~IEEE80211_F_WMEUPDATE; } /* WPA 1+2 */ if (vap->iv_flags & IEEE80211_F_WPA) frm = ieee80211_add_wpa(frm, vap); /* athAdvCaps */ bo->bo_ath_caps = frm; if (vap->iv_bss && vap->iv_bss->ni_ath_flags) frm = ieee80211_add_athAdvCap(frm, vap->iv_bss->ni_ath_flags, vap->iv_bss->ni_ath_defkeyindex); /* XR */ bo->bo_xr = frm;#ifdef ATH_SUPERG_XR if (vap->iv_xrvap && vap->iv_ath_cap & IEEE80211_ATHC_XR) /* XR */ frm = ieee80211_add_xr_param(frm, vap);#endif bo->bo_tim_trailerlen = frm - bo->bo_tim_trailer; bo->bo_chanswitch_trailerlen = frm - bo->bo_chanswitch; return frm;}/* * Allocate a beacon frame and fillin the appropriate bits. */struct sk_buff *ieee80211_beacon_alloc(struct ieee80211_node *ni, struct ieee80211_beacon_offsets *bo){ struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct ieee80211_frame *wh; struct sk_buff *skb; int pktlen; u_int8_t *frm; struct ieee80211_rateset *rs; /* * beacon frame format * [8] time stamp * [2] beacon interval * [2] cabability information * [tlv] ssid * [tlv] supported rates * [7] FH/DS parameter set * [tlv] IBSS/TIM parameter set * [tlv] country code * [3] power constraint * [5] channel switch announcement * [3] extended rate phy (ERP) * [tlv] extended supported rates * [tlv] WME parameters * [tlv] WPA/RSN parameters * [tlv] Atheros Advanced Capabilities * [tlv] AtherosXR parameters * XXX Vendor-specific OIDs (e.g. Atheros) * NB: we allocate the max space required for the TIM bitmap. */ rs = &ni->ni_rates; pktlen = 8 /* time stamp */ + sizeof(u_int16_t) /* beacon interval */ + sizeof(u_int16_t) /* capability information */ + 2 + ni->ni_esslen /* ssid */ + 2 + IEEE80211_RATE_SIZE /* supported rates */ + 7 /* FH/DS parameters max(7,3) */ + 2 + 4 + vap->iv_tim_len /* IBSS/TIM parameter set*/ + ic->ic_country_ie.country_len + 2 /* country code */ + 3 /* power constraint */ + 5 /* channel switch announcement */ + 3 /* ERP */ + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) /* Ext. Supp. Rates */ + (vap->iv_caps & IEEE80211_C_WME ? /* WME */ sizeof(struct ieee80211_wme_param) : 0) + (vap->iv_caps & IEEE80211_C_WPA ? /* WPA 1+2 */ 2 * sizeof(struct ieee80211_ie_wpa) : 0) + sizeof(struct ieee80211_ie_athAdvCap)#ifdef ATH_SUPERG_XR + (ic->ic_ath_cap & IEEE80211_ATHC_XR ? /* XR */ sizeof(struct ieee80211_xr_param) : 0)#endif ; skb = ieee80211_getmgtframe(&frm, pktlen); if (skb == NULL) { IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni, "%s: cannot get buf; size %u", __func__, pktlen); vap->iv_stats.is_tx_nobuf++; return NULL; } frm = ieee80211_beacon_init(ni, bo, frm); skb_trim(skb, frm - skb->data); wh = (struct ieee80211_frame *) skb_push(skb, sizeof(struct ieee80211_frame));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -