📄 ieee80211.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.c 1666 2006-07-04 10:22:11Z kelmo $ */#ifndef EXPORT_SYMTAB#define EXPORT_SYMTAB#endif/* * IEEE 802.11 generic handler */#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/rtnetlink.h> /* XXX for rtnl_lock */#include "if_media.h"#include <net80211/ieee80211_var.h>#include <net80211/if_athproto.h>const char *ieee80211_phymode_name[] = { "auto", /* IEEE80211_MODE_AUTO */ "11a", /* IEEE80211_MODE_11A */ "11b", /* IEEE80211_MODE_11B */ "11g", /* IEEE80211_MODE_11G */ "FH", /* IEEE80211_MODE_FH */ "turboA", /* IEEE80211_MODE_TURBO_A */ "turboG", /* IEEE80211_MODE_TURBO_G */ "staticTurboA", /* IEEE80211_MODE_TURBO_G */};EXPORT_SYMBOL(ieee80211_phymode_name);static void ieee80211com_media_status(struct net_device*, struct ifmediareq *);static int ieee80211com_media_change(struct net_device *);static struct net_device_stats *ieee80211_getstats(struct net_device *);static int ieee80211_change_mtu(struct net_device *, int);static void ieee80211_set_multicast_list(struct net_device *);MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");/* * Country Code Table for code-to-string conversion. */struct country_code_to_string{ u_int16_t iso_code; const char *iso_name;};/* * XXX: ugly, since must match define in other modules. */#define CTRY_DEBUG 0x1ff /* debug */#define CTRY_DEFAULT 0 /* default */static const struct country_code_to_string country_strings[] = { {CTRY_DEBUG, "DB" }, {CTRY_DEFAULT, "NA" }, {CTRY_ALBANIA, "AL" }, {CTRY_ALGERIA, "DZ" }, {CTRY_ARGENTINA, "AR" }, {CTRY_ARMENIA, "AM" }, {CTRY_AUSTRALIA, "AU" }, {CTRY_AUSTRIA, "AT" }, {CTRY_AZERBAIJAN, "AZ" }, {CTRY_BAHRAIN, "BH" }, {CTRY_BELARUS, "BY" }, {CTRY_BELGIUM, "BE" }, {CTRY_BELIZE, "BZ" }, {CTRY_BOLIVIA, "BO" }, {CTRY_BRAZIL, "BR" }, {CTRY_BRUNEI_DARUSSALAM, "BN" }, {CTRY_BULGARIA, "BG" }, {CTRY_CANADA, "CA" }, {CTRY_CHILE, "CL" }, {CTRY_CHINA, "CN" }, {CTRY_COLOMBIA, "CO" }, {CTRY_COSTA_RICA, "CR" }, {CTRY_CROATIA, "HR" }, {CTRY_CYPRUS, "CY" }, {CTRY_CZECH, "CZ" }, {CTRY_DENMARK, "DK" }, {CTRY_DOMINICAN_REPUBLIC, "DO" }, {CTRY_ECUADOR, "EC" }, {CTRY_EGYPT, "EG" }, {CTRY_EL_SALVADOR, "SV" }, {CTRY_ESTONIA, "EE" }, {CTRY_FINLAND, "FI" }, {CTRY_FRANCE, "FR" }, {CTRY_FRANCE2, "F2" }, {CTRY_GEORGIA, "GE" }, {CTRY_GERMANY, "DE" }, {CTRY_GREECE, "GR" }, {CTRY_GUATEMALA, "GT" }, {CTRY_HONDURAS, "HN" }, {CTRY_HONG_KONG, "HK" }, {CTRY_HUNGARY, "HU" }, {CTRY_ICELAND, "IS" }, {CTRY_INDIA, "IN" }, {CTRY_INDONESIA, "ID" }, {CTRY_IRAN, "IR" }, {CTRY_IRELAND, "IE" }, {CTRY_ISRAEL, "IL" }, {CTRY_ITALY, "IT" }, {CTRY_JAPAN, "JP" }, {CTRY_JAPAN1, "J1" }, {CTRY_JAPAN2, "J2" }, {CTRY_JAPAN3, "J3" }, {CTRY_JAPAN4, "J4" }, {CTRY_JAPAN5, "J5" }, {CTRY_JAPAN7, "JP" }, {CTRY_JAPAN6, "JP" }, {CTRY_JAPAN8, "JP" }, {CTRY_JAPAN9, "JP" }, {CTRY_JAPAN10, "JP" }, {CTRY_JAPAN11, "JP" }, {CTRY_JAPAN12, "JP" }, {CTRY_JAPAN13, "JP" }, {CTRY_JAPAN14, "JP" }, {CTRY_JAPAN15, "JP" }, {CTRY_JAPAN16, "JP" }, {CTRY_JAPAN17, "JP" }, {CTRY_JAPAN18, "JP" }, {CTRY_JAPAN19, "JP" }, {CTRY_JAPAN20, "JP" }, {CTRY_JAPAN21, "JP" }, {CTRY_JAPAN22, "JP" }, {CTRY_JAPAN23, "JP" }, {CTRY_JAPAN24, "JP" }, {CTRY_JAPAN25, "JP" }, {CTRY_JAPAN26, "JP" }, {CTRY_JAPAN27, "JP" }, {CTRY_JAPAN28, "JP" }, {CTRY_JAPAN29, "JP" }, {CTRY_JAPAN30, "JP" }, {CTRY_JAPAN31, "JP" }, {CTRY_JAPAN32, "JP" }, {CTRY_JAPAN33, "JP" }, {CTRY_JAPAN34, "JP" }, {CTRY_JAPAN35, "JP" }, {CTRY_JAPAN36, "JP" }, {CTRY_JAPAN37, "JP" }, {CTRY_JAPAN38, "JP" }, {CTRY_JAPAN39, "JP" }, {CTRY_JAPAN40, "JP" }, {CTRY_JAPAN41, "JP" }, {CTRY_JAPAN42, "JP" }, {CTRY_JAPAN43, "JP" }, {CTRY_JAPAN44, "JP" }, {CTRY_JAPAN45, "JP" }, {CTRY_JAPAN46, "JP" }, {CTRY_JAPAN47, "JP" }, {CTRY_JAPAN48, "JP" }, {CTRY_JORDAN, "JO" }, {CTRY_KAZAKHSTAN, "KZ" }, {CTRY_KOREA_NORTH, "KP" }, {CTRY_KOREA_ROC, "KR" }, {CTRY_KOREA_ROC2, "K2" }, {CTRY_KUWAIT, "KW" }, {CTRY_LATVIA, "LV" }, {CTRY_LEBANON, "LB" }, {CTRY_LIECHTENSTEIN, "LI" }, {CTRY_LITHUANIA, "LT" }, {CTRY_LUXEMBOURG, "LU" }, {CTRY_MACAU, "MO" }, {CTRY_MACEDONIA, "MK" }, {CTRY_MALAYSIA, "MY" }, {CTRY_MEXICO, "MX" }, {CTRY_MONACO, "MC" }, {CTRY_MOROCCO, "MA" }, {CTRY_NETHERLANDS, "NL" }, {CTRY_NEW_ZEALAND, "NZ" }, {CTRY_NORWAY, "NO" }, {CTRY_OMAN, "OM" }, {CTRY_PAKISTAN, "PK" }, {CTRY_PANAMA, "PA" }, {CTRY_PERU, "PE" }, {CTRY_PHILIPPINES, "PH" }, {CTRY_POLAND, "PL" }, {CTRY_PORTUGAL, "PT" }, {CTRY_PUERTO_RICO, "PR" }, {CTRY_QATAR, "QA" }, {CTRY_ROMANIA, "RO" }, {CTRY_RUSSIA, "RU" }, {CTRY_SAUDI_ARABIA, "SA" }, {CTRY_SINGAPORE, "SG" }, {CTRY_SLOVAKIA, "SK" }, {CTRY_SLOVENIA, "SI" }, {CTRY_SOUTH_AFRICA, "ZA" }, {CTRY_SPAIN, "ES" }, {CTRY_SWEDEN, "SE" }, {CTRY_SWITZERLAND, "CH" }, {CTRY_SYRIA, "SY" }, {CTRY_TAIWAN, "TW" }, {CTRY_THAILAND, "TH" }, {CTRY_TRINIDAD_Y_TOBAGO, "TT" }, {CTRY_TUNISIA, "TN" }, {CTRY_TURKEY, "TR" }, {CTRY_UKRAINE, "UA" }, {CTRY_UAE, "AE" }, {CTRY_UNITED_KINGDOM, "GB" }, {CTRY_UNITED_STATES, "US" }, {CTRY_UNITED_STATES_FCC49, "US" }, {CTRY_URUGUAY, "UY" }, {CTRY_UZBEKISTAN, "UZ" }, {CTRY_VENEZUELA, "VE" }, {CTRY_VIET_NAM, "VN" }, {CTRY_YEMEN, "YE" }, {CTRY_ZIMBABWE, "ZW" } };intieee80211_ifattach(struct ieee80211com *ic){ struct net_device *dev = ic->ic_dev; struct ieee80211_channel *c; struct ifmediareq imr; int i; _MOD_INC_USE(THIS_MODULE, return -ENODEV); /* * Pick an initial operating mode until we have a vap * created to lock it down correctly. This is only * drivers have something defined for configuring the * hardware at startup. */ ic->ic_opmode = IEEE80211_M_STA; /* everyone supports this */ /* * Fill in 802.11 available channel set, mark * all available channels as active, and pick * a default channel if not already specified. */ KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX, ("invalid number of channels specified: %u", ic->ic_nchans)); memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; for (i = 0; i < ic->ic_nchans; i++) { c = &ic->ic_channels[i]; KASSERT(c->ic_flags != 0, ("channel with no flags")); KASSERT(c->ic_ieee < IEEE80211_CHAN_MAX, ("channel with bogus ieee number %u", c->ic_ieee)); setbit(ic->ic_chan_avail, c->ic_ieee); /* * Identify mode capabilities. */ if (IEEE80211_IS_CHAN_A(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; if (IEEE80211_IS_CHAN_B(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; if (IEEE80211_IS_CHAN_PUREG(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; if (IEEE80211_IS_CHAN_FHSS(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_FH; if (IEEE80211_IS_CHAN_108A(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_A; if (IEEE80211_IS_CHAN_108G(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_G; } /* initialize candidate channels to all available */ memcpy(ic->ic_chan_active, ic->ic_chan_avail, sizeof(ic->ic_chan_avail)); /* validate ic->ic_curmode */ if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) ic->ic_curmode = IEEE80211_MODE_AUTO; /* * When 11g is supported, force the rate set to * include basic rates suitable for a mixed b/g bss. */ if (ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) ieee80211_set11gbasicrates( &ic->ic_sup_rates[IEEE80211_MODE_11G], IEEE80211_MODE_11G); /* setup initial channel settings */ ic->ic_bsschan = IEEE80211_CHAN_ANYC; /* arbitrarily pick the first channel */ ic->ic_curchan = &ic->ic_channels[0]; /* Enable marking of dfs by default */ ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS; /* * Enable WME by default if we're capable. */ if (ic->ic_caps & IEEE80211_C_WME) ic->ic_flags |= IEEE80211_F_WME; (void) ieee80211_setmode(ic, ic->ic_curmode); if (ic->ic_lintval == 0) ic->ic_lintval = IEEE80211_BINTVAL_DEFAULT; ic->ic_bmisstimeout = 7 * ic->ic_lintval; /* default 7 beacons */ IEEE80211_LOCK_INIT(ic, "ieee80211com"); IEEE80211_VAPS_LOCK_INIT(ic, "ieee80211com_vaps"); TAILQ_INIT(&ic->ic_vaps); ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX; ic->ic_txpowlimit = IEEE80211_TXPOWER_MIN; ic->ic_newtxpowlimit = IEEE80211_TXPOWER_MAX; ieee80211_crypto_attach(ic); ieee80211_node_attach(ic); ieee80211_power_attach(ic); ieee80211_proto_attach(ic); ieee80211_scan_attach(ic); ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, ieee80211com_media_change, ieee80211com_media_status); ieee80211com_media_status(dev, &imr); ifmedia_set(&ic->ic_media, imr.ifm_active); return 0;}EXPORT_SYMBOL(ieee80211_ifattach);voidieee80211_ifdetach(struct ieee80211com *ic){ struct ieee80211vap *vap; rtnl_lock(); while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL) ic->ic_vap_delete(vap); rtnl_unlock(); ieee80211_scan_detach(ic); ieee80211_proto_detach(ic); ieee80211_crypto_detach(ic); ieee80211_power_detach(ic); ieee80211_node_detach(ic); ifmedia_removeall(&ic->ic_media); IEEE80211_VAPS_LOCK_DESTROY(ic); IEEE80211_LOCK_DESTROY(ic); _MOD_DEC_USE(THIS_MODULE);}EXPORT_SYMBOL(ieee80211_ifdetach);intieee80211_vap_setup(struct ieee80211com *ic, struct net_device *dev, const char *name, int unit, int opmode, int flags){#define IEEE80211_C_OPMODE \ (IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | IEEE80211_C_AHDEMO | \ IEEE80211_C_MONITOR) struct ieee80211vap *vap = dev->priv; struct net_device *parent = ic->ic_dev; int err; if (name != NULL) { /* XXX */ if (strchr(name, '%')) { if ((err = dev_alloc_name(dev, name)) < 0) { printk(KERN_ERR "can't alloc name %s\n", name); return err; } } else strncpy(dev->name, name, sizeof(dev->name)); } dev->get_stats = ieee80211_getstats; dev->open = ieee80211_open; dev->stop = ieee80211_stop; dev->hard_start_xmit = ieee80211_hardstart; dev->set_multicast_list = ieee80211_set_multicast_list;#if 0 dev->set_mac_address = ieee80211_set_mac_address;#endif dev->change_mtu = ieee80211_change_mtu; dev->tx_queue_len = 0; /* NB: bypass queueing */ dev->hard_header_len = parent->hard_header_len; /* * The caller is assumed to allocate the device with * alloc_etherdev or similar so we arrange for the * space to be reclaimed accordingly. */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) /* in 2.4 things are done differently... */ dev->features |= NETIF_F_DYNALLOC;#else dev->destructor = free_netdev;#endif vap->iv_ic = ic; vap->iv_dev = dev; /* back pointer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -