am930mgr.c
来自「Linux Wireless LAN Project 的目标是开发一个完整的」· C语言 代码 · 共 2,470 行 · 第 1/5 页
C
2,470 行
/* am930mgr.c: Handles the 802.11 mac management functions.* --------------------------------------------------------------------** Linux WLAN ** The contents of this file are subject to the Mozilla Public* License Version 1.0 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.mozilla.org/MPL/** Software distributed under the License is distributed on an "AS* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** The initial developer of the original code is Mark S. Mathews* <mark@absoval.com>. Portions created by Mark S. Mathews* are Copyright (C) 1998 AbsoluteValue Software, Inc. All Rights Reserved.* * --------------------------------------------------------------------** The author may be reached as mark@absoval.com, or C/O AbsoluteValue* Software Inc., P.O. Box 941149, Maitland, FL, 32794-1149** Thanks to David Hinds, Donald Becker, and the rest of the Linux* developers worldwide for making all of this possible.** --------------------------------------------------------------------* */#include <linux/config.h>#include <wlan/wlan_compat.h>#if (WLAN_OS == WLAN_LINUX_KERNEL)/* The following prevents "kernel_version" from being set in this file. */#define __NO_VERSION__/* PCMCIA headers generated during PCMCIA package installation */#ifdef WLAN_PCMCIA#include <pcmcia/config.h>#include <pcmcia/k_compat.h>#endif/* Module related headers, non-module drivers should not include */#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>/* Ethernet and network includes */#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>/* Standard driver includes */#include <linux/delay.h>#include <linux/types.h>#include <linux/fcntl.h>#include <asm/system.h>#include <asm/io.h>#include <linux/in.h>#include <linux/ptrace.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <asm/bitops.h>#include <linux/errno.h>/* Card and Driver services includes */#ifdef WLAN_PCMCIA#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h>#include <pcmcia/cisreg.h>#endif#include <wlan/version.h>#include <wlan/am930mib.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/wlan_ioctl.h>#include <wlan/wlan_stable.h>#ifdef PCMCIA#include "am930di.h"#endif#include "am930llc.h"#include "am930mac.h"#include "am930hw.h"#include "am930mgr.h"#elif (WLAN_OS == WLAN_LWOS)#include <stddef.h>#include <stdlibsys.h>#include <direct.h>#include <hal.h>#include <mem.h>#include <kernel.h>#include <spi.h>#include <clock.h>#include <wlan/wlan_compat.h>#include <wlan/version.h>#include <wlan/am930mib.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/am930mib.h>#include <wlan/wlan_stable.h>#include <wlan/wlan_ioctl.h>#include <lw-wlan.h>#include <wlan/am930mac.h>#include <wlan/am930hw.h>#include <wlan/am930mgr.h>#else #error "No WLAN_OS match!"#endif/*================================================================*//* Local Constants *//*================================================================*//* Local Functions */static void am930mgr_authen1_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_authen2_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_authen3_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_authen4_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_mkchallengetext( am930mgr_t *mgr, UINT8 *chbuf, UINT chbuflen, UINT8 *key, UINT keylen);static wlan_pb_t *am930mgr_mkfrm_assocreq( am930mgr_t *mgr, UINT8 *daddr, UINT16 capinfo, UINT16 listen_int, wlan_ie_ssid_t *ssid, wlan_ie_supp_rates_t *rates);static wlan_pb_t *am930mgr_mkfrm_assocresp( am930mgr_t *mgr, UINT8 *daddr, UINT16 capinfo, UINT16 status, UINT16 aid, wlan_ie_supp_rates_t *rates);static wlan_pb_t *am930mgr_mkfrm_auth( am930mgr_t *mgr, UINT8 *daddr, UINT16 alg, UINT16 seq, UINT16 status, UINT8 *challenge);static wlan_pb_t *am930mgr_mkfrm_deauth( am930mgr_t *mgr, UINT8 *daddr, UINT16 reason);static wlan_pb_t *am930mgr_mkfrm_disassoc( am930mgr_t *mgr, UINT8 *daddr, UINT16 reason);static wlan_pb_t *am930mgr_mkfrm_reassocresp( am930mgr_t *mgr, UINT8 *daddr, UINT16 capinfo, UINT16 status, UINT16 aid, wlan_ie_supp_rates_t *rates);static int am930mgr_rates_basicissubset( am930mgr_t *mgr, wlan_ie_supp_rates_t *r1, wlan_ie_supp_rates_t *r2);static UINT8 am930mgr_rates_max(wlan_ie_supp_rates_t *rates);static void am930mgr_timerfunc(am930mgr_t *mgr);/*================================================================*//* Local Statics *//*----------------------------------------------------------------* am930mgr_construct** Allocates and initializes the mgr object and it's subobjects.** returns: NULL on failure, the address of the new object* otherwise.----------------------------------------------------------------*/am930mgr_t* am930mgr_construct(am930mac_t *mac, am930hw_t *hw){ am930mgr_t* mgr = NULL; DBFENTER; if ( mac != NULL ) { mgr = kmalloc( sizeof(am930mgr_t), GFP_KERNEL); if ( mgr != NULL ) { memset( mgr, 0, sizeof(am930mgr_t)); mgr->mac = mac; mgr->hw = hw; /* TODO: make this parameterized! */ mgr->challengekey[0] = 0xa4; mgr->challengekey[1] = 0xf6; mgr->challengekey[2] = 0xd2; mgr->challengekey[3] = 0x54; mgr->challengekey[4] = 0xc6; mgr->challengekey[5] = 0xc6; mgr->challengekey[6] = 0x56; mgr->challengekey[7] = 0xe6; mgr->challengekey[8] = 0x02; mgr->challengekey[9] = 0x64; mgr->challengekey[10] = 0xe2; mgr->challengekey[11] = 0x02; mgr->challengekey[12] = 0xd4; mgr->challengekey[13] = 0x16; mgr->challengekey[14] = 0x47; mgr->challengekey[15] = 0x86; mgr->challengekey[16] = 0x56; mgr->challengekey[17] = 0x77; mgr->challengekey[18] = 0x37;/* mgr->timerfunc = am930mgr_timerfunc; */ /* Management transaction timeout, default 10 seconds */ /* for auth and assoc */ mgr->mgmt_trans_timeout = wlan_seconds2ticks(10); /* Authenticated station timeout (AP), default 60 minutes */ mgr->ap_auth_timeout = wlan_minutes2ticks(60); /* Associated station timeout (AP), default 30 minutes */ mgr->ap_assoc_timeout = wlan_minutes2ticks(30); } } DBFEXIT; return mgr;}/*----------------------------------------------------------------* am930mgr_timerfunc** Timer function called from llc. We currently assume that this* function will be called every 1/10th second. Lets code* all the time stuff so it doesn't matter....use absolute time* from the system time register.** returns: nothing----------------------------------------------------------------*/void am930mgr_timerfunc(am930mgr_t *mgr){ static UINT count = 0; wlan_stable_item_t *sta; wlan_stable_item_t *sta_dealloc; UINT i; DBFENTER; if ( mgr->mac->mode == AM930_MACMODE_ESS_AP && ++count > 9 ) { /* only scan the stable once per second. */ count = 0; for ( i = 0; i < WLAN_STABLE_LEN; i++ ) { sta = mgr->stable[i]; while (sta != NULL) { /* Looking for: */ /* stations that need deallocation */ if ( sta->sta.state == WLAN_STA_STATE_FREE ) { if (sta->prev == NULL && sta->next == NULL) { mgr->stable[i] = NULL; } else if ( sta->prev == NULL && sta->next != NULL ) { mgr->stable[i] = sta->next; sta->next->prev = NULL; } else if ( sta->prev != NULL && sta->next == NULL ) { sta->prev->next = NULL; } else { sta->prev->next = sta->next; sta->next->prev = sta->prev; } mgr->aidtable[sta->sta.aid] = NULL; sta_dealloc = sta; sta = sta->next; am930shim_free(sta_dealloc, sizeof(wlan_stable_item_t)); continue; } /* timed out authentication transactions */ if ( (sta->sta.state == WLAN_STA_STATE_PENDING_ACTIVE) && (sta->sta.info & WLAN_STA_INFO_AUTH) && time_after_eq( jiffies, sta->sta.timeout) ) { sta->sta.state = WLAN_STA_STATE_FREE; sta->sta.info = 0; } /* inactive stations (mark them for future dealloc) */ /* if ( (sta->sta.state == WLAN_STA_STATE_ACTIVE) && time_after_eq( jiffies, sta-> */ sta = sta->next; } } } else { /* if we're a STA in INFRA we need to watch for: */ /* - Timed out authentication transactions */ /* - Timed out association transactions */ /* - if associated, Inactivity from the AP */ } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_destruct** destroys the mgr object** returns: nothing----------------------------------------------------------------*/void am930mgr_destruct( am930mgr_t *mgr ){ knownbss_t *bss; DBFENTER; if ( mgr != NULL ) { /* Free the remaining bss's */ while ( mgr->bsslist != NULL ) { bss = mgr->bsslist; mgr->bsslist = bss->next; /* TODO: when we add ttl, need to kill any timer funcs */ kfree_s( bss, sizeof( knownbss_t )); } kfree_s(mgr, sizeof(am930mgr_t)); } DBFEXIT;}/*----------------------------------------------------------------* am930mgr_assoc_begin_sta** Start the station association procedure. Namely, send an* association request frame to the AP.** returns: nothing for now----------------------------------------------------------------*/void am930mgr_assoc_begin_sta(am930mgr_t *mgr){ wlan_pb_t *pb; UINT16 capinfo; /* bogus hardcode, needs fixing */ UINT8 rates[] = {WLAN_EID_SUPP_RATES, 2, 0x82, 0x84}; DBFENTER; capinfo = WLAN_SET_MGMT_CAP_INFO_ESS(1); if ( mgr->mac->exclude_unencrypted ) { capinfo |= WLAN_SET_MGMT_CAP_INFO_PRIVACY(1); } /* build an assocreq frame and send it */ pb = am930mgr_mkfrm_assocreq( mgr, mgr->curr_bssid, capinfo, 0, /* listen_int, indicates no PS mode? */ (wlan_ie_ssid_t*)mgr->curr_ssid, (wlan_ie_supp_rates_t*)rates); if (pb != NULL ) { /* send the frame */ am930mac_txmac( mgr->mac, pb); mgr->mac->state = AM930_MACSTATE_ASSOCPENDING; } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_assoc_stop** Stop and clean up a pending association attempt.** returns: nothing for now----------------------------------------------------------------*/void am930mgr_assoc_stop(am930mgr_t *mgr){ if ( mgr->mac->state == AM930_MACSTATE_ASSOCPENDING ) { mgr->mac->state = AM930_MACSTATE_AUTH; }}/*----------------------------------------------------------------* am930mgr_assocreq_rx** Handle incoming association response frames.* NOTE: The reassocreq_rx is basically a cut-n-paste of this * function (bad Mark, bad, bad). If you change anything* here it should probably be changed in reassocreq as well.** Arguments:* rxpb packet buffer containing assocreq frame* stats receive statitistics for assocreq frame** returns: nothing for now----------------------------------------------------------------*/void am930mgr_assocreq_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ wlan_fr_assocreq_t f; wlan_stable_item_t *sta; wlan_pb_t *pb; DBFENTER; /* decode the frame */ f.len = rxpb->p80211buflen - WLAN_CRC_LEN; f.buf = rxpb->p80211buf; wlan_mgmt_decode_assocreq(&f); /* Check for class2 error */ sta = am930mgr_stable_lookup( mgr, f.hdr->a3.a2); if ( sta == NULL || !(sta->sta.info & WLAN_STA_INFO_AUTH) ) { pb = am930mgr_mkfrm_deauth( mgr, f.hdr->a3.a2, WLAN_MGMT_REASON_CLASS2_NONAUTH); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Check to make sure we're the SS the station says we are */ /* assume bad BSSID would be rejected by rx filter */ if ( memcmp( f.ssid->ssid, mgr->curr_ssid + WLAN_IEHDR_LEN, mgr->curr_ssid[1]) != 0 ) { pb = am930mgr_mkfrm_assocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC, 0, /* AID */ (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Capability Info check */ /* condition 1: is it not asking for an ESS? */ /* condition 2: is it asking for polling? (we don't support it) */ /* condition 3: is it asking for WEP and our wep keys aren't set? */ if ( (WLAN_GET_MGMT_CAP_INFO_ESS(ieee2host16(*f.cap_info)) == 0) || ((WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(ieee2host16(*f.cap_info)) == 1) && (WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(ieee2host16(*f.cap_info)) == 0)) || ((WLAN_GET_MGMT_CAP_INFO_PRIVACY(ieee2host16(*f.cap_info)) == 1) && (mgr->mac->privacy_invoked == 0)) ) { pb = am930mgr_mkfrm_assocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_CAPS_UNSUPPORTED, 0, /* AID */ (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?