Linux Audio

Check our new training course

Loading...
v6.8
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Original code based Host AP (software wireless LAN access point) driver
   4 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
   5 *
   6 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
   7 * <j@w1.fi>
   8 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
   9 * Copyright (c) 2004-2005, Intel Corporation
 
 
 
 
 
  10 */
  11
  12#include <linux/compiler.h>
  13#include <linux/errno.h>
  14#include <linux/if_arp.h>
  15#include <linux/in6.h>
  16#include <linux/gfp.h>
  17#include <linux/in.h>
  18#include <linux/ip.h>
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/netdevice.h>
  22#include <linux/proc_fs.h>
  23#include <linux/skbuff.h>
  24#include <linux/tcp.h>
  25#include <linux/types.h>
  26#include <linux/wireless.h>
  27#include <linux/etherdevice.h>
  28#include <linux/uaccess.h>
  29#include <linux/ctype.h>
  30
  31#include <net/lib80211.h>
  32
  33#include "libipw.h"
  34
  35static void libipw_monitor_rx(struct libipw_device *ieee,
  36					struct sk_buff *skb,
  37					struct libipw_rx_stats *rx_stats)
  38{
  39	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  40	u16 fc = le16_to_cpu(hdr->frame_control);
  41
  42	skb->dev = ieee->dev;
  43	skb_reset_mac_header(skb);
  44	skb_pull(skb, libipw_get_hdrlen(fc));
  45	skb->pkt_type = PACKET_OTHERHOST;
  46	skb->protocol = htons(ETH_P_80211_RAW);
  47	memset(skb->cb, 0, sizeof(skb->cb));
  48	netif_rx(skb);
  49}
  50
  51/* Called only as a tasklet (software IRQ) */
  52static struct libipw_frag_entry *libipw_frag_cache_find(struct
  53							      libipw_device
  54							      *ieee,
  55							      unsigned int seq,
  56							      unsigned int frag,
  57							      u8 * src,
  58							      u8 * dst)
  59{
  60	struct libipw_frag_entry *entry;
  61	int i;
  62
  63	for (i = 0; i < LIBIPW_FRAG_CACHE_LEN; i++) {
  64		entry = &ieee->frag_cache[i];
  65		if (entry->skb != NULL &&
  66		    time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
  67			LIBIPW_DEBUG_FRAG("expiring fragment cache entry "
  68					     "seq=%u last_frag=%u\n",
  69					     entry->seq, entry->last_frag);
  70			dev_kfree_skb_any(entry->skb);
  71			entry->skb = NULL;
  72		}
  73
  74		if (entry->skb != NULL && entry->seq == seq &&
  75		    (entry->last_frag + 1 == frag || frag == -1) &&
  76		    ether_addr_equal(entry->src_addr, src) &&
  77		    ether_addr_equal(entry->dst_addr, dst))
  78			return entry;
  79	}
  80
  81	return NULL;
  82}
  83
  84/* Called only as a tasklet (software IRQ) */
  85static struct sk_buff *libipw_frag_cache_get(struct libipw_device *ieee,
  86						struct libipw_hdr_4addr *hdr)
  87{
  88	struct sk_buff *skb = NULL;
  89	u16 sc;
  90	unsigned int frag, seq;
  91	struct libipw_frag_entry *entry;
  92
  93	sc = le16_to_cpu(hdr->seq_ctl);
  94	frag = WLAN_GET_SEQ_FRAG(sc);
  95	seq = WLAN_GET_SEQ_SEQ(sc);
  96
  97	if (frag == 0) {
  98		/* Reserve enough space to fit maximum frame length */
  99		skb = dev_alloc_skb(ieee->dev->mtu +
 100				    sizeof(struct libipw_hdr_4addr) +
 101				    8 /* LLC */  +
 102				    2 /* alignment */  +
 103				    8 /* WEP */  + ETH_ALEN /* WDS */ );
 104		if (skb == NULL)
 105			return NULL;
 106
 107		entry = &ieee->frag_cache[ieee->frag_next_idx];
 108		ieee->frag_next_idx++;
 109		if (ieee->frag_next_idx >= LIBIPW_FRAG_CACHE_LEN)
 110			ieee->frag_next_idx = 0;
 111
 112		if (entry->skb != NULL)
 113			dev_kfree_skb_any(entry->skb);
 114
 115		entry->first_frag_time = jiffies;
 116		entry->seq = seq;
 117		entry->last_frag = frag;
 118		entry->skb = skb;
 119		memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
 120		memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
 121	} else {
 122		/* received a fragment of a frame for which the head fragment
 123		 * should have already been received */
 124		entry = libipw_frag_cache_find(ieee, seq, frag, hdr->addr2,
 125						  hdr->addr1);
 126		if (entry != NULL) {
 127			entry->last_frag = frag;
 128			skb = entry->skb;
 129		}
 130	}
 131
 132	return skb;
 133}
 134
 135/* Called only as a tasklet (software IRQ) */
 136static int libipw_frag_cache_invalidate(struct libipw_device *ieee,
 137					   struct libipw_hdr_4addr *hdr)
 138{
 139	u16 sc;
 140	unsigned int seq;
 141	struct libipw_frag_entry *entry;
 142
 143	sc = le16_to_cpu(hdr->seq_ctl);
 144	seq = WLAN_GET_SEQ_SEQ(sc);
 145
 146	entry = libipw_frag_cache_find(ieee, seq, -1, hdr->addr2,
 147					  hdr->addr1);
 148
 149	if (entry == NULL) {
 150		LIBIPW_DEBUG_FRAG("could not invalidate fragment cache "
 151				     "entry (seq=%u)\n", seq);
 152		return -1;
 153	}
 154
 155	entry->skb = NULL;
 156	return 0;
 157}
 158
 159#ifdef NOT_YET
 160/* libipw_rx_frame_mgtmt
 161 *
 162 * Responsible for handling management control frames
 163 *
 164 * Called by libipw_rx */
 165static int
 166libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb,
 167			struct libipw_rx_stats *rx_stats, u16 type,
 168			u16 stype)
 169{
 170	if (ieee->iw_mode == IW_MODE_MASTER) {
 171		printk(KERN_DEBUG "%s: Master mode not yet supported.\n",
 172		       ieee->dev->name);
 173		return 0;
 174/*
 175  hostap_update_sta_ps(ieee, (struct hostap_libipw_hdr_4addr *)
 176  skb->data);*/
 177	}
 178
 179	if (ieee->hostapd && type == WLAN_FC_TYPE_MGMT) {
 180		if (stype == WLAN_FC_STYPE_BEACON &&
 181		    ieee->iw_mode == IW_MODE_MASTER) {
 182			struct sk_buff *skb2;
 183			/* Process beacon frames also in kernel driver to
 184			 * update STA(AP) table statistics */
 185			skb2 = skb_clone(skb, GFP_ATOMIC);
 186			if (skb2)
 187				hostap_rx(skb2->dev, skb2, rx_stats);
 188		}
 189
 190		/* send management frames to the user space daemon for
 191		 * processing */
 192		ieee->apdevstats.rx_packets++;
 193		ieee->apdevstats.rx_bytes += skb->len;
 194		prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
 195		return 0;
 196	}
 197
 198	if (ieee->iw_mode == IW_MODE_MASTER) {
 199		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
 200			printk(KERN_DEBUG "%s: unknown management frame "
 201			       "(type=0x%02x, stype=0x%02x) dropped\n",
 202			       skb->dev->name, type, stype);
 203			return -1;
 204		}
 205
 206		hostap_rx(skb->dev, skb, rx_stats);
 207		return 0;
 208	}
 209
 210	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
 211	       "received in non-Host AP mode\n", skb->dev->name);
 212	return -1;
 213}
 214#endif
 215
 216/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
 217/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
 218static unsigned char libipw_rfc1042_header[] =
 219    { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
 220
 221/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
 222static unsigned char libipw_bridge_tunnel_header[] =
 223    { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
 224/* No encapsulation header if EtherType < 0x600 (=length) */
 225
 226/* Called by libipw_rx_frame_decrypt */
 227static int libipw_is_eapol_frame(struct libipw_device *ieee,
 228				    struct sk_buff *skb)
 229{
 230	struct net_device *dev = ieee->dev;
 231	u16 fc, ethertype;
 232	struct libipw_hdr_3addr *hdr;
 233	u8 *pos;
 234
 235	if (skb->len < 24)
 236		return 0;
 237
 238	hdr = (struct libipw_hdr_3addr *)skb->data;
 239	fc = le16_to_cpu(hdr->frame_ctl);
 240
 241	/* check that the frame is unicast frame to us */
 242	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 243	    IEEE80211_FCTL_TODS &&
 244	    ether_addr_equal(hdr->addr1, dev->dev_addr) &&
 245	    ether_addr_equal(hdr->addr3, dev->dev_addr)) {
 246		/* ToDS frame with own addr BSSID and DA */
 247	} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 248		   IEEE80211_FCTL_FROMDS &&
 249		   ether_addr_equal(hdr->addr1, dev->dev_addr)) {
 250		/* FromDS frame with own addr as DA */
 251	} else
 252		return 0;
 253
 254	if (skb->len < 24 + 8)
 255		return 0;
 256
 257	/* check for port access entity Ethernet type */
 258	pos = skb->data + 24;
 259	ethertype = (pos[6] << 8) | pos[7];
 260	if (ethertype == ETH_P_PAE)
 261		return 1;
 262
 263	return 0;
 264}
 265
 266/* Called only as a tasklet (software IRQ), by libipw_rx */
 267static int
 268libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
 269			   struct lib80211_crypt_data *crypt)
 270{
 271	struct libipw_hdr_3addr *hdr;
 272	int res, hdrlen;
 273
 274	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
 275		return 0;
 276
 277	hdr = (struct libipw_hdr_3addr *)skb->data;
 278	hdrlen = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 279
 280	atomic_inc(&crypt->refcnt);
 281	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
 282	atomic_dec(&crypt->refcnt);
 283	if (res < 0) {
 284		LIBIPW_DEBUG_DROP("decryption failed (SA=%pM) res=%d\n",
 285				     hdr->addr2, res);
 286		if (res == -2)
 287			LIBIPW_DEBUG_DROP("Decryption failed ICV "
 288					     "mismatch (key %d)\n",
 289					     skb->data[hdrlen + 3] >> 6);
 290		ieee->ieee_stats.rx_discards_undecryptable++;
 291		return -1;
 292	}
 293
 294	return res;
 295}
 296
 297/* Called only as a tasklet (software IRQ), by libipw_rx */
 298static int
 299libipw_rx_frame_decrypt_msdu(struct libipw_device *ieee,
 300				struct sk_buff *skb, int keyidx,
 301				struct lib80211_crypt_data *crypt)
 302{
 303	struct libipw_hdr_3addr *hdr;
 304	int res, hdrlen;
 305
 306	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
 307		return 0;
 308
 309	hdr = (struct libipw_hdr_3addr *)skb->data;
 310	hdrlen = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 311
 312	atomic_inc(&crypt->refcnt);
 313	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
 314	atomic_dec(&crypt->refcnt);
 315	if (res < 0) {
 316		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
 317		       " (SA=%pM keyidx=%d)\n", ieee->dev->name, hdr->addr2,
 318		       keyidx);
 319		return -1;
 320	}
 321
 322	return 0;
 323}
 324
 325/* All received frames are sent to this function. @skb contains the frame in
 326 * IEEE 802.11 format, i.e., in the format it was sent over air.
 327 * This function is called only as a tasklet (software IRQ). */
 328int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
 329		 struct libipw_rx_stats *rx_stats)
 330{
 331	struct net_device *dev = ieee->dev;
 332	struct libipw_hdr_4addr *hdr;
 333	size_t hdrlen;
 334	u16 fc, type, stype, sc;
 335	unsigned int frag;
 336	u8 *payload;
 337	u16 ethertype;
 338#ifdef NOT_YET
 339	struct net_device *wds = NULL;
 340	struct sk_buff *skb2 = NULL;
 341	struct net_device *wds = NULL;
 342	int frame_authorized = 0;
 343	int from_assoc_ap = 0;
 344	void *sta = NULL;
 345#endif
 346	u8 dst[ETH_ALEN];
 347	u8 src[ETH_ALEN];
 348	struct lib80211_crypt_data *crypt = NULL;
 349	int keyidx = 0;
 350	int can_be_decrypted = 0;
 351
 352	hdr = (struct libipw_hdr_4addr *)skb->data;
 353	if (skb->len < 10) {
 354		printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
 355		goto rx_dropped;
 356	}
 357
 358	fc = le16_to_cpu(hdr->frame_ctl);
 359	type = WLAN_FC_GET_TYPE(fc);
 360	stype = WLAN_FC_GET_STYPE(fc);
 361	sc = le16_to_cpu(hdr->seq_ctl);
 362	frag = WLAN_GET_SEQ_FRAG(sc);
 363	hdrlen = libipw_get_hdrlen(fc);
 364
 365	if (skb->len < hdrlen) {
 366		printk(KERN_INFO "%s: invalid SKB length %d\n",
 367			dev->name, skb->len);
 368		goto rx_dropped;
 369	}
 370
 371	/* Put this code here so that we avoid duplicating it in all
 372	 * Rx paths. - Jean II */
 373#ifdef CONFIG_WIRELESS_EXT
 374#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
 375	/* If spy monitoring on */
 376	if (ieee->spy_data.spy_number > 0) {
 377		struct iw_quality wstats;
 378
 379		wstats.updated = 0;
 380		if (rx_stats->mask & LIBIPW_STATMASK_RSSI) {
 381			wstats.level = rx_stats->signal;
 382			wstats.updated |= IW_QUAL_LEVEL_UPDATED;
 383		} else
 384			wstats.updated |= IW_QUAL_LEVEL_INVALID;
 385
 386		if (rx_stats->mask & LIBIPW_STATMASK_NOISE) {
 387			wstats.noise = rx_stats->noise;
 388			wstats.updated |= IW_QUAL_NOISE_UPDATED;
 389		} else
 390			wstats.updated |= IW_QUAL_NOISE_INVALID;
 391
 392		if (rx_stats->mask & LIBIPW_STATMASK_SIGNAL) {
 393			wstats.qual = rx_stats->signal;
 394			wstats.updated |= IW_QUAL_QUAL_UPDATED;
 395		} else
 396			wstats.updated |= IW_QUAL_QUAL_INVALID;
 397
 398		/* Update spy records */
 399		wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
 400	}
 401#endif				/* IW_WIRELESS_SPY */
 402#endif				/* CONFIG_WIRELESS_EXT */
 403
 404#ifdef NOT_YET
 405	hostap_update_rx_stats(local->ap, hdr, rx_stats);
 406#endif
 407
 408	if (ieee->iw_mode == IW_MODE_MONITOR) {
 409		dev->stats.rx_packets++;
 410		dev->stats.rx_bytes += skb->len;
 411		libipw_monitor_rx(ieee, skb, rx_stats);
 412		return 1;
 413	}
 414
 415	can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) ||
 416			    is_broadcast_ether_addr(hdr->addr2)) ?
 417	    ieee->host_mc_decrypt : ieee->host_decrypt;
 418
 419	if (can_be_decrypted) {
 420		if (skb->len >= hdrlen + 3) {
 421			/* Top two-bits of byte 3 are the key index */
 422			keyidx = skb->data[hdrlen + 3] >> 6;
 423		}
 424
 425		/* ieee->crypt[] is WEP_KEY (4) in length.  Given that keyidx
 426		 * is only allowed 2-bits of storage, no value of keyidx can
 427		 * be provided via above code that would result in keyidx
 428		 * being out of range */
 429		crypt = ieee->crypt_info.crypt[keyidx];
 430
 431#ifdef NOT_YET
 432		sta = NULL;
 433
 434		/* Use station specific key to override default keys if the
 435		 * receiver address is a unicast address ("individual RA"). If
 436		 * bcrx_sta_key parameter is set, station specific key is used
 437		 * even with broad/multicast targets (this is against IEEE
 438		 * 802.11, but makes it easier to use different keys with
 439		 * stations that do not support WEP key mapping). */
 440
 441		if (is_unicast_ether_addr(hdr->addr1) || local->bcrx_sta_key)
 442			(void)hostap_handle_sta_crypto(local, hdr, &crypt,
 443						       &sta);
 444#endif
 445
 446		/* allow NULL decrypt to indicate an station specific override
 447		 * for default encryption */
 448		if (crypt && (crypt->ops == NULL ||
 449			      crypt->ops->decrypt_mpdu == NULL))
 450			crypt = NULL;
 451
 452		if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
 453			/* This seems to be triggered by some (multicast?)
 454			 * frames from other than current BSS, so just drop the
 455			 * frames silently instead of filling system log with
 456			 * these reports. */
 457			LIBIPW_DEBUG_DROP("Decryption failed (not set)"
 458					     " (SA=%pM)\n", hdr->addr2);
 459			ieee->ieee_stats.rx_discards_undecryptable++;
 460			goto rx_dropped;
 461		}
 462	}
 463#ifdef NOT_YET
 464	if (type != WLAN_FC_TYPE_DATA) {
 465		if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
 466		    fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
 467		    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
 468			printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
 469			       "from %pM\n", dev->name, hdr->addr2);
 470			/* TODO: could inform hostapd about this so that it
 471			 * could send auth failure report */
 472			goto rx_dropped;
 473		}
 474
 475		if (libipw_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
 476			goto rx_dropped;
 477		else
 478			goto rx_exit;
 479	}
 480#endif
 481	/* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
 482	if (sc == ieee->prev_seq_ctl)
 483		goto rx_dropped;
 484	else
 485		ieee->prev_seq_ctl = sc;
 486
 487	/* Data frame - extract src/dst addresses */
 488	if (skb->len < LIBIPW_3ADDR_LEN)
 489		goto rx_dropped;
 490
 491	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 492	case IEEE80211_FCTL_FROMDS:
 493		memcpy(dst, hdr->addr1, ETH_ALEN);
 494		memcpy(src, hdr->addr3, ETH_ALEN);
 495		break;
 496	case IEEE80211_FCTL_TODS:
 497		memcpy(dst, hdr->addr3, ETH_ALEN);
 498		memcpy(src, hdr->addr2, ETH_ALEN);
 499		break;
 500	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
 501		if (skb->len < LIBIPW_4ADDR_LEN)
 502			goto rx_dropped;
 503		memcpy(dst, hdr->addr3, ETH_ALEN);
 504		memcpy(src, hdr->addr4, ETH_ALEN);
 505		break;
 506	default:
 507		memcpy(dst, hdr->addr1, ETH_ALEN);
 508		memcpy(src, hdr->addr2, ETH_ALEN);
 509		break;
 510	}
 511
 512#ifdef NOT_YET
 513	if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
 514		goto rx_dropped;
 515	if (wds) {
 516		skb->dev = dev = wds;
 517		stats = hostap_get_stats(dev);
 518	}
 519
 520	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
 521	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 522	    IEEE80211_FCTL_FROMDS && ieee->stadev &&
 523	    ether_addr_equal(hdr->addr2, ieee->assoc_ap_addr)) {
 524		/* Frame from BSSID of the AP for which we are a client */
 525		skb->dev = dev = ieee->stadev;
 526		stats = hostap_get_stats(dev);
 527		from_assoc_ap = 1;
 528	}
 529#endif
 530
 531#ifdef NOT_YET
 532	if ((ieee->iw_mode == IW_MODE_MASTER ||
 533	     ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
 534		switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
 535					     wds != NULL)) {
 536		case AP_RX_CONTINUE_NOT_AUTHORIZED:
 537			frame_authorized = 0;
 538			break;
 539		case AP_RX_CONTINUE:
 540			frame_authorized = 1;
 541			break;
 542		case AP_RX_DROP:
 543			goto rx_dropped;
 544		case AP_RX_EXIT:
 545			goto rx_exit;
 546		}
 547	}
 548#endif
 549
 550	/* Nullfunc frames may have PS-bit set, so they must be passed to
 551	 * hostap_handle_sta_rx() before being dropped here. */
 552
 553	stype &= ~IEEE80211_STYPE_QOS_DATA;
 554
 555	if (stype != IEEE80211_STYPE_DATA &&
 556	    stype != IEEE80211_STYPE_DATA_CFACK &&
 557	    stype != IEEE80211_STYPE_DATA_CFPOLL &&
 558	    stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
 559		if (stype != IEEE80211_STYPE_NULLFUNC)
 560			LIBIPW_DEBUG_DROP("RX: dropped data frame "
 561					     "with no data (type=0x%02x, "
 562					     "subtype=0x%02x, len=%d)\n",
 563					     type, stype, skb->len);
 564		goto rx_dropped;
 565	}
 566
 567	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
 568
 569	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 570	    (keyidx = libipw_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 571		goto rx_dropped;
 572
 573	hdr = (struct libipw_hdr_4addr *)skb->data;
 574
 575	/* skb: hdr + (possibly fragmented) plaintext payload */
 576	// PR: FIXME: hostap has additional conditions in the "if" below:
 577	// ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
 578	if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
 579		int flen;
 580		struct sk_buff *frag_skb = libipw_frag_cache_get(ieee, hdr);
 581		LIBIPW_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
 582
 583		if (!frag_skb) {
 584			LIBIPW_DEBUG(LIBIPW_DL_RX | LIBIPW_DL_FRAG,
 585					"Rx cannot get skb from fragment "
 586					"cache (morefrag=%d seq=%u frag=%u)\n",
 587					(fc & IEEE80211_FCTL_MOREFRAGS) != 0,
 588					WLAN_GET_SEQ_SEQ(sc), frag);
 589			goto rx_dropped;
 590		}
 591
 592		flen = skb->len;
 593		if (frag != 0)
 594			flen -= hdrlen;
 595
 596		if (frag_skb->tail + flen > frag_skb->end) {
 597			printk(KERN_WARNING "%s: host decrypted and "
 598			       "reassembled frame did not fit skb\n",
 599			       dev->name);
 600			libipw_frag_cache_invalidate(ieee, hdr);
 601			goto rx_dropped;
 602		}
 603
 604		if (frag == 0) {
 605			/* copy first fragment (including full headers) into
 606			 * beginning of the fragment cache skb */
 607			skb_copy_from_linear_data(skb, skb_put(frag_skb, flen), flen);
 608		} else {
 609			/* append frame payload to the end of the fragment
 610			 * cache skb */
 611			skb_copy_from_linear_data_offset(skb, hdrlen,
 612				      skb_put(frag_skb, flen), flen);
 613		}
 614		dev_kfree_skb_any(skb);
 615		skb = NULL;
 616
 617		if (fc & IEEE80211_FCTL_MOREFRAGS) {
 618			/* more fragments expected - leave the skb in fragment
 619			 * cache for now; it will be delivered to upper layers
 620			 * after all fragments have been received */
 621			goto rx_exit;
 622		}
 623
 624		/* this was the last fragment and the frame will be
 625		 * delivered, so remove skb from fragment cache */
 626		skb = frag_skb;
 627		hdr = (struct libipw_hdr_4addr *)skb->data;
 628		libipw_frag_cache_invalidate(ieee, hdr);
 629	}
 630
 631	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
 632	 * encrypted/authenticated */
 633	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 634	    libipw_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
 635		goto rx_dropped;
 636
 637	hdr = (struct libipw_hdr_4addr *)skb->data;
 638	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
 639		if (		/*ieee->ieee802_1x && */
 640			   libipw_is_eapol_frame(ieee, skb)) {
 641			/* pass unencrypted EAPOL frames even if encryption is
 642			 * configured */
 643		} else {
 644			LIBIPW_DEBUG_DROP("encryption configured, but RX "
 645					     "frame not encrypted (SA=%pM)\n",
 646					     hdr->addr2);
 647			goto rx_dropped;
 648		}
 649	}
 650
 651	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
 652	    !libipw_is_eapol_frame(ieee, skb)) {
 653		LIBIPW_DEBUG_DROP("dropped unencrypted RX data "
 654				     "frame from %pM (drop_unencrypted=1)\n",
 655				     hdr->addr2);
 656		goto rx_dropped;
 657	}
 658
 659	/* If the frame was decrypted in hardware, we may need to strip off
 660	 * any security data (IV, ICV, etc) that was left behind */
 661	if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
 662	    ieee->host_strip_iv_icv) {
 663		int trimlen = 0;
 664
 665		/* Top two-bits of byte 3 are the key index */
 666		if (skb->len >= hdrlen + 3)
 667			keyidx = skb->data[hdrlen + 3] >> 6;
 668
 669		/* To strip off any security data which appears before the
 670		 * payload, we simply increase hdrlen (as the header gets
 671		 * chopped off immediately below). For the security data which
 672		 * appears after the payload, we use skb_trim. */
 673
 674		switch (ieee->sec.encode_alg[keyidx]) {
 675		case SEC_ALG_WEP:
 676			/* 4 byte IV */
 677			hdrlen += 4;
 678			/* 4 byte ICV */
 679			trimlen = 4;
 680			break;
 681		case SEC_ALG_TKIP:
 682			/* 4 byte IV, 4 byte ExtIV */
 683			hdrlen += 8;
 684			/* 8 byte MIC, 4 byte ICV */
 685			trimlen = 12;
 686			break;
 687		case SEC_ALG_CCMP:
 688			/* 8 byte CCMP header */
 689			hdrlen += 8;
 690			/* 8 byte MIC */
 691			trimlen = 8;
 692			break;
 693		}
 694
 695		if (skb->len < trimlen)
 696			goto rx_dropped;
 697
 698		__skb_trim(skb, skb->len - trimlen);
 699
 700		if (skb->len < hdrlen)
 701			goto rx_dropped;
 702	}
 703
 704	/* skb: hdr + (possible reassembled) full plaintext payload */
 705
 706	payload = skb->data + hdrlen;
 707	ethertype = (payload[6] << 8) | payload[7];
 708
 709#ifdef NOT_YET
 710	/* If IEEE 802.1X is used, check whether the port is authorized to send
 711	 * the received frame. */
 712	if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
 713		if (ethertype == ETH_P_PAE) {
 714			printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
 715			       dev->name);
 716			if (ieee->hostapd && ieee->apdev) {
 717				/* Send IEEE 802.1X frames to the user
 718				 * space daemon for processing */
 719				prism2_rx_80211(ieee->apdev, skb, rx_stats,
 720						PRISM2_RX_MGMT);
 721				ieee->apdevstats.rx_packets++;
 722				ieee->apdevstats.rx_bytes += skb->len;
 723				goto rx_exit;
 724			}
 725		} else if (!frame_authorized) {
 726			printk(KERN_DEBUG "%s: dropped frame from "
 727			       "unauthorized port (IEEE 802.1X): "
 728			       "ethertype=0x%04x\n", dev->name, ethertype);
 729			goto rx_dropped;
 730		}
 731	}
 732#endif
 733
 734	/* convert hdr + possible LLC headers into Ethernet header */
 735	if (skb->len - hdrlen >= 8 &&
 736	    ((memcmp(payload, libipw_rfc1042_header, SNAP_SIZE) == 0 &&
 737	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
 738	     memcmp(payload, libipw_bridge_tunnel_header, SNAP_SIZE) == 0)) {
 739		/* remove RFC1042 or Bridge-Tunnel encapsulation and
 740		 * replace EtherType */
 741		skb_pull(skb, hdrlen + SNAP_SIZE);
 742		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
 743		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
 744	} else {
 745		__be16 len;
 746		/* Leave Ethernet header part of hdr and full payload */
 747		skb_pull(skb, hdrlen);
 748		len = htons(skb->len);
 749		memcpy(skb_push(skb, 2), &len, 2);
 750		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
 751		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
 752	}
 753
 754#ifdef NOT_YET
 755	if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 756		    IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
 757		/* Non-standard frame: get addr4 from its bogus location after
 758		 * the payload */
 759		skb_copy_to_linear_data_offset(skb, ETH_ALEN,
 760					       skb->data + skb->len - ETH_ALEN,
 761					       ETH_ALEN);
 762		skb_trim(skb, skb->len - ETH_ALEN);
 763	}
 764#endif
 765
 766	dev->stats.rx_packets++;
 767	dev->stats.rx_bytes += skb->len;
 768
 769#ifdef NOT_YET
 770	if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
 771		if (is_multicast_ether_addr(dst)) {
 772			/* copy multicast frame both to the higher layers and
 773			 * to the wireless media */
 774			ieee->ap->bridged_multicast++;
 775			skb2 = skb_clone(skb, GFP_ATOMIC);
 776			if (skb2 == NULL)
 777				printk(KERN_DEBUG "%s: skb_clone failed for "
 778				       "multicast frame\n", dev->name);
 779		} else if (hostap_is_sta_assoc(ieee->ap, dst)) {
 780			/* send frame directly to the associated STA using
 781			 * wireless media and not passing to higher layers */
 782			ieee->ap->bridged_unicast++;
 783			skb2 = skb;
 784			skb = NULL;
 785		}
 786	}
 787
 788	if (skb2 != NULL) {
 789		/* send to wireless media */
 790		skb2->dev = dev;
 791		skb2->protocol = htons(ETH_P_802_3);
 792		skb_reset_mac_header(skb2);
 793		skb_reset_network_header(skb2);
 794		/* skb2->network_header += ETH_HLEN; */
 795		dev_queue_xmit(skb2);
 796	}
 797#endif
 798
 799	if (skb) {
 800		skb->protocol = eth_type_trans(skb, dev);
 801		memset(skb->cb, 0, sizeof(skb->cb));
 802		skb->ip_summed = CHECKSUM_NONE;	/* 802.11 crc not sufficient */
 803		if (netif_rx(skb) == NET_RX_DROP) {
 804			/* netif_rx always succeeds, but it might drop
 805			 * the packet.  If it drops the packet, we log that
 806			 * in our stats. */
 807			LIBIPW_DEBUG_DROP
 808			    ("RX: netif_rx dropped the packet\n");
 809			dev->stats.rx_dropped++;
 810		}
 811	}
 812
 813      rx_exit:
 814#ifdef NOT_YET
 815	if (sta)
 816		hostap_handle_sta_release(sta);
 817#endif
 818	return 1;
 819
 820      rx_dropped:
 821	dev->stats.rx_dropped++;
 822
 823	/* Returning 0 indicates to caller that we have not handled the SKB--
 824	 * so it is still allocated and can be used again by underlying
 825	 * hardware as a DMA target */
 826	return 0;
 827}
 828
 829/* Filter out unrelated packets, call libipw_rx[_mgt]
 830 * This function takes over the skb, it should not be used again after calling
 831 * this function. */
 832void libipw_rx_any(struct libipw_device *ieee,
 833		     struct sk_buff *skb, struct libipw_rx_stats *stats)
 834{
 835	struct libipw_hdr_4addr *hdr;
 836	int is_packet_for_us;
 837	u16 fc;
 838
 839	if (ieee->iw_mode == IW_MODE_MONITOR) {
 840		if (!libipw_rx(ieee, skb, stats))
 841			dev_kfree_skb_irq(skb);
 842		return;
 843	}
 844
 845	if (skb->len < sizeof(struct ieee80211_hdr))
 846		goto drop_free;
 847
 848	hdr = (struct libipw_hdr_4addr *)skb->data;
 849	fc = le16_to_cpu(hdr->frame_ctl);
 850
 851	if ((fc & IEEE80211_FCTL_VERS) != 0)
 852		goto drop_free;
 853
 854	switch (fc & IEEE80211_FCTL_FTYPE) {
 855	case IEEE80211_FTYPE_MGMT:
 856		if (skb->len < sizeof(struct libipw_hdr_3addr))
 857			goto drop_free;
 858		libipw_rx_mgt(ieee, hdr, stats);
 859		dev_kfree_skb_irq(skb);
 860		return;
 861	case IEEE80211_FTYPE_DATA:
 862		break;
 863	case IEEE80211_FTYPE_CTL:
 864		return;
 865	default:
 866		return;
 867	}
 868
 869	is_packet_for_us = 0;
 870	switch (ieee->iw_mode) {
 871	case IW_MODE_ADHOC:
 872		/* our BSS and not from/to DS */
 873		if (ether_addr_equal(hdr->addr3, ieee->bssid))
 874		if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) {
 875			/* promisc: get all */
 876			if (ieee->dev->flags & IFF_PROMISC)
 877				is_packet_for_us = 1;
 878			/* to us */
 879			else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr))
 880				is_packet_for_us = 1;
 881			/* mcast */
 882			else if (is_multicast_ether_addr(hdr->addr1))
 883				is_packet_for_us = 1;
 884		}
 885		break;
 886	case IW_MODE_INFRA:
 887		/* our BSS (== from our AP) and from DS */
 888		if (ether_addr_equal(hdr->addr2, ieee->bssid))
 889		if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) {
 890			/* promisc: get all */
 891			if (ieee->dev->flags & IFF_PROMISC)
 892				is_packet_for_us = 1;
 893			/* to us */
 894			else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr))
 895				is_packet_for_us = 1;
 896			/* mcast */
 897			else if (is_multicast_ether_addr(hdr->addr1)) {
 898				/* not our own packet bcasted from AP */
 899				if (!ether_addr_equal(hdr->addr3, ieee->dev->dev_addr))
 900					is_packet_for_us = 1;
 901			}
 902		}
 903		break;
 904	default:
 905		/* ? */
 906		break;
 907	}
 908
 909	if (is_packet_for_us)
 910		if (!libipw_rx(ieee, skb, stats))
 911			dev_kfree_skb_irq(skb);
 912	return;
 913
 914drop_free:
 915	dev_kfree_skb_irq(skb);
 916	ieee->dev->stats.rx_dropped++;
 917}
 918
 919#define MGMT_FRAME_FIXED_PART_LENGTH		0x24
 920
 921static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
 922
 923/*
 924* Make the structure we read from the beacon packet to have
 925* the right values
 926*/
 927static int libipw_verify_qos_info(struct libipw_qos_information_element
 928				     *info_element, int sub_type)
 929{
 930	if (info_element->elementID != QOS_ELEMENT_ID)
 931		return -1;
 932	if (info_element->qui_subtype != sub_type)
 933		return -1;
 934	if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
 935		return -1;
 936	if (info_element->qui_type != QOS_OUI_TYPE)
 937		return -1;
 938	if (info_element->version != QOS_VERSION_1)
 939		return -1;
 940
 941	return 0;
 942}
 943
 944/*
 945 * Parse a QoS parameter element
 946 */
 947static int libipw_read_qos_param_element(
 948			struct libipw_qos_parameter_info *element_param,
 949			struct libipw_info_element *info_element)
 950{
 951	size_t size = sizeof(*element_param);
 
 952
 953	if (!element_param || !info_element || info_element->len != size - 2)
 954		return -1;
 955
 956	memcpy(element_param, info_element, size);
 957	return libipw_verify_qos_info(&element_param->info_element,
 958				      QOS_OUI_PARAM_SUB_TYPE);
 
 
 
 
 
 
 
 
 959}
 960
 961/*
 962 * Parse a QoS information element
 963 */
 964static int libipw_read_qos_info_element(
 965			struct libipw_qos_information_element *element_info,
 966			struct libipw_info_element *info_element)
 
 967{
 968	size_t size = sizeof(struct libipw_qos_information_element) - 2;
 
 969
 970	if (!element_info || !info_element || info_element->len != size - 2)
 
 
 971		return -1;
 972
 973	memcpy(element_info, info_element, size);
 974	return libipw_verify_qos_info(element_info, QOS_OUI_INFO_SUB_TYPE);
 
 
 
 
 
 
 
 
 
 
 975}
 976
 977/*
 978 * Write QoS parameters from the ac parameters.
 979 */
 980static void libipw_qos_convert_ac_to_parameters(struct
 981						  libipw_qos_parameter_info
 982						  *param_elm, struct
 983						  libipw_qos_parameters
 984						  *qos_param)
 985{
 
 986	int i;
 987	struct libipw_qos_ac_parameter *ac_params;
 988	u32 txop;
 989	u8 cw_min;
 990	u8 cw_max;
 991
 992	for (i = 0; i < QOS_QUEUE_NUM; i++) {
 993		ac_params = &(param_elm->ac_params_record[i]);
 994
 995		qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
 996		qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
 997
 998		cw_min = ac_params->ecw_min_max & 0x0F;
 999		qos_param->cw_min[i] = cpu_to_le16((1 << cw_min) - 1);
1000
1001		cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
1002		qos_param->cw_max[i] = cpu_to_le16((1 << cw_max) - 1);
1003
1004		qos_param->flag[i] =
1005		    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
1006
1007		txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
1008		qos_param->tx_op_limit[i] = cpu_to_le16(txop);
1009	}
 
1010}
1011
1012/*
1013 * we have a generic data element which it may contain QoS information or
1014 * parameters element. check the information element length to decide
1015 * which type to read
1016 */
1017static int libipw_parse_qos_info_param_IE(struct libipw_info_element
1018					     *info_element,
1019					     struct libipw_network *network)
1020{
1021	int rc = 0;
1022	struct libipw_qos_parameters *qos_param = NULL;
1023	struct libipw_qos_information_element qos_info_element;
1024
1025	rc = libipw_read_qos_info_element(&qos_info_element, info_element);
1026
1027	if (rc == 0) {
1028		network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
1029		network->flags |= NETWORK_HAS_QOS_INFORMATION;
1030	} else {
1031		struct libipw_qos_parameter_info param_element;
1032
1033		rc = libipw_read_qos_param_element(&param_element,
1034						      info_element);
1035		if (rc == 0) {
1036			qos_param = &(network->qos_data.parameters);
1037			libipw_qos_convert_ac_to_parameters(&param_element,
1038							       qos_param);
1039			network->flags |= NETWORK_HAS_QOS_PARAMETERS;
1040			network->qos_data.param_count =
1041			    param_element.info_element.ac_info & 0x0F;
1042		}
1043	}
1044
1045	if (rc == 0) {
1046		LIBIPW_DEBUG_QOS("QoS is supported\n");
1047		network->qos_data.supported = 1;
1048	}
1049	return rc;
1050}
1051
1052#ifdef CONFIG_LIBIPW_DEBUG
1053#define MFIE_STRING(x) case WLAN_EID_ ##x: return #x
1054
1055static const char *get_info_element_string(u16 id)
1056{
1057	switch (id) {
1058		MFIE_STRING(SSID);
1059		MFIE_STRING(SUPP_RATES);
1060		MFIE_STRING(FH_PARAMS);
1061		MFIE_STRING(DS_PARAMS);
1062		MFIE_STRING(CF_PARAMS);
1063		MFIE_STRING(TIM);
1064		MFIE_STRING(IBSS_PARAMS);
1065		MFIE_STRING(COUNTRY);
1066		MFIE_STRING(REQUEST);
1067		MFIE_STRING(CHALLENGE);
1068		MFIE_STRING(PWR_CONSTRAINT);
1069		MFIE_STRING(PWR_CAPABILITY);
1070		MFIE_STRING(TPC_REQUEST);
1071		MFIE_STRING(TPC_REPORT);
1072		MFIE_STRING(SUPPORTED_CHANNELS);
1073		MFIE_STRING(CHANNEL_SWITCH);
1074		MFIE_STRING(MEASURE_REQUEST);
1075		MFIE_STRING(MEASURE_REPORT);
1076		MFIE_STRING(QUIET);
1077		MFIE_STRING(IBSS_DFS);
1078		MFIE_STRING(ERP_INFO);
1079		MFIE_STRING(RSN);
1080		MFIE_STRING(EXT_SUPP_RATES);
1081		MFIE_STRING(VENDOR_SPECIFIC);
1082		MFIE_STRING(QOS_PARAMETER);
1083	default:
1084		return "UNKNOWN";
1085	}
1086}
1087#endif
1088
1089static int libipw_parse_info_param(struct libipw_info_element
1090				      *info_element, u16 length,
1091				      struct libipw_network *network)
1092{
1093	u8 i;
1094#ifdef CONFIG_LIBIPW_DEBUG
1095	char rates_str[64];
1096	char *p;
1097#endif
1098
1099	while (length >= sizeof(*info_element)) {
1100		if (sizeof(*info_element) + info_element->len > length) {
1101			LIBIPW_DEBUG_MGMT("Info elem: parse failed: "
1102					     "info_element->len + 2 > left : "
1103					     "info_element->len+2=%zd left=%d, id=%d.\n",
1104					     info_element->len +
1105					     sizeof(*info_element),
1106					     length, info_element->id);
1107			/* We stop processing but don't return an error here
1108			 * because some misbehaviour APs break this rule. ie.
1109			 * Orinoco AP1000. */
1110			break;
1111		}
1112
1113		switch (info_element->id) {
1114		case WLAN_EID_SSID:
1115			network->ssid_len = min(info_element->len,
1116						(u8) IW_ESSID_MAX_SIZE);
1117			memcpy(network->ssid, info_element->data,
1118			       network->ssid_len);
1119			if (network->ssid_len < IW_ESSID_MAX_SIZE)
1120				memset(network->ssid + network->ssid_len, 0,
1121				       IW_ESSID_MAX_SIZE - network->ssid_len);
1122
1123			LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%*pE' len=%d.\n",
1124					  network->ssid_len, network->ssid,
1125					  network->ssid_len);
1126			break;
1127
1128		case WLAN_EID_SUPP_RATES:
1129#ifdef CONFIG_LIBIPW_DEBUG
1130			p = rates_str;
1131#endif
1132			network->rates_len = min(info_element->len,
1133						 MAX_RATES_LENGTH);
1134			for (i = 0; i < network->rates_len; i++) {
1135				network->rates[i] = info_element->data[i];
1136#ifdef CONFIG_LIBIPW_DEBUG
1137				p += scnprintf(p, sizeof(rates_str) -
1138					      (p - rates_str), "%02X ",
1139					      network->rates[i]);
1140#endif
1141				if (libipw_is_ofdm_rate
1142				    (info_element->data[i])) {
1143					network->flags |= NETWORK_HAS_OFDM;
1144					if (info_element->data[i] &
1145					    LIBIPW_BASIC_RATE_MASK)
1146						network->flags &=
1147						    ~NETWORK_HAS_CCK;
1148				}
1149			}
1150
1151			LIBIPW_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
1152					     rates_str, network->rates_len);
1153			break;
1154
1155		case WLAN_EID_EXT_SUPP_RATES:
1156#ifdef CONFIG_LIBIPW_DEBUG
1157			p = rates_str;
1158#endif
1159			network->rates_ex_len = min(info_element->len,
1160						    MAX_RATES_EX_LENGTH);
1161			for (i = 0; i < network->rates_ex_len; i++) {
1162				network->rates_ex[i] = info_element->data[i];
1163#ifdef CONFIG_LIBIPW_DEBUG
1164				p += scnprintf(p, sizeof(rates_str) -
1165					      (p - rates_str), "%02X ",
1166					      network->rates_ex[i]);
1167#endif
1168				if (libipw_is_ofdm_rate
1169				    (info_element->data[i])) {
1170					network->flags |= NETWORK_HAS_OFDM;
1171					if (info_element->data[i] &
1172					    LIBIPW_BASIC_RATE_MASK)
1173						network->flags &=
1174						    ~NETWORK_HAS_CCK;
1175				}
1176			}
1177
1178			LIBIPW_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
1179					     rates_str, network->rates_ex_len);
1180			break;
1181
1182		case WLAN_EID_DS_PARAMS:
1183			LIBIPW_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
1184					     info_element->data[0]);
1185			network->channel = info_element->data[0];
1186			break;
1187
1188		case WLAN_EID_FH_PARAMS:
1189			LIBIPW_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
1190			break;
1191
1192		case WLAN_EID_CF_PARAMS:
1193			LIBIPW_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
1194			break;
1195
1196		case WLAN_EID_TIM:
1197			network->tim.tim_count = info_element->data[0];
1198			network->tim.tim_period = info_element->data[1];
1199			LIBIPW_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
1200			break;
1201
1202		case WLAN_EID_ERP_INFO:
1203			network->erp_value = info_element->data[0];
1204			network->flags |= NETWORK_HAS_ERP_VALUE;
1205			LIBIPW_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1206					     network->erp_value);
1207			break;
1208
1209		case WLAN_EID_IBSS_PARAMS:
1210			network->atim_window = info_element->data[0];
1211			LIBIPW_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
1212					     network->atim_window);
1213			break;
1214
1215		case WLAN_EID_CHALLENGE:
1216			LIBIPW_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
1217			break;
1218
1219		case WLAN_EID_VENDOR_SPECIFIC:
1220			LIBIPW_DEBUG_MGMT("WLAN_EID_VENDOR_SPECIFIC: %d bytes\n",
1221					     info_element->len);
1222			if (!libipw_parse_qos_info_param_IE(info_element,
1223							       network))
1224				break;
1225
1226			if (info_element->len >= 4 &&
1227			    info_element->data[0] == 0x00 &&
1228			    info_element->data[1] == 0x50 &&
1229			    info_element->data[2] == 0xf2 &&
1230			    info_element->data[3] == 0x01) {
1231				network->wpa_ie_len = min(info_element->len + 2,
1232							  MAX_WPA_IE_LEN);
1233				memcpy(network->wpa_ie, info_element,
1234				       network->wpa_ie_len);
1235			}
1236			break;
1237
1238		case WLAN_EID_RSN:
1239			LIBIPW_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
1240					     info_element->len);
1241			network->rsn_ie_len = min(info_element->len + 2,
1242						  MAX_WPA_IE_LEN);
1243			memcpy(network->rsn_ie, info_element,
1244			       network->rsn_ie_len);
1245			break;
1246
1247		case WLAN_EID_QOS_PARAMETER:
1248			printk(KERN_ERR
1249			       "QoS Error need to parse QOS_PARAMETER IE\n");
1250			break;
1251			/* 802.11h */
1252		case WLAN_EID_PWR_CONSTRAINT:
1253			network->power_constraint = info_element->data[0];
1254			network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
1255			break;
1256
1257		case WLAN_EID_CHANNEL_SWITCH:
1258			network->power_constraint = info_element->data[0];
1259			network->flags |= NETWORK_HAS_CSA;
1260			break;
1261
1262		case WLAN_EID_QUIET:
1263			network->quiet.count = info_element->data[0];
1264			network->quiet.period = info_element->data[1];
1265			network->quiet.duration = info_element->data[2];
1266			network->quiet.offset = info_element->data[3];
1267			network->flags |= NETWORK_HAS_QUIET;
1268			break;
1269
1270		case WLAN_EID_IBSS_DFS:
1271			network->flags |= NETWORK_HAS_IBSS_DFS;
1272			break;
1273
1274		case WLAN_EID_TPC_REPORT:
1275			network->tpc_report.transmit_power =
1276			    info_element->data[0];
1277			network->tpc_report.link_margin = info_element->data[1];
1278			network->flags |= NETWORK_HAS_TPC_REPORT;
1279			break;
1280
1281		default:
1282			LIBIPW_DEBUG_MGMT
1283			    ("Unsupported info element: %s (%d)\n",
1284			     get_info_element_string(info_element->id),
1285			     info_element->id);
1286			break;
1287		}
1288
1289		length -= sizeof(*info_element) + info_element->len;
1290		info_element =
1291		    (struct libipw_info_element *)&info_element->
1292		    data[info_element->len];
1293	}
1294
1295	return 0;
1296}
1297
1298static int libipw_handle_assoc_resp(struct libipw_device *ieee, struct libipw_assoc_response
1299				       *frame, struct libipw_rx_stats *stats)
1300{
1301	struct libipw_network network_resp = { };
1302	struct libipw_network *network = &network_resp;
1303	struct net_device *dev = ieee->dev;
1304
1305	network->flags = 0;
1306	network->qos_data.active = 0;
1307	network->qos_data.supported = 0;
1308	network->qos_data.param_count = 0;
1309	network->qos_data.old_param_count = 0;
1310
1311	//network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
1312	network->atim_window = le16_to_cpu(frame->aid);
1313	network->listen_interval = le16_to_cpu(frame->status);
1314	memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
1315	network->capability = le16_to_cpu(frame->capability);
1316	network->last_scanned = jiffies;
1317	network->rates_len = network->rates_ex_len = 0;
1318	network->last_associate = 0;
1319	network->ssid_len = 0;
1320	network->erp_value =
1321	    (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
1322
1323	if (stats->freq == LIBIPW_52GHZ_BAND) {
1324		/* for A band (No DS info) */
1325		network->channel = stats->received_channel;
1326	} else
1327		network->flags |= NETWORK_HAS_CCK;
1328
1329	network->wpa_ie_len = 0;
1330	network->rsn_ie_len = 0;
1331
1332	if (libipw_parse_info_param((void *)frame->variable,
1333				    stats->len - sizeof(*frame), network))
1334		return 1;
1335
1336	network->mode = 0;
1337	if (stats->freq == LIBIPW_52GHZ_BAND)
1338		network->mode = IEEE_A;
1339	else {
1340		if (network->flags & NETWORK_HAS_OFDM)
1341			network->mode |= IEEE_G;
1342		if (network->flags & NETWORK_HAS_CCK)
1343			network->mode |= IEEE_B;
1344	}
1345
1346	memcpy(&network->stats, stats, sizeof(network->stats));
1347
1348	if (ieee->handle_assoc_response != NULL)
1349		ieee->handle_assoc_response(dev, frame, network);
1350
1351	return 0;
1352}
1353
1354/***************************************************/
1355
1356static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_response
1357					 *beacon,
1358					 struct libipw_network *network,
1359					 struct libipw_rx_stats *stats)
1360{
1361	network->qos_data.active = 0;
1362	network->qos_data.supported = 0;
1363	network->qos_data.param_count = 0;
1364	network->qos_data.old_param_count = 0;
1365
1366	/* Pull out fixed field data */
1367	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1368	network->capability = le16_to_cpu(beacon->capability);
1369	network->last_scanned = jiffies;
1370	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1371	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1372	network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1373	/* Where to pull this? beacon->listen_interval; */
1374	network->listen_interval = 0x0A;
1375	network->rates_len = network->rates_ex_len = 0;
1376	network->last_associate = 0;
1377	network->ssid_len = 0;
1378	network->flags = 0;
1379	network->atim_window = 0;
1380	network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1381	    0x3 : 0x0;
1382
1383	if (stats->freq == LIBIPW_52GHZ_BAND) {
1384		/* for A band (No DS info) */
1385		network->channel = stats->received_channel;
1386	} else
1387		network->flags |= NETWORK_HAS_CCK;
1388
1389	network->wpa_ie_len = 0;
1390	network->rsn_ie_len = 0;
1391
1392	if (libipw_parse_info_param((void *)beacon->variable,
1393				    stats->len - sizeof(*beacon), network))
1394		return 1;
1395
1396	network->mode = 0;
1397	if (stats->freq == LIBIPW_52GHZ_BAND)
1398		network->mode = IEEE_A;
1399	else {
1400		if (network->flags & NETWORK_HAS_OFDM)
1401			network->mode |= IEEE_G;
1402		if (network->flags & NETWORK_HAS_CCK)
1403			network->mode |= IEEE_B;
1404	}
1405
1406	if (network->mode == 0) {
1407		LIBIPW_DEBUG_SCAN("Filtered out '%*pE (%pM)' network.\n",
1408				  network->ssid_len, network->ssid,
1409				  network->bssid);
1410		return 1;
1411	}
1412
1413	memcpy(&network->stats, stats, sizeof(network->stats));
1414
1415	return 0;
1416}
1417
1418static inline int is_same_network(struct libipw_network *src,
1419				  struct libipw_network *dst)
1420{
1421	/* A network is only a duplicate if the channel, BSSID, and ESSID
1422	 * all match.  We treat all <hidden> with the same BSSID and channel
1423	 * as one network */
1424	return ((src->ssid_len == dst->ssid_len) &&
1425		(src->channel == dst->channel) &&
1426		ether_addr_equal_64bits(src->bssid, dst->bssid) &&
1427		!memcmp(src->ssid, dst->ssid, src->ssid_len));
1428}
1429
1430static void update_network(struct libipw_network *dst,
1431				  struct libipw_network *src)
1432{
1433	int qos_active;
1434	u8 old_param;
1435
1436	/* We only update the statistics if they were created by receiving
1437	 * the network information on the actual channel the network is on.
1438	 *
1439	 * This keeps beacons received on neighbor channels from bringing
1440	 * down the signal level of an AP. */
1441	if (dst->channel == src->stats.received_channel)
1442		memcpy(&dst->stats, &src->stats,
1443		       sizeof(struct libipw_rx_stats));
1444	else
1445		LIBIPW_DEBUG_SCAN("Network %pM info received "
1446			"off channel (%d vs. %d)\n", src->bssid,
1447			dst->channel, src->stats.received_channel);
1448
1449	dst->capability = src->capability;
1450	memcpy(dst->rates, src->rates, src->rates_len);
1451	dst->rates_len = src->rates_len;
1452	memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1453	dst->rates_ex_len = src->rates_ex_len;
1454
1455	dst->mode = src->mode;
1456	dst->flags = src->flags;
1457	dst->time_stamp[0] = src->time_stamp[0];
1458	dst->time_stamp[1] = src->time_stamp[1];
1459
1460	dst->beacon_interval = src->beacon_interval;
1461	dst->listen_interval = src->listen_interval;
1462	dst->atim_window = src->atim_window;
1463	dst->erp_value = src->erp_value;
1464	dst->tim = src->tim;
1465
1466	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1467	dst->wpa_ie_len = src->wpa_ie_len;
1468	memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1469	dst->rsn_ie_len = src->rsn_ie_len;
1470
1471	dst->last_scanned = jiffies;
1472	qos_active = src->qos_data.active;
1473	old_param = dst->qos_data.old_param_count;
1474	if (dst->flags & NETWORK_HAS_QOS_MASK)
1475		memcpy(&dst->qos_data, &src->qos_data,
1476		       sizeof(struct libipw_qos_data));
1477	else {
1478		dst->qos_data.supported = src->qos_data.supported;
1479		dst->qos_data.param_count = src->qos_data.param_count;
1480	}
1481
1482	if (dst->qos_data.supported == 1) {
1483		if (dst->ssid_len)
1484			LIBIPW_DEBUG_QOS
1485			    ("QoS the network %s is QoS supported\n",
1486			     dst->ssid);
1487		else
1488			LIBIPW_DEBUG_QOS
1489			    ("QoS the network is QoS supported\n");
1490	}
1491	dst->qos_data.active = qos_active;
1492	dst->qos_data.old_param_count = old_param;
1493
1494	/* dst->last_associate is not overwritten */
1495}
1496
1497static inline int is_beacon(__le16 fc)
1498{
1499	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
1500}
1501
1502static void libipw_process_probe_response(struct libipw_device
1503						    *ieee, struct
1504						    libipw_probe_response
1505						    *beacon, struct libipw_rx_stats
1506						    *stats)
1507{
1508	struct net_device *dev = ieee->dev;
1509	struct libipw_network network = { };
1510	struct libipw_network *target;
1511	struct libipw_network *oldest = NULL;
1512#ifdef CONFIG_LIBIPW_DEBUG
1513	struct libipw_info_element *info_element = (void *)beacon->variable;
1514#endif
1515	unsigned long flags;
1516
1517	LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1518		     info_element->len, info_element->data,
1519		     beacon->header.addr3,
1520		     (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
1521		     (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
1522		     (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
1523		     (beacon->capability & cpu_to_le16(1 << 0xc)) ? '1' : '0',
1524		     (beacon->capability & cpu_to_le16(1 << 0xb)) ? '1' : '0',
1525		     (beacon->capability & cpu_to_le16(1 << 0xa)) ? '1' : '0',
1526		     (beacon->capability & cpu_to_le16(1 << 0x9)) ? '1' : '0',
1527		     (beacon->capability & cpu_to_le16(1 << 0x8)) ? '1' : '0',
1528		     (beacon->capability & cpu_to_le16(1 << 0x7)) ? '1' : '0',
1529		     (beacon->capability & cpu_to_le16(1 << 0x6)) ? '1' : '0',
1530		     (beacon->capability & cpu_to_le16(1 << 0x5)) ? '1' : '0',
1531		     (beacon->capability & cpu_to_le16(1 << 0x4)) ? '1' : '0',
1532		     (beacon->capability & cpu_to_le16(1 << 0x3)) ? '1' : '0',
1533		     (beacon->capability & cpu_to_le16(1 << 0x2)) ? '1' : '0',
1534		     (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
1535		     (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
1536
1537	if (libipw_network_init(ieee, beacon, &network, stats)) {
1538		LIBIPW_DEBUG_SCAN("Dropped '%*pE' (%pM) via %s.\n",
1539				  info_element->len, info_element->data,
1540				  beacon->header.addr3,
1541				  is_beacon(beacon->header.frame_ctl) ?
1542				  "BEACON" : "PROBE RESPONSE");
1543		return;
1544	}
1545
1546	/* The network parsed correctly -- so now we scan our known networks
1547	 * to see if we can find it in our list.
1548	 *
1549	 * NOTE:  This search is definitely not optimized.  Once its doing
1550	 *        the "right thing" we'll optimize it for efficiency if
1551	 *        necessary */
1552
1553	/* Search for this entry in the list and update it if it is
1554	 * already there. */
1555
1556	spin_lock_irqsave(&ieee->lock, flags);
1557
1558	list_for_each_entry(target, &ieee->network_list, list) {
1559		if (is_same_network(target, &network))
1560			break;
1561
1562		if ((oldest == NULL) ||
1563		    time_before(target->last_scanned, oldest->last_scanned))
1564			oldest = target;
1565	}
1566
1567	/* If we didn't find a match, then get a new network slot to initialize
1568	 * with this beacon's information */
1569	if (&target->list == &ieee->network_list) {
1570		if (list_empty(&ieee->network_free_list)) {
1571			/* If there are no more slots, expire the oldest */
1572			list_del(&oldest->list);
1573			target = oldest;
1574			LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n",
1575					  target->ssid_len, target->ssid,
1576					  target->bssid);
1577		} else {
1578			/* Otherwise just pull from the free list */
1579			target = list_entry(ieee->network_free_list.next,
1580					    struct libipw_network, list);
1581			list_del(ieee->network_free_list.next);
1582		}
1583
1584#ifdef CONFIG_LIBIPW_DEBUG
1585		LIBIPW_DEBUG_SCAN("Adding '%*pE' (%pM) via %s.\n",
1586				  network.ssid_len, network.ssid,
1587				  network.bssid,
1588				  is_beacon(beacon->header.frame_ctl) ?
1589				  "BEACON" : "PROBE RESPONSE");
1590#endif
1591		memcpy(target, &network, sizeof(*target));
1592		list_add_tail(&target->list, &ieee->network_list);
1593	} else {
1594		LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n",
1595				  target->ssid_len, target->ssid,
1596				  target->bssid,
1597				  is_beacon(beacon->header.frame_ctl) ?
1598				  "BEACON" : "PROBE RESPONSE");
1599		update_network(target, &network);
1600	}
1601
1602	spin_unlock_irqrestore(&ieee->lock, flags);
1603
1604	if (is_beacon(beacon->header.frame_ctl)) {
1605		if (ieee->handle_beacon != NULL)
1606			ieee->handle_beacon(dev, beacon, target);
1607	} else {
1608		if (ieee->handle_probe_response != NULL)
1609			ieee->handle_probe_response(dev, beacon, target);
1610	}
1611}
1612
1613void libipw_rx_mgt(struct libipw_device *ieee,
1614		      struct libipw_hdr_4addr *header,
1615		      struct libipw_rx_stats *stats)
1616{
1617	switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
1618	case IEEE80211_STYPE_ASSOC_RESP:
1619		LIBIPW_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
1620				     WLAN_FC_GET_STYPE(le16_to_cpu
1621						       (header->frame_ctl)));
1622		libipw_handle_assoc_resp(ieee,
1623					    (struct libipw_assoc_response *)
1624					    header, stats);
1625		break;
1626
1627	case IEEE80211_STYPE_REASSOC_RESP:
1628		LIBIPW_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
1629				     WLAN_FC_GET_STYPE(le16_to_cpu
1630						       (header->frame_ctl)));
1631		break;
1632
1633	case IEEE80211_STYPE_PROBE_REQ:
1634		LIBIPW_DEBUG_MGMT("received auth (%d)\n",
1635				     WLAN_FC_GET_STYPE(le16_to_cpu
1636						       (header->frame_ctl)));
1637
1638		if (ieee->handle_probe_request != NULL)
1639			ieee->handle_probe_request(ieee->dev,
1640						   (struct
1641						    libipw_probe_request *)
1642						   header, stats);
1643		break;
1644
1645	case IEEE80211_STYPE_PROBE_RESP:
1646		LIBIPW_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1647				     WLAN_FC_GET_STYPE(le16_to_cpu
1648						       (header->frame_ctl)));
1649		LIBIPW_DEBUG_SCAN("Probe response\n");
1650		libipw_process_probe_response(ieee,
1651						 (struct
1652						  libipw_probe_response *)
1653						 header, stats);
1654		break;
1655
1656	case IEEE80211_STYPE_BEACON:
1657		LIBIPW_DEBUG_MGMT("received BEACON (%d)\n",
1658				     WLAN_FC_GET_STYPE(le16_to_cpu
1659						       (header->frame_ctl)));
1660		LIBIPW_DEBUG_SCAN("Beacon\n");
1661		libipw_process_probe_response(ieee,
1662						 (struct
1663						  libipw_probe_response *)
1664						 header, stats);
1665		break;
1666	case IEEE80211_STYPE_AUTH:
1667
1668		LIBIPW_DEBUG_MGMT("received auth (%d)\n",
1669				     WLAN_FC_GET_STYPE(le16_to_cpu
1670						       (header->frame_ctl)));
1671
1672		if (ieee->handle_auth != NULL)
1673			ieee->handle_auth(ieee->dev,
1674					  (struct libipw_auth *)header);
1675		break;
1676
1677	case IEEE80211_STYPE_DISASSOC:
1678		if (ieee->handle_disassoc != NULL)
1679			ieee->handle_disassoc(ieee->dev,
1680					      (struct libipw_disassoc *)
1681					      header);
1682		break;
1683
1684	case IEEE80211_STYPE_ACTION:
1685		LIBIPW_DEBUG_MGMT("ACTION\n");
1686		if (ieee->handle_action)
1687			ieee->handle_action(ieee->dev,
1688					    (struct libipw_action *)
1689					    header, stats);
1690		break;
1691
1692	case IEEE80211_STYPE_REASSOC_REQ:
1693		LIBIPW_DEBUG_MGMT("received reassoc (%d)\n",
1694				     WLAN_FC_GET_STYPE(le16_to_cpu
1695						       (header->frame_ctl)));
1696
1697		LIBIPW_DEBUG_MGMT("%s: LIBIPW_REASSOC_REQ received\n",
1698				     ieee->dev->name);
1699		if (ieee->handle_reassoc_request != NULL)
1700			ieee->handle_reassoc_request(ieee->dev,
1701						    (struct libipw_reassoc_request *)
1702						     header);
1703		break;
1704
1705	case IEEE80211_STYPE_ASSOC_REQ:
1706		LIBIPW_DEBUG_MGMT("received assoc (%d)\n",
1707				     WLAN_FC_GET_STYPE(le16_to_cpu
1708						       (header->frame_ctl)));
1709
1710		LIBIPW_DEBUG_MGMT("%s: LIBIPW_ASSOC_REQ received\n",
1711				     ieee->dev->name);
1712		if (ieee->handle_assoc_request != NULL)
1713			ieee->handle_assoc_request(ieee->dev);
1714		break;
1715
1716	case IEEE80211_STYPE_DEAUTH:
1717		LIBIPW_DEBUG_MGMT("DEAUTH\n");
1718		if (ieee->handle_deauth != NULL)
1719			ieee->handle_deauth(ieee->dev,
1720					    (struct libipw_deauth *)
1721					    header);
1722		break;
1723	default:
1724		LIBIPW_DEBUG_MGMT("received UNKNOWN (%d)\n",
1725				     WLAN_FC_GET_STYPE(le16_to_cpu
1726						       (header->frame_ctl)));
1727		LIBIPW_DEBUG_MGMT("%s: Unknown management packet: %d\n",
1728				     ieee->dev->name,
1729				     WLAN_FC_GET_STYPE(le16_to_cpu
1730						       (header->frame_ctl)));
1731		break;
1732	}
1733}
1734
1735EXPORT_SYMBOL_GPL(libipw_rx_any);
1736EXPORT_SYMBOL(libipw_rx_mgt);
1737EXPORT_SYMBOL(libipw_rx);
v4.10.11
 
   1/*
   2 * Original code based Host AP (software wireless LAN access point) driver
   3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
   4 *
   5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
   6 * <j@w1.fi>
   7 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
   8 * Copyright (c) 2004-2005, Intel Corporation
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation. See README and COPYING for
  13 * more details.
  14 */
  15
  16#include <linux/compiler.h>
  17#include <linux/errno.h>
  18#include <linux/if_arp.h>
  19#include <linux/in6.h>
  20#include <linux/gfp.h>
  21#include <linux/in.h>
  22#include <linux/ip.h>
  23#include <linux/kernel.h>
  24#include <linux/module.h>
  25#include <linux/netdevice.h>
  26#include <linux/proc_fs.h>
  27#include <linux/skbuff.h>
  28#include <linux/tcp.h>
  29#include <linux/types.h>
  30#include <linux/wireless.h>
  31#include <linux/etherdevice.h>
  32#include <linux/uaccess.h>
  33#include <linux/ctype.h>
  34
  35#include <net/lib80211.h>
  36
  37#include "libipw.h"
  38
  39static void libipw_monitor_rx(struct libipw_device *ieee,
  40					struct sk_buff *skb,
  41					struct libipw_rx_stats *rx_stats)
  42{
  43	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  44	u16 fc = le16_to_cpu(hdr->frame_control);
  45
  46	skb->dev = ieee->dev;
  47	skb_reset_mac_header(skb);
  48	skb_pull(skb, libipw_get_hdrlen(fc));
  49	skb->pkt_type = PACKET_OTHERHOST;
  50	skb->protocol = htons(ETH_P_80211_RAW);
  51	memset(skb->cb, 0, sizeof(skb->cb));
  52	netif_rx(skb);
  53}
  54
  55/* Called only as a tasklet (software IRQ) */
  56static struct libipw_frag_entry *libipw_frag_cache_find(struct
  57							      libipw_device
  58							      *ieee,
  59							      unsigned int seq,
  60							      unsigned int frag,
  61							      u8 * src,
  62							      u8 * dst)
  63{
  64	struct libipw_frag_entry *entry;
  65	int i;
  66
  67	for (i = 0; i < LIBIPW_FRAG_CACHE_LEN; i++) {
  68		entry = &ieee->frag_cache[i];
  69		if (entry->skb != NULL &&
  70		    time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
  71			LIBIPW_DEBUG_FRAG("expiring fragment cache entry "
  72					     "seq=%u last_frag=%u\n",
  73					     entry->seq, entry->last_frag);
  74			dev_kfree_skb_any(entry->skb);
  75			entry->skb = NULL;
  76		}
  77
  78		if (entry->skb != NULL && entry->seq == seq &&
  79		    (entry->last_frag + 1 == frag || frag == -1) &&
  80		    ether_addr_equal(entry->src_addr, src) &&
  81		    ether_addr_equal(entry->dst_addr, dst))
  82			return entry;
  83	}
  84
  85	return NULL;
  86}
  87
  88/* Called only as a tasklet (software IRQ) */
  89static struct sk_buff *libipw_frag_cache_get(struct libipw_device *ieee,
  90						struct libipw_hdr_4addr *hdr)
  91{
  92	struct sk_buff *skb = NULL;
  93	u16 sc;
  94	unsigned int frag, seq;
  95	struct libipw_frag_entry *entry;
  96
  97	sc = le16_to_cpu(hdr->seq_ctl);
  98	frag = WLAN_GET_SEQ_FRAG(sc);
  99	seq = WLAN_GET_SEQ_SEQ(sc);
 100
 101	if (frag == 0) {
 102		/* Reserve enough space to fit maximum frame length */
 103		skb = dev_alloc_skb(ieee->dev->mtu +
 104				    sizeof(struct libipw_hdr_4addr) +
 105				    8 /* LLC */  +
 106				    2 /* alignment */  +
 107				    8 /* WEP */  + ETH_ALEN /* WDS */ );
 108		if (skb == NULL)
 109			return NULL;
 110
 111		entry = &ieee->frag_cache[ieee->frag_next_idx];
 112		ieee->frag_next_idx++;
 113		if (ieee->frag_next_idx >= LIBIPW_FRAG_CACHE_LEN)
 114			ieee->frag_next_idx = 0;
 115
 116		if (entry->skb != NULL)
 117			dev_kfree_skb_any(entry->skb);
 118
 119		entry->first_frag_time = jiffies;
 120		entry->seq = seq;
 121		entry->last_frag = frag;
 122		entry->skb = skb;
 123		memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
 124		memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
 125	} else {
 126		/* received a fragment of a frame for which the head fragment
 127		 * should have already been received */
 128		entry = libipw_frag_cache_find(ieee, seq, frag, hdr->addr2,
 129						  hdr->addr1);
 130		if (entry != NULL) {
 131			entry->last_frag = frag;
 132			skb = entry->skb;
 133		}
 134	}
 135
 136	return skb;
 137}
 138
 139/* Called only as a tasklet (software IRQ) */
 140static int libipw_frag_cache_invalidate(struct libipw_device *ieee,
 141					   struct libipw_hdr_4addr *hdr)
 142{
 143	u16 sc;
 144	unsigned int seq;
 145	struct libipw_frag_entry *entry;
 146
 147	sc = le16_to_cpu(hdr->seq_ctl);
 148	seq = WLAN_GET_SEQ_SEQ(sc);
 149
 150	entry = libipw_frag_cache_find(ieee, seq, -1, hdr->addr2,
 151					  hdr->addr1);
 152
 153	if (entry == NULL) {
 154		LIBIPW_DEBUG_FRAG("could not invalidate fragment cache "
 155				     "entry (seq=%u)\n", seq);
 156		return -1;
 157	}
 158
 159	entry->skb = NULL;
 160	return 0;
 161}
 162
 163#ifdef NOT_YET
 164/* libipw_rx_frame_mgtmt
 165 *
 166 * Responsible for handling management control frames
 167 *
 168 * Called by libipw_rx */
 169static int
 170libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb,
 171			struct libipw_rx_stats *rx_stats, u16 type,
 172			u16 stype)
 173{
 174	if (ieee->iw_mode == IW_MODE_MASTER) {
 175		printk(KERN_DEBUG "%s: Master mode not yet supported.\n",
 176		       ieee->dev->name);
 177		return 0;
 178/*
 179  hostap_update_sta_ps(ieee, (struct hostap_libipw_hdr_4addr *)
 180  skb->data);*/
 181	}
 182
 183	if (ieee->hostapd && type == WLAN_FC_TYPE_MGMT) {
 184		if (stype == WLAN_FC_STYPE_BEACON &&
 185		    ieee->iw_mode == IW_MODE_MASTER) {
 186			struct sk_buff *skb2;
 187			/* Process beacon frames also in kernel driver to
 188			 * update STA(AP) table statistics */
 189			skb2 = skb_clone(skb, GFP_ATOMIC);
 190			if (skb2)
 191				hostap_rx(skb2->dev, skb2, rx_stats);
 192		}
 193
 194		/* send management frames to the user space daemon for
 195		 * processing */
 196		ieee->apdevstats.rx_packets++;
 197		ieee->apdevstats.rx_bytes += skb->len;
 198		prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
 199		return 0;
 200	}
 201
 202	if (ieee->iw_mode == IW_MODE_MASTER) {
 203		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
 204			printk(KERN_DEBUG "%s: unknown management frame "
 205			       "(type=0x%02x, stype=0x%02x) dropped\n",
 206			       skb->dev->name, type, stype);
 207			return -1;
 208		}
 209
 210		hostap_rx(skb->dev, skb, rx_stats);
 211		return 0;
 212	}
 213
 214	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
 215	       "received in non-Host AP mode\n", skb->dev->name);
 216	return -1;
 217}
 218#endif
 219
 220/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
 221/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
 222static unsigned char libipw_rfc1042_header[] =
 223    { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
 224
 225/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
 226static unsigned char libipw_bridge_tunnel_header[] =
 227    { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
 228/* No encapsulation header if EtherType < 0x600 (=length) */
 229
 230/* Called by libipw_rx_frame_decrypt */
 231static int libipw_is_eapol_frame(struct libipw_device *ieee,
 232				    struct sk_buff *skb)
 233{
 234	struct net_device *dev = ieee->dev;
 235	u16 fc, ethertype;
 236	struct libipw_hdr_3addr *hdr;
 237	u8 *pos;
 238
 239	if (skb->len < 24)
 240		return 0;
 241
 242	hdr = (struct libipw_hdr_3addr *)skb->data;
 243	fc = le16_to_cpu(hdr->frame_ctl);
 244
 245	/* check that the frame is unicast frame to us */
 246	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 247	    IEEE80211_FCTL_TODS &&
 248	    ether_addr_equal(hdr->addr1, dev->dev_addr) &&
 249	    ether_addr_equal(hdr->addr3, dev->dev_addr)) {
 250		/* ToDS frame with own addr BSSID and DA */
 251	} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 252		   IEEE80211_FCTL_FROMDS &&
 253		   ether_addr_equal(hdr->addr1, dev->dev_addr)) {
 254		/* FromDS frame with own addr as DA */
 255	} else
 256		return 0;
 257
 258	if (skb->len < 24 + 8)
 259		return 0;
 260
 261	/* check for port access entity Ethernet type */
 262	pos = skb->data + 24;
 263	ethertype = (pos[6] << 8) | pos[7];
 264	if (ethertype == ETH_P_PAE)
 265		return 1;
 266
 267	return 0;
 268}
 269
 270/* Called only as a tasklet (software IRQ), by libipw_rx */
 271static int
 272libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
 273			   struct lib80211_crypt_data *crypt)
 274{
 275	struct libipw_hdr_3addr *hdr;
 276	int res, hdrlen;
 277
 278	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
 279		return 0;
 280
 281	hdr = (struct libipw_hdr_3addr *)skb->data;
 282	hdrlen = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 283
 284	atomic_inc(&crypt->refcnt);
 285	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
 286	atomic_dec(&crypt->refcnt);
 287	if (res < 0) {
 288		LIBIPW_DEBUG_DROP("decryption failed (SA=%pM) res=%d\n",
 289				     hdr->addr2, res);
 290		if (res == -2)
 291			LIBIPW_DEBUG_DROP("Decryption failed ICV "
 292					     "mismatch (key %d)\n",
 293					     skb->data[hdrlen + 3] >> 6);
 294		ieee->ieee_stats.rx_discards_undecryptable++;
 295		return -1;
 296	}
 297
 298	return res;
 299}
 300
 301/* Called only as a tasklet (software IRQ), by libipw_rx */
 302static int
 303libipw_rx_frame_decrypt_msdu(struct libipw_device *ieee,
 304				struct sk_buff *skb, int keyidx,
 305				struct lib80211_crypt_data *crypt)
 306{
 307	struct libipw_hdr_3addr *hdr;
 308	int res, hdrlen;
 309
 310	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
 311		return 0;
 312
 313	hdr = (struct libipw_hdr_3addr *)skb->data;
 314	hdrlen = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 315
 316	atomic_inc(&crypt->refcnt);
 317	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
 318	atomic_dec(&crypt->refcnt);
 319	if (res < 0) {
 320		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
 321		       " (SA=%pM keyidx=%d)\n", ieee->dev->name, hdr->addr2,
 322		       keyidx);
 323		return -1;
 324	}
 325
 326	return 0;
 327}
 328
 329/* All received frames are sent to this function. @skb contains the frame in
 330 * IEEE 802.11 format, i.e., in the format it was sent over air.
 331 * This function is called only as a tasklet (software IRQ). */
 332int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
 333		 struct libipw_rx_stats *rx_stats)
 334{
 335	struct net_device *dev = ieee->dev;
 336	struct libipw_hdr_4addr *hdr;
 337	size_t hdrlen;
 338	u16 fc, type, stype, sc;
 339	unsigned int frag;
 340	u8 *payload;
 341	u16 ethertype;
 342#ifdef NOT_YET
 343	struct net_device *wds = NULL;
 344	struct sk_buff *skb2 = NULL;
 345	struct net_device *wds = NULL;
 346	int frame_authorized = 0;
 347	int from_assoc_ap = 0;
 348	void *sta = NULL;
 349#endif
 350	u8 dst[ETH_ALEN];
 351	u8 src[ETH_ALEN];
 352	struct lib80211_crypt_data *crypt = NULL;
 353	int keyidx = 0;
 354	int can_be_decrypted = 0;
 355
 356	hdr = (struct libipw_hdr_4addr *)skb->data;
 357	if (skb->len < 10) {
 358		printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
 359		goto rx_dropped;
 360	}
 361
 362	fc = le16_to_cpu(hdr->frame_ctl);
 363	type = WLAN_FC_GET_TYPE(fc);
 364	stype = WLAN_FC_GET_STYPE(fc);
 365	sc = le16_to_cpu(hdr->seq_ctl);
 366	frag = WLAN_GET_SEQ_FRAG(sc);
 367	hdrlen = libipw_get_hdrlen(fc);
 368
 369	if (skb->len < hdrlen) {
 370		printk(KERN_INFO "%s: invalid SKB length %d\n",
 371			dev->name, skb->len);
 372		goto rx_dropped;
 373	}
 374
 375	/* Put this code here so that we avoid duplicating it in all
 376	 * Rx paths. - Jean II */
 377#ifdef CONFIG_WIRELESS_EXT
 378#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
 379	/* If spy monitoring on */
 380	if (ieee->spy_data.spy_number > 0) {
 381		struct iw_quality wstats;
 382
 383		wstats.updated = 0;
 384		if (rx_stats->mask & LIBIPW_STATMASK_RSSI) {
 385			wstats.level = rx_stats->signal;
 386			wstats.updated |= IW_QUAL_LEVEL_UPDATED;
 387		} else
 388			wstats.updated |= IW_QUAL_LEVEL_INVALID;
 389
 390		if (rx_stats->mask & LIBIPW_STATMASK_NOISE) {
 391			wstats.noise = rx_stats->noise;
 392			wstats.updated |= IW_QUAL_NOISE_UPDATED;
 393		} else
 394			wstats.updated |= IW_QUAL_NOISE_INVALID;
 395
 396		if (rx_stats->mask & LIBIPW_STATMASK_SIGNAL) {
 397			wstats.qual = rx_stats->signal;
 398			wstats.updated |= IW_QUAL_QUAL_UPDATED;
 399		} else
 400			wstats.updated |= IW_QUAL_QUAL_INVALID;
 401
 402		/* Update spy records */
 403		wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
 404	}
 405#endif				/* IW_WIRELESS_SPY */
 406#endif				/* CONFIG_WIRELESS_EXT */
 407
 408#ifdef NOT_YET
 409	hostap_update_rx_stats(local->ap, hdr, rx_stats);
 410#endif
 411
 412	if (ieee->iw_mode == IW_MODE_MONITOR) {
 413		dev->stats.rx_packets++;
 414		dev->stats.rx_bytes += skb->len;
 415		libipw_monitor_rx(ieee, skb, rx_stats);
 416		return 1;
 417	}
 418
 419	can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) ||
 420			    is_broadcast_ether_addr(hdr->addr2)) ?
 421	    ieee->host_mc_decrypt : ieee->host_decrypt;
 422
 423	if (can_be_decrypted) {
 424		if (skb->len >= hdrlen + 3) {
 425			/* Top two-bits of byte 3 are the key index */
 426			keyidx = skb->data[hdrlen + 3] >> 6;
 427		}
 428
 429		/* ieee->crypt[] is WEP_KEY (4) in length.  Given that keyidx
 430		 * is only allowed 2-bits of storage, no value of keyidx can
 431		 * be provided via above code that would result in keyidx
 432		 * being out of range */
 433		crypt = ieee->crypt_info.crypt[keyidx];
 434
 435#ifdef NOT_YET
 436		sta = NULL;
 437
 438		/* Use station specific key to override default keys if the
 439		 * receiver address is a unicast address ("individual RA"). If
 440		 * bcrx_sta_key parameter is set, station specific key is used
 441		 * even with broad/multicast targets (this is against IEEE
 442		 * 802.11, but makes it easier to use different keys with
 443		 * stations that do not support WEP key mapping). */
 444
 445		if (is_unicast_ether_addr(hdr->addr1) || local->bcrx_sta_key)
 446			(void)hostap_handle_sta_crypto(local, hdr, &crypt,
 447						       &sta);
 448#endif
 449
 450		/* allow NULL decrypt to indicate an station specific override
 451		 * for default encryption */
 452		if (crypt && (crypt->ops == NULL ||
 453			      crypt->ops->decrypt_mpdu == NULL))
 454			crypt = NULL;
 455
 456		if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
 457			/* This seems to be triggered by some (multicast?)
 458			 * frames from other than current BSS, so just drop the
 459			 * frames silently instead of filling system log with
 460			 * these reports. */
 461			LIBIPW_DEBUG_DROP("Decryption failed (not set)"
 462					     " (SA=%pM)\n", hdr->addr2);
 463			ieee->ieee_stats.rx_discards_undecryptable++;
 464			goto rx_dropped;
 465		}
 466	}
 467#ifdef NOT_YET
 468	if (type != WLAN_FC_TYPE_DATA) {
 469		if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
 470		    fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
 471		    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
 472			printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
 473			       "from %pM\n", dev->name, hdr->addr2);
 474			/* TODO: could inform hostapd about this so that it
 475			 * could send auth failure report */
 476			goto rx_dropped;
 477		}
 478
 479		if (libipw_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
 480			goto rx_dropped;
 481		else
 482			goto rx_exit;
 483	}
 484#endif
 485	/* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
 486	if (sc == ieee->prev_seq_ctl)
 487		goto rx_dropped;
 488	else
 489		ieee->prev_seq_ctl = sc;
 490
 491	/* Data frame - extract src/dst addresses */
 492	if (skb->len < LIBIPW_3ADDR_LEN)
 493		goto rx_dropped;
 494
 495	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 496	case IEEE80211_FCTL_FROMDS:
 497		memcpy(dst, hdr->addr1, ETH_ALEN);
 498		memcpy(src, hdr->addr3, ETH_ALEN);
 499		break;
 500	case IEEE80211_FCTL_TODS:
 501		memcpy(dst, hdr->addr3, ETH_ALEN);
 502		memcpy(src, hdr->addr2, ETH_ALEN);
 503		break;
 504	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
 505		if (skb->len < LIBIPW_4ADDR_LEN)
 506			goto rx_dropped;
 507		memcpy(dst, hdr->addr3, ETH_ALEN);
 508		memcpy(src, hdr->addr4, ETH_ALEN);
 509		break;
 510	default:
 511		memcpy(dst, hdr->addr1, ETH_ALEN);
 512		memcpy(src, hdr->addr2, ETH_ALEN);
 513		break;
 514	}
 515
 516#ifdef NOT_YET
 517	if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
 518		goto rx_dropped;
 519	if (wds) {
 520		skb->dev = dev = wds;
 521		stats = hostap_get_stats(dev);
 522	}
 523
 524	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
 525	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 526	    IEEE80211_FCTL_FROMDS && ieee->stadev &&
 527	    ether_addr_equal(hdr->addr2, ieee->assoc_ap_addr)) {
 528		/* Frame from BSSID of the AP for which we are a client */
 529		skb->dev = dev = ieee->stadev;
 530		stats = hostap_get_stats(dev);
 531		from_assoc_ap = 1;
 532	}
 533#endif
 534
 535#ifdef NOT_YET
 536	if ((ieee->iw_mode == IW_MODE_MASTER ||
 537	     ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
 538		switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
 539					     wds != NULL)) {
 540		case AP_RX_CONTINUE_NOT_AUTHORIZED:
 541			frame_authorized = 0;
 542			break;
 543		case AP_RX_CONTINUE:
 544			frame_authorized = 1;
 545			break;
 546		case AP_RX_DROP:
 547			goto rx_dropped;
 548		case AP_RX_EXIT:
 549			goto rx_exit;
 550		}
 551	}
 552#endif
 553
 554	/* Nullfunc frames may have PS-bit set, so they must be passed to
 555	 * hostap_handle_sta_rx() before being dropped here. */
 556
 557	stype &= ~IEEE80211_STYPE_QOS_DATA;
 558
 559	if (stype != IEEE80211_STYPE_DATA &&
 560	    stype != IEEE80211_STYPE_DATA_CFACK &&
 561	    stype != IEEE80211_STYPE_DATA_CFPOLL &&
 562	    stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
 563		if (stype != IEEE80211_STYPE_NULLFUNC)
 564			LIBIPW_DEBUG_DROP("RX: dropped data frame "
 565					     "with no data (type=0x%02x, "
 566					     "subtype=0x%02x, len=%d)\n",
 567					     type, stype, skb->len);
 568		goto rx_dropped;
 569	}
 570
 571	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
 572
 573	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 574	    (keyidx = libipw_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 575		goto rx_dropped;
 576
 577	hdr = (struct libipw_hdr_4addr *)skb->data;
 578
 579	/* skb: hdr + (possibly fragmented) plaintext payload */
 580	// PR: FIXME: hostap has additional conditions in the "if" below:
 581	// ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
 582	if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
 583		int flen;
 584		struct sk_buff *frag_skb = libipw_frag_cache_get(ieee, hdr);
 585		LIBIPW_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
 586
 587		if (!frag_skb) {
 588			LIBIPW_DEBUG(LIBIPW_DL_RX | LIBIPW_DL_FRAG,
 589					"Rx cannot get skb from fragment "
 590					"cache (morefrag=%d seq=%u frag=%u)\n",
 591					(fc & IEEE80211_FCTL_MOREFRAGS) != 0,
 592					WLAN_GET_SEQ_SEQ(sc), frag);
 593			goto rx_dropped;
 594		}
 595
 596		flen = skb->len;
 597		if (frag != 0)
 598			flen -= hdrlen;
 599
 600		if (frag_skb->tail + flen > frag_skb->end) {
 601			printk(KERN_WARNING "%s: host decrypted and "
 602			       "reassembled frame did not fit skb\n",
 603			       dev->name);
 604			libipw_frag_cache_invalidate(ieee, hdr);
 605			goto rx_dropped;
 606		}
 607
 608		if (frag == 0) {
 609			/* copy first fragment (including full headers) into
 610			 * beginning of the fragment cache skb */
 611			skb_copy_from_linear_data(skb, skb_put(frag_skb, flen), flen);
 612		} else {
 613			/* append frame payload to the end of the fragment
 614			 * cache skb */
 615			skb_copy_from_linear_data_offset(skb, hdrlen,
 616				      skb_put(frag_skb, flen), flen);
 617		}
 618		dev_kfree_skb_any(skb);
 619		skb = NULL;
 620
 621		if (fc & IEEE80211_FCTL_MOREFRAGS) {
 622			/* more fragments expected - leave the skb in fragment
 623			 * cache for now; it will be delivered to upper layers
 624			 * after all fragments have been received */
 625			goto rx_exit;
 626		}
 627
 628		/* this was the last fragment and the frame will be
 629		 * delivered, so remove skb from fragment cache */
 630		skb = frag_skb;
 631		hdr = (struct libipw_hdr_4addr *)skb->data;
 632		libipw_frag_cache_invalidate(ieee, hdr);
 633	}
 634
 635	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
 636	 * encrypted/authenticated */
 637	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 638	    libipw_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
 639		goto rx_dropped;
 640
 641	hdr = (struct libipw_hdr_4addr *)skb->data;
 642	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
 643		if (		/*ieee->ieee802_1x && */
 644			   libipw_is_eapol_frame(ieee, skb)) {
 645			/* pass unencrypted EAPOL frames even if encryption is
 646			 * configured */
 647		} else {
 648			LIBIPW_DEBUG_DROP("encryption configured, but RX "
 649					     "frame not encrypted (SA=%pM)\n",
 650					     hdr->addr2);
 651			goto rx_dropped;
 652		}
 653	}
 654
 655	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
 656	    !libipw_is_eapol_frame(ieee, skb)) {
 657		LIBIPW_DEBUG_DROP("dropped unencrypted RX data "
 658				     "frame from %pM (drop_unencrypted=1)\n",
 659				     hdr->addr2);
 660		goto rx_dropped;
 661	}
 662
 663	/* If the frame was decrypted in hardware, we may need to strip off
 664	 * any security data (IV, ICV, etc) that was left behind */
 665	if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
 666	    ieee->host_strip_iv_icv) {
 667		int trimlen = 0;
 668
 669		/* Top two-bits of byte 3 are the key index */
 670		if (skb->len >= hdrlen + 3)
 671			keyidx = skb->data[hdrlen + 3] >> 6;
 672
 673		/* To strip off any security data which appears before the
 674		 * payload, we simply increase hdrlen (as the header gets
 675		 * chopped off immediately below). For the security data which
 676		 * appears after the payload, we use skb_trim. */
 677
 678		switch (ieee->sec.encode_alg[keyidx]) {
 679		case SEC_ALG_WEP:
 680			/* 4 byte IV */
 681			hdrlen += 4;
 682			/* 4 byte ICV */
 683			trimlen = 4;
 684			break;
 685		case SEC_ALG_TKIP:
 686			/* 4 byte IV, 4 byte ExtIV */
 687			hdrlen += 8;
 688			/* 8 byte MIC, 4 byte ICV */
 689			trimlen = 12;
 690			break;
 691		case SEC_ALG_CCMP:
 692			/* 8 byte CCMP header */
 693			hdrlen += 8;
 694			/* 8 byte MIC */
 695			trimlen = 8;
 696			break;
 697		}
 698
 699		if (skb->len < trimlen)
 700			goto rx_dropped;
 701
 702		__skb_trim(skb, skb->len - trimlen);
 703
 704		if (skb->len < hdrlen)
 705			goto rx_dropped;
 706	}
 707
 708	/* skb: hdr + (possible reassembled) full plaintext payload */
 709
 710	payload = skb->data + hdrlen;
 711	ethertype = (payload[6] << 8) | payload[7];
 712
 713#ifdef NOT_YET
 714	/* If IEEE 802.1X is used, check whether the port is authorized to send
 715	 * the received frame. */
 716	if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
 717		if (ethertype == ETH_P_PAE) {
 718			printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
 719			       dev->name);
 720			if (ieee->hostapd && ieee->apdev) {
 721				/* Send IEEE 802.1X frames to the user
 722				 * space daemon for processing */
 723				prism2_rx_80211(ieee->apdev, skb, rx_stats,
 724						PRISM2_RX_MGMT);
 725				ieee->apdevstats.rx_packets++;
 726				ieee->apdevstats.rx_bytes += skb->len;
 727				goto rx_exit;
 728			}
 729		} else if (!frame_authorized) {
 730			printk(KERN_DEBUG "%s: dropped frame from "
 731			       "unauthorized port (IEEE 802.1X): "
 732			       "ethertype=0x%04x\n", dev->name, ethertype);
 733			goto rx_dropped;
 734		}
 735	}
 736#endif
 737
 738	/* convert hdr + possible LLC headers into Ethernet header */
 739	if (skb->len - hdrlen >= 8 &&
 740	    ((memcmp(payload, libipw_rfc1042_header, SNAP_SIZE) == 0 &&
 741	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
 742	     memcmp(payload, libipw_bridge_tunnel_header, SNAP_SIZE) == 0)) {
 743		/* remove RFC1042 or Bridge-Tunnel encapsulation and
 744		 * replace EtherType */
 745		skb_pull(skb, hdrlen + SNAP_SIZE);
 746		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
 747		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
 748	} else {
 749		__be16 len;
 750		/* Leave Ethernet header part of hdr and full payload */
 751		skb_pull(skb, hdrlen);
 752		len = htons(skb->len);
 753		memcpy(skb_push(skb, 2), &len, 2);
 754		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
 755		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
 756	}
 757
 758#ifdef NOT_YET
 759	if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 760		    IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
 761		/* Non-standard frame: get addr4 from its bogus location after
 762		 * the payload */
 763		skb_copy_to_linear_data_offset(skb, ETH_ALEN,
 764					       skb->data + skb->len - ETH_ALEN,
 765					       ETH_ALEN);
 766		skb_trim(skb, skb->len - ETH_ALEN);
 767	}
 768#endif
 769
 770	dev->stats.rx_packets++;
 771	dev->stats.rx_bytes += skb->len;
 772
 773#ifdef NOT_YET
 774	if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
 775		if (is_multicast_ether_addr(dst)) {
 776			/* copy multicast frame both to the higher layers and
 777			 * to the wireless media */
 778			ieee->ap->bridged_multicast++;
 779			skb2 = skb_clone(skb, GFP_ATOMIC);
 780			if (skb2 == NULL)
 781				printk(KERN_DEBUG "%s: skb_clone failed for "
 782				       "multicast frame\n", dev->name);
 783		} else if (hostap_is_sta_assoc(ieee->ap, dst)) {
 784			/* send frame directly to the associated STA using
 785			 * wireless media and not passing to higher layers */
 786			ieee->ap->bridged_unicast++;
 787			skb2 = skb;
 788			skb = NULL;
 789		}
 790	}
 791
 792	if (skb2 != NULL) {
 793		/* send to wireless media */
 794		skb2->dev = dev;
 795		skb2->protocol = htons(ETH_P_802_3);
 796		skb_reset_mac_header(skb2);
 797		skb_reset_network_header(skb2);
 798		/* skb2->network_header += ETH_HLEN; */
 799		dev_queue_xmit(skb2);
 800	}
 801#endif
 802
 803	if (skb) {
 804		skb->protocol = eth_type_trans(skb, dev);
 805		memset(skb->cb, 0, sizeof(skb->cb));
 806		skb->ip_summed = CHECKSUM_NONE;	/* 802.11 crc not sufficient */
 807		if (netif_rx(skb) == NET_RX_DROP) {
 808			/* netif_rx always succeeds, but it might drop
 809			 * the packet.  If it drops the packet, we log that
 810			 * in our stats. */
 811			LIBIPW_DEBUG_DROP
 812			    ("RX: netif_rx dropped the packet\n");
 813			dev->stats.rx_dropped++;
 814		}
 815	}
 816
 817      rx_exit:
 818#ifdef NOT_YET
 819	if (sta)
 820		hostap_handle_sta_release(sta);
 821#endif
 822	return 1;
 823
 824      rx_dropped:
 825	dev->stats.rx_dropped++;
 826
 827	/* Returning 0 indicates to caller that we have not handled the SKB--
 828	 * so it is still allocated and can be used again by underlying
 829	 * hardware as a DMA target */
 830	return 0;
 831}
 832
 833/* Filter out unrelated packets, call libipw_rx[_mgt]
 834 * This function takes over the skb, it should not be used again after calling
 835 * this function. */
 836void libipw_rx_any(struct libipw_device *ieee,
 837		     struct sk_buff *skb, struct libipw_rx_stats *stats)
 838{
 839	struct libipw_hdr_4addr *hdr;
 840	int is_packet_for_us;
 841	u16 fc;
 842
 843	if (ieee->iw_mode == IW_MODE_MONITOR) {
 844		if (!libipw_rx(ieee, skb, stats))
 845			dev_kfree_skb_irq(skb);
 846		return;
 847	}
 848
 849	if (skb->len < sizeof(struct ieee80211_hdr))
 850		goto drop_free;
 851
 852	hdr = (struct libipw_hdr_4addr *)skb->data;
 853	fc = le16_to_cpu(hdr->frame_ctl);
 854
 855	if ((fc & IEEE80211_FCTL_VERS) != 0)
 856		goto drop_free;
 857
 858	switch (fc & IEEE80211_FCTL_FTYPE) {
 859	case IEEE80211_FTYPE_MGMT:
 860		if (skb->len < sizeof(struct libipw_hdr_3addr))
 861			goto drop_free;
 862		libipw_rx_mgt(ieee, hdr, stats);
 863		dev_kfree_skb_irq(skb);
 864		return;
 865	case IEEE80211_FTYPE_DATA:
 866		break;
 867	case IEEE80211_FTYPE_CTL:
 868		return;
 869	default:
 870		return;
 871	}
 872
 873	is_packet_for_us = 0;
 874	switch (ieee->iw_mode) {
 875	case IW_MODE_ADHOC:
 876		/* our BSS and not from/to DS */
 877		if (ether_addr_equal(hdr->addr3, ieee->bssid))
 878		if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) {
 879			/* promisc: get all */
 880			if (ieee->dev->flags & IFF_PROMISC)
 881				is_packet_for_us = 1;
 882			/* to us */
 883			else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr))
 884				is_packet_for_us = 1;
 885			/* mcast */
 886			else if (is_multicast_ether_addr(hdr->addr1))
 887				is_packet_for_us = 1;
 888		}
 889		break;
 890	case IW_MODE_INFRA:
 891		/* our BSS (== from our AP) and from DS */
 892		if (ether_addr_equal(hdr->addr2, ieee->bssid))
 893		if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) {
 894			/* promisc: get all */
 895			if (ieee->dev->flags & IFF_PROMISC)
 896				is_packet_for_us = 1;
 897			/* to us */
 898			else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr))
 899				is_packet_for_us = 1;
 900			/* mcast */
 901			else if (is_multicast_ether_addr(hdr->addr1)) {
 902				/* not our own packet bcasted from AP */
 903				if (!ether_addr_equal(hdr->addr3, ieee->dev->dev_addr))
 904					is_packet_for_us = 1;
 905			}
 906		}
 907		break;
 908	default:
 909		/* ? */
 910		break;
 911	}
 912
 913	if (is_packet_for_us)
 914		if (!libipw_rx(ieee, skb, stats))
 915			dev_kfree_skb_irq(skb);
 916	return;
 917
 918drop_free:
 919	dev_kfree_skb_irq(skb);
 920	ieee->dev->stats.rx_dropped++;
 921}
 922
 923#define MGMT_FRAME_FIXED_PART_LENGTH		0x24
 924
 925static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
 926
 927/*
 928* Make the structure we read from the beacon packet to have
 929* the right values
 930*/
 931static int libipw_verify_qos_info(struct libipw_qos_information_element
 932				     *info_element, int sub_type)
 933{
 934
 
 935	if (info_element->qui_subtype != sub_type)
 936		return -1;
 937	if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
 938		return -1;
 939	if (info_element->qui_type != QOS_OUI_TYPE)
 940		return -1;
 941	if (info_element->version != QOS_VERSION_1)
 942		return -1;
 943
 944	return 0;
 945}
 946
 947/*
 948 * Parse a QoS parameter element
 949 */
 950static int libipw_read_qos_param_element(struct libipw_qos_parameter_info
 951					    *element_param, struct libipw_info_element
 952					    *info_element)
 953{
 954	int ret = 0;
 955	u16 size = sizeof(struct libipw_qos_parameter_info) - 2;
 956
 957	if ((info_element == NULL) || (element_param == NULL))
 958		return -1;
 959
 960	if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
 961		memcpy(element_param->info_element.qui, info_element->data,
 962		       info_element->len);
 963		element_param->info_element.elementID = info_element->id;
 964		element_param->info_element.length = info_element->len;
 965	} else
 966		ret = -1;
 967	if (ret == 0)
 968		ret = libipw_verify_qos_info(&element_param->info_element,
 969						QOS_OUI_PARAM_SUB_TYPE);
 970	return ret;
 971}
 972
 973/*
 974 * Parse a QoS information element
 975 */
 976static int libipw_read_qos_info_element(struct
 977					   libipw_qos_information_element
 978					   *element_info, struct libipw_info_element
 979					   *info_element)
 980{
 981	int ret = 0;
 982	u16 size = sizeof(struct libipw_qos_information_element) - 2;
 983
 984	if (element_info == NULL)
 985		return -1;
 986	if (info_element == NULL)
 987		return -1;
 988
 989	if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
 990		memcpy(element_info->qui, info_element->data,
 991		       info_element->len);
 992		element_info->elementID = info_element->id;
 993		element_info->length = info_element->len;
 994	} else
 995		ret = -1;
 996
 997	if (ret == 0)
 998		ret = libipw_verify_qos_info(element_info,
 999						QOS_OUI_INFO_SUB_TYPE);
1000	return ret;
1001}
1002
1003/*
1004 * Write QoS parameters from the ac parameters.
1005 */
1006static int libipw_qos_convert_ac_to_parameters(struct
1007						  libipw_qos_parameter_info
1008						  *param_elm, struct
1009						  libipw_qos_parameters
1010						  *qos_param)
1011{
1012	int rc = 0;
1013	int i;
1014	struct libipw_qos_ac_parameter *ac_params;
1015	u32 txop;
1016	u8 cw_min;
1017	u8 cw_max;
1018
1019	for (i = 0; i < QOS_QUEUE_NUM; i++) {
1020		ac_params = &(param_elm->ac_params_record[i]);
1021
1022		qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
1023		qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
1024
1025		cw_min = ac_params->ecw_min_max & 0x0F;
1026		qos_param->cw_min[i] = cpu_to_le16((1 << cw_min) - 1);
1027
1028		cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
1029		qos_param->cw_max[i] = cpu_to_le16((1 << cw_max) - 1);
1030
1031		qos_param->flag[i] =
1032		    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
1033
1034		txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
1035		qos_param->tx_op_limit[i] = cpu_to_le16(txop);
1036	}
1037	return rc;
1038}
1039
1040/*
1041 * we have a generic data element which it may contain QoS information or
1042 * parameters element. check the information element length to decide
1043 * which type to read
1044 */
1045static int libipw_parse_qos_info_param_IE(struct libipw_info_element
1046					     *info_element,
1047					     struct libipw_network *network)
1048{
1049	int rc = 0;
1050	struct libipw_qos_parameters *qos_param = NULL;
1051	struct libipw_qos_information_element qos_info_element;
1052
1053	rc = libipw_read_qos_info_element(&qos_info_element, info_element);
1054
1055	if (rc == 0) {
1056		network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
1057		network->flags |= NETWORK_HAS_QOS_INFORMATION;
1058	} else {
1059		struct libipw_qos_parameter_info param_element;
1060
1061		rc = libipw_read_qos_param_element(&param_element,
1062						      info_element);
1063		if (rc == 0) {
1064			qos_param = &(network->qos_data.parameters);
1065			libipw_qos_convert_ac_to_parameters(&param_element,
1066							       qos_param);
1067			network->flags |= NETWORK_HAS_QOS_PARAMETERS;
1068			network->qos_data.param_count =
1069			    param_element.info_element.ac_info & 0x0F;
1070		}
1071	}
1072
1073	if (rc == 0) {
1074		LIBIPW_DEBUG_QOS("QoS is supported\n");
1075		network->qos_data.supported = 1;
1076	}
1077	return rc;
1078}
1079
1080#ifdef CONFIG_LIBIPW_DEBUG
1081#define MFIE_STRING(x) case WLAN_EID_ ##x: return #x
1082
1083static const char *get_info_element_string(u16 id)
1084{
1085	switch (id) {
1086		MFIE_STRING(SSID);
1087		MFIE_STRING(SUPP_RATES);
1088		MFIE_STRING(FH_PARAMS);
1089		MFIE_STRING(DS_PARAMS);
1090		MFIE_STRING(CF_PARAMS);
1091		MFIE_STRING(TIM);
1092		MFIE_STRING(IBSS_PARAMS);
1093		MFIE_STRING(COUNTRY);
1094		MFIE_STRING(REQUEST);
1095		MFIE_STRING(CHALLENGE);
1096		MFIE_STRING(PWR_CONSTRAINT);
1097		MFIE_STRING(PWR_CAPABILITY);
1098		MFIE_STRING(TPC_REQUEST);
1099		MFIE_STRING(TPC_REPORT);
1100		MFIE_STRING(SUPPORTED_CHANNELS);
1101		MFIE_STRING(CHANNEL_SWITCH);
1102		MFIE_STRING(MEASURE_REQUEST);
1103		MFIE_STRING(MEASURE_REPORT);
1104		MFIE_STRING(QUIET);
1105		MFIE_STRING(IBSS_DFS);
1106		MFIE_STRING(ERP_INFO);
1107		MFIE_STRING(RSN);
1108		MFIE_STRING(EXT_SUPP_RATES);
1109		MFIE_STRING(VENDOR_SPECIFIC);
1110		MFIE_STRING(QOS_PARAMETER);
1111	default:
1112		return "UNKNOWN";
1113	}
1114}
1115#endif
1116
1117static int libipw_parse_info_param(struct libipw_info_element
1118				      *info_element, u16 length,
1119				      struct libipw_network *network)
1120{
1121	u8 i;
1122#ifdef CONFIG_LIBIPW_DEBUG
1123	char rates_str[64];
1124	char *p;
1125#endif
1126
1127	while (length >= sizeof(*info_element)) {
1128		if (sizeof(*info_element) + info_element->len > length) {
1129			LIBIPW_DEBUG_MGMT("Info elem: parse failed: "
1130					     "info_element->len + 2 > left : "
1131					     "info_element->len+2=%zd left=%d, id=%d.\n",
1132					     info_element->len +
1133					     sizeof(*info_element),
1134					     length, info_element->id);
1135			/* We stop processing but don't return an error here
1136			 * because some misbehaviour APs break this rule. ie.
1137			 * Orinoco AP1000. */
1138			break;
1139		}
1140
1141		switch (info_element->id) {
1142		case WLAN_EID_SSID:
1143			network->ssid_len = min(info_element->len,
1144						(u8) IW_ESSID_MAX_SIZE);
1145			memcpy(network->ssid, info_element->data,
1146			       network->ssid_len);
1147			if (network->ssid_len < IW_ESSID_MAX_SIZE)
1148				memset(network->ssid + network->ssid_len, 0,
1149				       IW_ESSID_MAX_SIZE - network->ssid_len);
1150
1151			LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%*pE' len=%d.\n",
1152					  network->ssid_len, network->ssid,
1153					  network->ssid_len);
1154			break;
1155
1156		case WLAN_EID_SUPP_RATES:
1157#ifdef CONFIG_LIBIPW_DEBUG
1158			p = rates_str;
1159#endif
1160			network->rates_len = min(info_element->len,
1161						 MAX_RATES_LENGTH);
1162			for (i = 0; i < network->rates_len; i++) {
1163				network->rates[i] = info_element->data[i];
1164#ifdef CONFIG_LIBIPW_DEBUG
1165				p += snprintf(p, sizeof(rates_str) -
1166					      (p - rates_str), "%02X ",
1167					      network->rates[i]);
1168#endif
1169				if (libipw_is_ofdm_rate
1170				    (info_element->data[i])) {
1171					network->flags |= NETWORK_HAS_OFDM;
1172					if (info_element->data[i] &
1173					    LIBIPW_BASIC_RATE_MASK)
1174						network->flags &=
1175						    ~NETWORK_HAS_CCK;
1176				}
1177			}
1178
1179			LIBIPW_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
1180					     rates_str, network->rates_len);
1181			break;
1182
1183		case WLAN_EID_EXT_SUPP_RATES:
1184#ifdef CONFIG_LIBIPW_DEBUG
1185			p = rates_str;
1186#endif
1187			network->rates_ex_len = min(info_element->len,
1188						    MAX_RATES_EX_LENGTH);
1189			for (i = 0; i < network->rates_ex_len; i++) {
1190				network->rates_ex[i] = info_element->data[i];
1191#ifdef CONFIG_LIBIPW_DEBUG
1192				p += snprintf(p, sizeof(rates_str) -
1193					      (p - rates_str), "%02X ",
1194					      network->rates_ex[i]);
1195#endif
1196				if (libipw_is_ofdm_rate
1197				    (info_element->data[i])) {
1198					network->flags |= NETWORK_HAS_OFDM;
1199					if (info_element->data[i] &
1200					    LIBIPW_BASIC_RATE_MASK)
1201						network->flags &=
1202						    ~NETWORK_HAS_CCK;
1203				}
1204			}
1205
1206			LIBIPW_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
1207					     rates_str, network->rates_ex_len);
1208			break;
1209
1210		case WLAN_EID_DS_PARAMS:
1211			LIBIPW_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
1212					     info_element->data[0]);
1213			network->channel = info_element->data[0];
1214			break;
1215
1216		case WLAN_EID_FH_PARAMS:
1217			LIBIPW_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
1218			break;
1219
1220		case WLAN_EID_CF_PARAMS:
1221			LIBIPW_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
1222			break;
1223
1224		case WLAN_EID_TIM:
1225			network->tim.tim_count = info_element->data[0];
1226			network->tim.tim_period = info_element->data[1];
1227			LIBIPW_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
1228			break;
1229
1230		case WLAN_EID_ERP_INFO:
1231			network->erp_value = info_element->data[0];
1232			network->flags |= NETWORK_HAS_ERP_VALUE;
1233			LIBIPW_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1234					     network->erp_value);
1235			break;
1236
1237		case WLAN_EID_IBSS_PARAMS:
1238			network->atim_window = info_element->data[0];
1239			LIBIPW_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
1240					     network->atim_window);
1241			break;
1242
1243		case WLAN_EID_CHALLENGE:
1244			LIBIPW_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
1245			break;
1246
1247		case WLAN_EID_VENDOR_SPECIFIC:
1248			LIBIPW_DEBUG_MGMT("WLAN_EID_VENDOR_SPECIFIC: %d bytes\n",
1249					     info_element->len);
1250			if (!libipw_parse_qos_info_param_IE(info_element,
1251							       network))
1252				break;
1253
1254			if (info_element->len >= 4 &&
1255			    info_element->data[0] == 0x00 &&
1256			    info_element->data[1] == 0x50 &&
1257			    info_element->data[2] == 0xf2 &&
1258			    info_element->data[3] == 0x01) {
1259				network->wpa_ie_len = min(info_element->len + 2,
1260							  MAX_WPA_IE_LEN);
1261				memcpy(network->wpa_ie, info_element,
1262				       network->wpa_ie_len);
1263			}
1264			break;
1265
1266		case WLAN_EID_RSN:
1267			LIBIPW_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
1268					     info_element->len);
1269			network->rsn_ie_len = min(info_element->len + 2,
1270						  MAX_WPA_IE_LEN);
1271			memcpy(network->rsn_ie, info_element,
1272			       network->rsn_ie_len);
1273			break;
1274
1275		case WLAN_EID_QOS_PARAMETER:
1276			printk(KERN_ERR
1277			       "QoS Error need to parse QOS_PARAMETER IE\n");
1278			break;
1279			/* 802.11h */
1280		case WLAN_EID_PWR_CONSTRAINT:
1281			network->power_constraint = info_element->data[0];
1282			network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
1283			break;
1284
1285		case WLAN_EID_CHANNEL_SWITCH:
1286			network->power_constraint = info_element->data[0];
1287			network->flags |= NETWORK_HAS_CSA;
1288			break;
1289
1290		case WLAN_EID_QUIET:
1291			network->quiet.count = info_element->data[0];
1292			network->quiet.period = info_element->data[1];
1293			network->quiet.duration = info_element->data[2];
1294			network->quiet.offset = info_element->data[3];
1295			network->flags |= NETWORK_HAS_QUIET;
1296			break;
1297
1298		case WLAN_EID_IBSS_DFS:
1299			network->flags |= NETWORK_HAS_IBSS_DFS;
1300			break;
1301
1302		case WLAN_EID_TPC_REPORT:
1303			network->tpc_report.transmit_power =
1304			    info_element->data[0];
1305			network->tpc_report.link_margin = info_element->data[1];
1306			network->flags |= NETWORK_HAS_TPC_REPORT;
1307			break;
1308
1309		default:
1310			LIBIPW_DEBUG_MGMT
1311			    ("Unsupported info element: %s (%d)\n",
1312			     get_info_element_string(info_element->id),
1313			     info_element->id);
1314			break;
1315		}
1316
1317		length -= sizeof(*info_element) + info_element->len;
1318		info_element =
1319		    (struct libipw_info_element *)&info_element->
1320		    data[info_element->len];
1321	}
1322
1323	return 0;
1324}
1325
1326static int libipw_handle_assoc_resp(struct libipw_device *ieee, struct libipw_assoc_response
1327				       *frame, struct libipw_rx_stats *stats)
1328{
1329	struct libipw_network network_resp = { };
1330	struct libipw_network *network = &network_resp;
1331	struct net_device *dev = ieee->dev;
1332
1333	network->flags = 0;
1334	network->qos_data.active = 0;
1335	network->qos_data.supported = 0;
1336	network->qos_data.param_count = 0;
1337	network->qos_data.old_param_count = 0;
1338
1339	//network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
1340	network->atim_window = le16_to_cpu(frame->aid);
1341	network->listen_interval = le16_to_cpu(frame->status);
1342	memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
1343	network->capability = le16_to_cpu(frame->capability);
1344	network->last_scanned = jiffies;
1345	network->rates_len = network->rates_ex_len = 0;
1346	network->last_associate = 0;
1347	network->ssid_len = 0;
1348	network->erp_value =
1349	    (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
1350
1351	if (stats->freq == LIBIPW_52GHZ_BAND) {
1352		/* for A band (No DS info) */
1353		network->channel = stats->received_channel;
1354	} else
1355		network->flags |= NETWORK_HAS_CCK;
1356
1357	network->wpa_ie_len = 0;
1358	network->rsn_ie_len = 0;
1359
1360	if (libipw_parse_info_param
1361	    (frame->info_element, stats->len - sizeof(*frame), network))
1362		return 1;
1363
1364	network->mode = 0;
1365	if (stats->freq == LIBIPW_52GHZ_BAND)
1366		network->mode = IEEE_A;
1367	else {
1368		if (network->flags & NETWORK_HAS_OFDM)
1369			network->mode |= IEEE_G;
1370		if (network->flags & NETWORK_HAS_CCK)
1371			network->mode |= IEEE_B;
1372	}
1373
1374	memcpy(&network->stats, stats, sizeof(network->stats));
1375
1376	if (ieee->handle_assoc_response != NULL)
1377		ieee->handle_assoc_response(dev, frame, network);
1378
1379	return 0;
1380}
1381
1382/***************************************************/
1383
1384static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_response
1385					 *beacon,
1386					 struct libipw_network *network,
1387					 struct libipw_rx_stats *stats)
1388{
1389	network->qos_data.active = 0;
1390	network->qos_data.supported = 0;
1391	network->qos_data.param_count = 0;
1392	network->qos_data.old_param_count = 0;
1393
1394	/* Pull out fixed field data */
1395	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1396	network->capability = le16_to_cpu(beacon->capability);
1397	network->last_scanned = jiffies;
1398	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1399	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1400	network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1401	/* Where to pull this? beacon->listen_interval; */
1402	network->listen_interval = 0x0A;
1403	network->rates_len = network->rates_ex_len = 0;
1404	network->last_associate = 0;
1405	network->ssid_len = 0;
1406	network->flags = 0;
1407	network->atim_window = 0;
1408	network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1409	    0x3 : 0x0;
1410
1411	if (stats->freq == LIBIPW_52GHZ_BAND) {
1412		/* for A band (No DS info) */
1413		network->channel = stats->received_channel;
1414	} else
1415		network->flags |= NETWORK_HAS_CCK;
1416
1417	network->wpa_ie_len = 0;
1418	network->rsn_ie_len = 0;
1419
1420	if (libipw_parse_info_param
1421	    (beacon->info_element, stats->len - sizeof(*beacon), network))
1422		return 1;
1423
1424	network->mode = 0;
1425	if (stats->freq == LIBIPW_52GHZ_BAND)
1426		network->mode = IEEE_A;
1427	else {
1428		if (network->flags & NETWORK_HAS_OFDM)
1429			network->mode |= IEEE_G;
1430		if (network->flags & NETWORK_HAS_CCK)
1431			network->mode |= IEEE_B;
1432	}
1433
1434	if (network->mode == 0) {
1435		LIBIPW_DEBUG_SCAN("Filtered out '%*pE (%pM)' network.\n",
1436				  network->ssid_len, network->ssid,
1437				  network->bssid);
1438		return 1;
1439	}
1440
1441	memcpy(&network->stats, stats, sizeof(network->stats));
1442
1443	return 0;
1444}
1445
1446static inline int is_same_network(struct libipw_network *src,
1447				  struct libipw_network *dst)
1448{
1449	/* A network is only a duplicate if the channel, BSSID, and ESSID
1450	 * all match.  We treat all <hidden> with the same BSSID and channel
1451	 * as one network */
1452	return ((src->ssid_len == dst->ssid_len) &&
1453		(src->channel == dst->channel) &&
1454		ether_addr_equal_64bits(src->bssid, dst->bssid) &&
1455		!memcmp(src->ssid, dst->ssid, src->ssid_len));
1456}
1457
1458static void update_network(struct libipw_network *dst,
1459				  struct libipw_network *src)
1460{
1461	int qos_active;
1462	u8 old_param;
1463
1464	/* We only update the statistics if they were created by receiving
1465	 * the network information on the actual channel the network is on.
1466	 *
1467	 * This keeps beacons received on neighbor channels from bringing
1468	 * down the signal level of an AP. */
1469	if (dst->channel == src->stats.received_channel)
1470		memcpy(&dst->stats, &src->stats,
1471		       sizeof(struct libipw_rx_stats));
1472	else
1473		LIBIPW_DEBUG_SCAN("Network %pM info received "
1474			"off channel (%d vs. %d)\n", src->bssid,
1475			dst->channel, src->stats.received_channel);
1476
1477	dst->capability = src->capability;
1478	memcpy(dst->rates, src->rates, src->rates_len);
1479	dst->rates_len = src->rates_len;
1480	memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1481	dst->rates_ex_len = src->rates_ex_len;
1482
1483	dst->mode = src->mode;
1484	dst->flags = src->flags;
1485	dst->time_stamp[0] = src->time_stamp[0];
1486	dst->time_stamp[1] = src->time_stamp[1];
1487
1488	dst->beacon_interval = src->beacon_interval;
1489	dst->listen_interval = src->listen_interval;
1490	dst->atim_window = src->atim_window;
1491	dst->erp_value = src->erp_value;
1492	dst->tim = src->tim;
1493
1494	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1495	dst->wpa_ie_len = src->wpa_ie_len;
1496	memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1497	dst->rsn_ie_len = src->rsn_ie_len;
1498
1499	dst->last_scanned = jiffies;
1500	qos_active = src->qos_data.active;
1501	old_param = dst->qos_data.old_param_count;
1502	if (dst->flags & NETWORK_HAS_QOS_MASK)
1503		memcpy(&dst->qos_data, &src->qos_data,
1504		       sizeof(struct libipw_qos_data));
1505	else {
1506		dst->qos_data.supported = src->qos_data.supported;
1507		dst->qos_data.param_count = src->qos_data.param_count;
1508	}
1509
1510	if (dst->qos_data.supported == 1) {
1511		if (dst->ssid_len)
1512			LIBIPW_DEBUG_QOS
1513			    ("QoS the network %s is QoS supported\n",
1514			     dst->ssid);
1515		else
1516			LIBIPW_DEBUG_QOS
1517			    ("QoS the network is QoS supported\n");
1518	}
1519	dst->qos_data.active = qos_active;
1520	dst->qos_data.old_param_count = old_param;
1521
1522	/* dst->last_associate is not overwritten */
1523}
1524
1525static inline int is_beacon(__le16 fc)
1526{
1527	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
1528}
1529
1530static void libipw_process_probe_response(struct libipw_device
1531						    *ieee, struct
1532						    libipw_probe_response
1533						    *beacon, struct libipw_rx_stats
1534						    *stats)
1535{
1536	struct net_device *dev = ieee->dev;
1537	struct libipw_network network = { };
1538	struct libipw_network *target;
1539	struct libipw_network *oldest = NULL;
1540#ifdef CONFIG_LIBIPW_DEBUG
1541	struct libipw_info_element *info_element = beacon->info_element;
1542#endif
1543	unsigned long flags;
1544
1545	LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1546		     info_element->len, info_element->data,
1547		     beacon->header.addr3,
1548		     (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
1549		     (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
1550		     (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
1551		     (beacon->capability & cpu_to_le16(1 << 0xc)) ? '1' : '0',
1552		     (beacon->capability & cpu_to_le16(1 << 0xb)) ? '1' : '0',
1553		     (beacon->capability & cpu_to_le16(1 << 0xa)) ? '1' : '0',
1554		     (beacon->capability & cpu_to_le16(1 << 0x9)) ? '1' : '0',
1555		     (beacon->capability & cpu_to_le16(1 << 0x8)) ? '1' : '0',
1556		     (beacon->capability & cpu_to_le16(1 << 0x7)) ? '1' : '0',
1557		     (beacon->capability & cpu_to_le16(1 << 0x6)) ? '1' : '0',
1558		     (beacon->capability & cpu_to_le16(1 << 0x5)) ? '1' : '0',
1559		     (beacon->capability & cpu_to_le16(1 << 0x4)) ? '1' : '0',
1560		     (beacon->capability & cpu_to_le16(1 << 0x3)) ? '1' : '0',
1561		     (beacon->capability & cpu_to_le16(1 << 0x2)) ? '1' : '0',
1562		     (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
1563		     (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
1564
1565	if (libipw_network_init(ieee, beacon, &network, stats)) {
1566		LIBIPW_DEBUG_SCAN("Dropped '%*pE' (%pM) via %s.\n",
1567				  info_element->len, info_element->data,
1568				  beacon->header.addr3,
1569				  is_beacon(beacon->header.frame_ctl) ?
1570				  "BEACON" : "PROBE RESPONSE");
1571		return;
1572	}
1573
1574	/* The network parsed correctly -- so now we scan our known networks
1575	 * to see if we can find it in our list.
1576	 *
1577	 * NOTE:  This search is definitely not optimized.  Once its doing
1578	 *        the "right thing" we'll optimize it for efficiency if
1579	 *        necessary */
1580
1581	/* Search for this entry in the list and update it if it is
1582	 * already there. */
1583
1584	spin_lock_irqsave(&ieee->lock, flags);
1585
1586	list_for_each_entry(target, &ieee->network_list, list) {
1587		if (is_same_network(target, &network))
1588			break;
1589
1590		if ((oldest == NULL) ||
1591		    time_before(target->last_scanned, oldest->last_scanned))
1592			oldest = target;
1593	}
1594
1595	/* If we didn't find a match, then get a new network slot to initialize
1596	 * with this beacon's information */
1597	if (&target->list == &ieee->network_list) {
1598		if (list_empty(&ieee->network_free_list)) {
1599			/* If there are no more slots, expire the oldest */
1600			list_del(&oldest->list);
1601			target = oldest;
1602			LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n",
1603					  target->ssid_len, target->ssid,
1604					  target->bssid);
1605		} else {
1606			/* Otherwise just pull from the free list */
1607			target = list_entry(ieee->network_free_list.next,
1608					    struct libipw_network, list);
1609			list_del(ieee->network_free_list.next);
1610		}
1611
1612#ifdef CONFIG_LIBIPW_DEBUG
1613		LIBIPW_DEBUG_SCAN("Adding '%*pE' (%pM) via %s.\n",
1614				  network.ssid_len, network.ssid,
1615				  network.bssid,
1616				  is_beacon(beacon->header.frame_ctl) ?
1617				  "BEACON" : "PROBE RESPONSE");
1618#endif
1619		memcpy(target, &network, sizeof(*target));
1620		list_add_tail(&target->list, &ieee->network_list);
1621	} else {
1622		LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n",
1623				  target->ssid_len, target->ssid,
1624				  target->bssid,
1625				  is_beacon(beacon->header.frame_ctl) ?
1626				  "BEACON" : "PROBE RESPONSE");
1627		update_network(target, &network);
1628	}
1629
1630	spin_unlock_irqrestore(&ieee->lock, flags);
1631
1632	if (is_beacon(beacon->header.frame_ctl)) {
1633		if (ieee->handle_beacon != NULL)
1634			ieee->handle_beacon(dev, beacon, target);
1635	} else {
1636		if (ieee->handle_probe_response != NULL)
1637			ieee->handle_probe_response(dev, beacon, target);
1638	}
1639}
1640
1641void libipw_rx_mgt(struct libipw_device *ieee,
1642		      struct libipw_hdr_4addr *header,
1643		      struct libipw_rx_stats *stats)
1644{
1645	switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
1646	case IEEE80211_STYPE_ASSOC_RESP:
1647		LIBIPW_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
1648				     WLAN_FC_GET_STYPE(le16_to_cpu
1649						       (header->frame_ctl)));
1650		libipw_handle_assoc_resp(ieee,
1651					    (struct libipw_assoc_response *)
1652					    header, stats);
1653		break;
1654
1655	case IEEE80211_STYPE_REASSOC_RESP:
1656		LIBIPW_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
1657				     WLAN_FC_GET_STYPE(le16_to_cpu
1658						       (header->frame_ctl)));
1659		break;
1660
1661	case IEEE80211_STYPE_PROBE_REQ:
1662		LIBIPW_DEBUG_MGMT("received auth (%d)\n",
1663				     WLAN_FC_GET_STYPE(le16_to_cpu
1664						       (header->frame_ctl)));
1665
1666		if (ieee->handle_probe_request != NULL)
1667			ieee->handle_probe_request(ieee->dev,
1668						   (struct
1669						    libipw_probe_request *)
1670						   header, stats);
1671		break;
1672
1673	case IEEE80211_STYPE_PROBE_RESP:
1674		LIBIPW_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1675				     WLAN_FC_GET_STYPE(le16_to_cpu
1676						       (header->frame_ctl)));
1677		LIBIPW_DEBUG_SCAN("Probe response\n");
1678		libipw_process_probe_response(ieee,
1679						 (struct
1680						  libipw_probe_response *)
1681						 header, stats);
1682		break;
1683
1684	case IEEE80211_STYPE_BEACON:
1685		LIBIPW_DEBUG_MGMT("received BEACON (%d)\n",
1686				     WLAN_FC_GET_STYPE(le16_to_cpu
1687						       (header->frame_ctl)));
1688		LIBIPW_DEBUG_SCAN("Beacon\n");
1689		libipw_process_probe_response(ieee,
1690						 (struct
1691						  libipw_probe_response *)
1692						 header, stats);
1693		break;
1694	case IEEE80211_STYPE_AUTH:
1695
1696		LIBIPW_DEBUG_MGMT("received auth (%d)\n",
1697				     WLAN_FC_GET_STYPE(le16_to_cpu
1698						       (header->frame_ctl)));
1699
1700		if (ieee->handle_auth != NULL)
1701			ieee->handle_auth(ieee->dev,
1702					  (struct libipw_auth *)header);
1703		break;
1704
1705	case IEEE80211_STYPE_DISASSOC:
1706		if (ieee->handle_disassoc != NULL)
1707			ieee->handle_disassoc(ieee->dev,
1708					      (struct libipw_disassoc *)
1709					      header);
1710		break;
1711
1712	case IEEE80211_STYPE_ACTION:
1713		LIBIPW_DEBUG_MGMT("ACTION\n");
1714		if (ieee->handle_action)
1715			ieee->handle_action(ieee->dev,
1716					    (struct libipw_action *)
1717					    header, stats);
1718		break;
1719
1720	case IEEE80211_STYPE_REASSOC_REQ:
1721		LIBIPW_DEBUG_MGMT("received reassoc (%d)\n",
1722				     WLAN_FC_GET_STYPE(le16_to_cpu
1723						       (header->frame_ctl)));
1724
1725		LIBIPW_DEBUG_MGMT("%s: LIBIPW_REASSOC_REQ received\n",
1726				     ieee->dev->name);
1727		if (ieee->handle_reassoc_request != NULL)
1728			ieee->handle_reassoc_request(ieee->dev,
1729						    (struct libipw_reassoc_request *)
1730						     header);
1731		break;
1732
1733	case IEEE80211_STYPE_ASSOC_REQ:
1734		LIBIPW_DEBUG_MGMT("received assoc (%d)\n",
1735				     WLAN_FC_GET_STYPE(le16_to_cpu
1736						       (header->frame_ctl)));
1737
1738		LIBIPW_DEBUG_MGMT("%s: LIBIPW_ASSOC_REQ received\n",
1739				     ieee->dev->name);
1740		if (ieee->handle_assoc_request != NULL)
1741			ieee->handle_assoc_request(ieee->dev);
1742		break;
1743
1744	case IEEE80211_STYPE_DEAUTH:
1745		LIBIPW_DEBUG_MGMT("DEAUTH\n");
1746		if (ieee->handle_deauth != NULL)
1747			ieee->handle_deauth(ieee->dev,
1748					    (struct libipw_deauth *)
1749					    header);
1750		break;
1751	default:
1752		LIBIPW_DEBUG_MGMT("received UNKNOWN (%d)\n",
1753				     WLAN_FC_GET_STYPE(le16_to_cpu
1754						       (header->frame_ctl)));
1755		LIBIPW_DEBUG_MGMT("%s: Unknown management packet: %d\n",
1756				     ieee->dev->name,
1757				     WLAN_FC_GET_STYPE(le16_to_cpu
1758						       (header->frame_ctl)));
1759		break;
1760	}
1761}
1762
1763EXPORT_SYMBOL_GPL(libipw_rx_any);
1764EXPORT_SYMBOL(libipw_rx_mgt);
1765EXPORT_SYMBOL(libipw_rx);