⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee80211_rx.c

📁 rtl8180网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	u16 sc;	unsigned int seq;	struct ieee80211_frag_entry *entry;	sc = le16_to_cpu(hdr->seq_ctrl);	seq = WLAN_GET_SEQ_SEQ(sc);	entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2, 					  hdr->addr1);	if (entry == NULL) {		printk(KERN_DEBUG "%s: could not invalidate fragment cache "		       "entry (seq=%u)\n",		       ieee->dev->name, seq);		return -1;	}	entry->skb = NULL;	return 0;} static inline voidieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb){	u8 dest[ETH_ALEN];		//IEEE80211DMESG("Rx probe");	ieee->ieee_stats.rx_probe++;	//DMESG("Dest is "MACSTR, MAC2STR(dest));	if (probe_rq_parse(ieee, skb, dest)){		//IEEE80211DMESG("Was for me!");		ieee->ieee_stats.tx_probe++;		ieee80211_resp_to_probe(ieee, dest);			}}static inline voidieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb){	u8 dest[ETH_ALEN];	int status;	//IEEE80211DMESG("Rx probe");	ieee->ieee_stats.rx_auth_rq++;		if((status = auth_rq_parse(skb,dest))!= -1){		ieee80211_resp_to_auth(ieee,status,dest);	}	//DMESG("Dest is "MACSTR, MAC2STR(dest));	}static inline voidieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb){	u8 dest[ETH_ALEN];	unsigned long flags;		ieee->ieee_stats.rx_assoc_rq++;	if(assoc_rq_parse(skb,dest)!=-1){		ieee80211_resp_to_assoc_rq(ieee,dest);	}		IEEE80211DMESG("New client associated: "MACSTR, MAC2STR(dest));		spin_lock_irqsave(&ieee->lock,flags);	add_associate(ieee,dest);	spin_unlock_irqrestore(&ieee->lock,flags);}static inline intieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,			struct ieee80211_rx_stats *rx_stats, u16 type,			u16 stype){	u16 errcode;	#if 0	if (ieee->iw_mode == IW_MODE_MASTER) {		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",		       ieee->dev->name);		return 0;	/*  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)  skb->data);*/	}	#endif	if (type == WLAN_FC_TYPE_MGMT) {		if (stype == IEEE802_11_STYPE_BEACON ||		    stype == IEEE802_11_STYPE_PROBE_RESP){		//	struct sk_buff *skb2;			/* Process beacon frames also in kernel driver to			 * update STA(AP) table statistics */		//	skb2 = skb_clone(skb, GFP_ATOMIC);		//	if (skb2)			/*if(ieee->link_state!=WLAN_LINK_ASSOCIATED)*/						if(ieee80211_rx_beacon(ieee, skb,rx_stats))				return -1;			else				return 1;		}		if(ieee->iw_mode == IW_MODE_MASTER && 			(stype == IEEE802_11_STYPE_ASSOC_REQ || stype == IEEE802_11_STYPE_REASSOC_REQ))					ieee80211_rx_assoc_rq(ieee, skb);				if(ieee->iw_mode == IW_MODE_MASTER && 			stype == IEEE802_11_STYPE_AUTH)			ieee80211_rx_auth_rq(ieee, skb);					if(((ieee->iw_mode == IW_MODE_ADHOC 			|| ieee->iw_mode == IW_MODE_MASTER)&&			ieee->link_state == WLAN_LINK_ASSOCIATED) && 				stype == IEEE802_11_STYPE_PROBE_REQ)			ieee80211_rx_probe_rq(ieee, skb);					if(ieee->link_state == WLAN_LINK_ASSOCIATED && 			ieee->iw_mode == IW_MODE_INFRA){			if(stype == IEEE802_11_STYPE_DISASSOC ||			   stype == IEEE802_11_STYPE_DEAUTH){								ieee->func->data_poll_hard_stop(ieee->dev);								ieee->link_state = WLAN_LINK_ASSOCIATING;				ieee->ieee_stats.reassoc++;								ieee80211_associate_step1(ieee);				//queue_work(ieee->workqueue ,&ieee->associate_tasklet);			}		}		if(ieee->link_state == WLAN_LINK_ASSOCIATING && 			ieee->iw_mode == IW_MODE_INFRA){					if(ieee->associate_state==ASSOC_AUTH)				if(stype == IEEE802_11_STYPE_AUTH){					IEEE80211DMESG("Received authentication response");					if(0 == (errcode=auth_parse(skb))){						ieee->associate_state=ASSOC_REQ;						ieee->ieee_stats.rx_aut_ok++;												ieee80211_associate_step2(ieee);					}else{						ieee->ieee_stats.rx_aut_err++;						IEEE80211DMESG("Authentication respose status code 0x%x",errcode);						ieee80211_associate_abort(ieee);					}				}			if(ieee->associate_state==ASSOC_REQ)				if(stype == IEEE802_11_STYPE_ASSOC_RESP){					IEEE80211DMESG("Received association response");					if(0 == (errcode=assoc_parse(skb)))					{						ieee->associate_state=ASSOC_SUCCESS;						ieee->ieee_stats.rx_ass_ok++;												ieee80211_associate_complete(ieee);					}else{						ieee->ieee_stats.rx_ass_err++;						IEEE80211DMESG("Association response status code 0x%x",errcode);						ieee80211_associate_abort(ieee); 					}				}				}		/* send management frames to the user space daemon for		 * processing */		//ieee->apdevstats.rx_packets++;		//ieee->apdevstats.rx_bytes += skb->len;		//prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);		return 0;	}#if 0	    	    if (ieee->iw_mode == IW_MODE_MASTER) {		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {			printk(KERN_DEBUG "%s: unknown management frame "			       "(type=0x%02x, stype=0x%02x) dropped\n",			       skb->dev->name, type, stype);			return -1;		}		hostap_rx(skb->dev, skb, rx_stats);		return 0;	} #endif	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "	       "received in non-Host AP mode\n", skb->dev->name);	return -1;}/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation *//* Ethernet-II snap header (RFC1042 for most EtherTypes) */static unsigned char rfc1042_header[] ={ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */static unsigned char bridge_tunnel_header[] ={ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };/* No encapsulation header if EtherType < 0x600 (=length) */#ifndef CONFIG_IEEE80211_NOWEP/* Called by ieee80211_rx_frame_decrypt */static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, 				    struct sk_buff *skb){	struct net_device *dev = ieee->dev;	u16 fc, ethertype;	struct ieee80211_hdr *hdr;	u8 *pos;	if (skb->len < 24)		return 0;	hdr = (struct ieee80211_hdr *) skb->data;	fc = le16_to_cpu(hdr->frame_control);	/* check that the frame is unicast frame to us */	if ((fc & (IEEE802_11_FCTL_TODS | IEEE802_11_FCTL_FROMDS)) == 	    IEEE802_11_FCTL_TODS &&	    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&	    memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {		/* ToDS frame with own addr BSSID and DA */	} else if ((fc & (IEEE802_11_FCTL_TODS | IEEE802_11_FCTL_FROMDS)) == 		   IEEE802_11_FCTL_FROMDS &&		   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {		/* FromDS frame with own addr as DA */	} else		return 0;	if (skb->len < 24 + 8)		return 0;	/* check for port access entity Ethernet type */	pos = skb->data + 24;	ethertype = (pos[6] << 8) | pos[7];	if (ethertype == ETH_P_PAE)		return 1;	return 0;}/* Called only as a tasklet (software IRQ), by ieee80211_rx */static inline intieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,			struct ieee80211_crypt_data *crypt){	struct ieee80211_hdr *hdr;	int res, hdrlen;	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)		return 0;	hdr = (struct ieee80211_hdr *) skb->data;	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));#ifdef NOT_YET	if (ieee->tkip_countermeasures &&	    strcmp(crypt->ops->name, "TKIP") == 0) {		if (net_ratelimit()) {			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "			       "received packet from " MACSTR "\n",			       ieee->dev->name, MAC2STR(hdr->addr2));		}		return -1;	}#endif	atomic_inc(&crypt->refcnt);	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);	atomic_dec(&crypt->refcnt);	if (res < 0) {		printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR		       ") res=%d\n",		       ieee->dev->name, MAC2STR(hdr->addr2), res);		if (res == -2)			printk(KERN_DEBUG "%s: WEP decryption failed ICV mismatch\n",				ieee->dev->name);		ieee->ieee_stats.rx_discards_wep_undecryptable++;		return -1;	}	return res;}/* Called only as a tasklet (software IRQ), by ieee80211_rx */static inline intieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,			     int keyidx, struct ieee80211_crypt_data *crypt){	struct ieee80211_hdr *hdr;	int res, hdrlen;	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)		return 0;	hdr = (struct ieee80211_hdr *) skb->data;	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));	atomic_inc(&crypt->refcnt);	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);	atomic_dec(&crypt->refcnt);	if (res < 0) {		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"		       " (SA=" MACSTR " keyidx=%d)\n",		       ieee->dev->name, MAC2STR(hdr->addr2), keyidx);		return -1;	}	return 0;}#endif /* CONFIG_IEEE80211_NOWEP *//* All received frames are sent to this function. @skb contains the frame in * IEEE 802.11 format, i.e., in the format it was sent over air. * This function is called only as a tasklet (software IRQ). */int ieee80211_r8180_rx(struct ieee80211_device *ieee, struct sk_buff *skb,		 struct ieee80211_rx_stats *rx_stats){	struct net_device *dev = ieee->dev;	struct ieee80211_hdr *hdr;	size_t hdrlen;	u16 fc, type, stype, sc;	struct net_device_stats *stats;	unsigned int frag;	u8 *payload;	u16 ethertype;	int err;	struct sk_buff *skb2 = NULL;	short unknow;	unsigned long flags;#ifdef NOT_YET	struct net_device *wds = NULL;		struct net_device *wds = NULL;	int frame_authorized = 0;	int from_assoc_ap = 0;	void *sta = NULL;#endif	u8 dst[ETH_ALEN];	u8 src[ETH_ALEN];#ifndef CONFIG_IEEE80211_NOWEP	struct ieee80211_crypt_data *crypt = NULL;	int keyidx = 0;#endif /* CONFIG_IEEE80211_NOWEP */	hdr = (struct ieee80211_hdr *)skb->data;	stats = &ieee->stats;	if (skb->len < 10) {		printk(KERN_INFO "%s: SKB length < 10\n",		       dev->name);		goto rx_dropped;	}		fc = le16_to_cpu(hdr->frame_control);	type = WLAN_FC_GET_TYPE(fc);	stype = WLAN_FC_GET_STYPE(fc);	sc = le16_to_cpu(hdr->seq_ctrl);	frag = WLAN_GET_SEQ_FRAG(sc);	hdrlen = ieee80211_get_hdrlen(fc);#ifdef NOT_YET#if WIRELESS_EXT > 15	/* Put this code here so that we avoid duplicating it in all	 * Rx paths. - Jean II */#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */	/* If spy monitoring on */	if (iface->spy_data.spy_number > 0) {		struct iw_quality wstats;		wstats.level = rx_stats->signal;		wstats.noise = rx_stats->noise;		wstats.updated = 6;	/* No qual value */		/* Update spy records */		wireless_spy_update(dev, hdr->addr2, &wstats);	}#endif /* IW_WIRELESS_SPY */#endif /* WIRELESS_EXT > 15 */	hostap_update_rx_stats(local->ap, hdr, rx_stats);#endif#if WIRELESS_EXT > 15	if (ieee->iw_mode == IW_MODE_MONITOR) {		ieee80211_monitor_rx(ieee, skb, rx_stats);		stats->rx_packets++;		stats->rx_bytes += skb->len;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -