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

📄 p80211conv.c

📁 对于无线网卡采用prism芯片的linux的开源驱动.
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* perform de-wep if necessary.. */	if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {		if (payload_length <= 8) {			WLAN_LOG_ERROR("WEP frame too short (%u).\n",					skb->len);			return 1;		}		if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,				       payload_length - 8, -1, 				       skb->data + payload_offset, 				       skb->data + payload_offset + payload_length - 4))) {			/* de-wep failed, drop skb. */			WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo);			wlandev->rx.decrypt_err++;			return 2;		}		/* subtract the IV+ICV length off the payload */		payload_length -= 8;		/* chop off the IV */		skb_pull(skb, 4);		/* chop off the ICV. */		skb_trim(skb, skb->len - 4);				wlandev->rx.decrypt++;	}	e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);	e_llc = (wlan_llc_t *) (skb->data + payload_offset);	e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));	/* Test for the various encodings */	if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&	     ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&	     ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||	     (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {		WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length);		/* 802.3 Encapsulated */		/* Test for an overlength frame */		if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {			/* A bogus length ethfrm has been encap'd. */			/* Is someone trying an oflow attack? */			WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n", 				payload_length, netdev->mtu + WLAN_ETHHDR_LEN);			return 1;		}		/* Chop off the 802.11 header.  it's already sane. */		skb_pull(skb, payload_offset);		/* chop off the 802.11 CRC */		skb_trim(skb, skb->len - WLAN_CRC_LEN);	} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&		   (e_llc->dsap == 0xaa) &&		   (e_llc->ssap == 0xaa) &&		   (e_llc->ctl == 0x03) && 		   (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&		    (ethconv == WLAN_ETHCONV_8021h) && 		    (p80211_stt_findproto(ieee2host16(e_snap->type)))) || 		    (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0)))	{		WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length);		/* it's a SNAP + RFC1042 frame && protocol is in STT */		/* build 802.3 + RFC1042 */				/* Test for an overlength frame */		if ( payload_length > netdev->mtu ) {			/* A bogus length ethfrm has been sent. */			/* Is someone trying an oflow attack? */			WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n", 				payload_length, netdev->mtu);			return 1;		}		/* chop 802.11 header from skb. */		skb_pull(skb, payload_offset);		/* create 802.3 header at beginning of skb. */		e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);		memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);		memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); 		e_hdr->type = htons(payload_length);		/* chop off the 802.11 CRC */		skb_trim(skb, skb->len - WLAN_CRC_LEN);	}  else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&		    (e_llc->dsap == 0xaa) &&		    (e_llc->ssap == 0xaa) &&		    (e_llc->ctl == 0x03) ) {		WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length);		/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */		/* build a DIXII + RFC894 */				/* Test for an overlength frame */		if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t))		    > netdev->mtu) {			/* A bogus length ethfrm has been sent. */			/* Is someone trying an oflow attack? */			WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n",					(long int) (payload_length - sizeof(wlan_llc_t) - 						    sizeof(wlan_snap_t)),					netdev->mtu);			return 1;		}		/* chop 802.11 header from skb. */		skb_pull(skb, payload_offset);		/* chop llc header from skb. */		skb_pull(skb, sizeof(wlan_llc_t));		/* chop snap header from skb. */		skb_pull(skb, sizeof(wlan_snap_t));		/* create 802.3 header at beginning of skb. */		e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);		e_hdr->type = e_snap->type;		memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);		memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); 		/* chop off the 802.11 CRC */		skb_trim(skb, skb->len - WLAN_CRC_LEN);	} else {		WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length);		/* any NON-ENCAP */		/* it's a generic 80211+LLC or IPX 'Raw 802.3' */		/*  build an 802.3 frame */		/* allocate space and setup hostbuf */		/* Test for an overlength frame */		if ( payload_length > netdev->mtu ) {			/* A bogus length ethfrm has been sent. */			/* Is someone trying an oflow attack? */			WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n",				payload_length,				netdev->mtu);			return 1;		}		/* Chop off the 802.11 header. */		skb_pull(skb, payload_offset);		/* create 802.3 header at beginning of skb. */		e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);		memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);		memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); 		e_hdr->type = htons(payload_length);		/* chop off the 802.11 CRC */		skb_trim(skb, skb->len - WLAN_CRC_LEN);	}	skb->protocol = eth_type_trans(skb, netdev);	skb->mac.raw = (unsigned char *) e_hdr; /* new MAC header */        /* jkriegl: process signal and noise as set in hfa384x_int_rx() */	/* jkriegl: only process signal/noise if requested by iwspy */        if (wlandev->spy_number)                orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb));	/* Free the metadata */	p80211skb_rxmeta_detach(skb);	DBFEXIT;	return 0;}/*----------------------------------------------------------------* p80211_stt_findproto** Searches the 802.1h Selective Translation Table for a given * protocol.** Arguments:*	proto	protocl number (in host order) to search for.** Returns: *	1 - if the table is empty or a match is found.*	0 - if the table is non-empty and a match is not found.*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/int p80211_stt_findproto(UINT16 proto){	/* Always return found for now.  This is the behavior used by the */	/*  Zoom Win95 driver when 802.1h mode is selected */	/* TODO: If necessary, add an actual search we'll probably		 need this to match the CMAC's way of doing things.		 Need to do some testing to confirm.	*/	if (proto == 0x80f3)  /* APPLETALK */		return 1;	return 0;}/*----------------------------------------------------------------* p80211skb_rxmeta_detach** Disconnects the frmmeta and rxmeta from an skb.** Arguments:*	wlandev		The wlandev this skb belongs to.*	skb		The skb we're attaching to.** Returns: *	0 on success, non-zero otherwise*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/voidp80211skb_rxmeta_detach(struct sk_buff *skb){	p80211_rxmeta_t		*rxmeta;	p80211_frmmeta_t	*frmmeta;	DBFENTER;	/* Sanity checks */	if ( skb==NULL ) {			/* bad skb */		WLAN_LOG_DEBUG(1, "Called w/ null skb.\n");		goto exit;	}	frmmeta = P80211SKB_FRMMETA(skb);	if ( frmmeta == NULL ) { 		/* no magic */		WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n");		goto exit;	}	rxmeta = frmmeta->rx;	if ( rxmeta == NULL ) {			/* bad meta ptr */		WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n");		goto exit;	}		/* Free rxmeta */	kfree(rxmeta);	/* Clear skb->cb */	memset(skb->cb, 0, sizeof(skb->cb));exit:	DBFEXIT;	return;}/*----------------------------------------------------------------* p80211skb_rxmeta_attach** Allocates a p80211rxmeta structure, initializes it, and attaches* it to an skb.** Arguments:*	wlandev		The wlandev this skb belongs to.*	skb		The skb we're attaching to.** Returns: *	0 on success, non-zero otherwise*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/intp80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb){	int			result = 0;	p80211_rxmeta_t		*rxmeta;	p80211_frmmeta_t	*frmmeta;	DBFENTER;	/* If these already have metadata, we error out! */	if (P80211SKB_RXMETA(skb) != NULL) {		WLAN_LOG_ERROR("%s: RXmeta already attached!\n", 				wlandev->name);			result = 0;		goto exit;	}	/* Allocate the rxmeta */	rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC); 	if ( rxmeta == NULL ) {		WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n", 				wlandev->name);		result = 1;		goto exit;	}	/* Initialize the rxmeta */	memset(rxmeta, 0, sizeof(p80211_rxmeta_t));	rxmeta->wlandev = wlandev;	rxmeta->hosttime = jiffies;	/* Overlay a frmmeta_t onto skb->cb */	memset(skb->cb, 0, sizeof(p80211_frmmeta_t));	frmmeta = (p80211_frmmeta_t*)(skb->cb);	frmmeta->magic = P80211_FRMMETA_MAGIC;	frmmeta->rx = rxmeta;exit:	DBFEXIT;	return result;}/*----------------------------------------------------------------* p80211skb_free** Frees an entire p80211skb by checking and freeing the meta struct* and then freeing the skb.** Arguments:*	wlandev		The wlandev this skb belongs to.*	skb		The skb we're attaching to.** Returns: *	0 on success, non-zero otherwise*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/voidp80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb){	p80211_frmmeta_t	*meta;	DBFENTER;	meta = P80211SKB_FRMMETA(skb);	if ( meta && meta->rx) {		p80211skb_rxmeta_detach(skb);	} else {		WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);	}	dev_kfree_skb(skb);	DBFEXIT;	return;}

⌨️ 快捷键说明

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