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

📄 p80211conv.c

📁 Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用意是提供全系列的IEEE 802.11标准的Mac 管理功能
💻 C
📖 第 1 页 / 共 2 页
字号:
		skb_put( ((struct sk_buff*)pb->ethhostbuf), buflen);	/* make room */		pb->ethbuf = ((struct sk_buff*)pb->ethhostbuf)->data;		pb->ethbuflen = buflen;		/* setup the pointers */		pb->eth_hdr = (wlan_ethhdr_t*)pb->ethbuf;		pb->eth_llc = (wlan_llc_t*)(pb->ethbuf + sizeof(wlan_ethhdr_t));		pb->eth_snap = (wlan_snap_t*)			(pb->ethbuf + sizeof(wlan_ethhdr_t) + sizeof(wlan_llc_t));		pb->eth_payload = pb->ethbuf + sizeof(wlan_ethhdr_t);		pb->eth_payloadlen = buflen - sizeof(wlan_ethhdr_t);		/* now copy the data from the 80211 frame */		memcpy( pb->ethbuf, pb->p80211_payload, buflen);	/* copy the data */	} else if (	pb->p80211_llc->dsap == 0xaa &&				pb->p80211_llc->ssap == 0xaa &&				pb->p80211_llc->ctl == 0x03 &&				memcmp( pb->p80211_snap->oui, 					oui_rfc1042, WLAN_IEEE_OUI_LEN) == 0 &&				ethconv == WLAN_ETHCONV_8021h && 				p80211_stt_findproto(ieee2host16(pb->p80211_snap->type)) ) {		/* it's a SNAP + RFC1042 frame && protocol is in STT */		/* build 802.3 + RFC1042 */				/* Test for an overlength frame */		if ( pb->p80211_payloadlen > WLAN_MAX_ETHFRM_LEN - WLAN_ETHHDR_LEN ) {			/* A bogus length ethfrm has been sent. */			/* Is someone trying an oflow attack? */			return 1;		}		llclen = pb->p80211_payloadlen;		buflen = wlan_max( llclen + sizeof(wlan_ethhdr_t), WLAN_MIN_ETHFRM_LEN);		pb->ethhostbuf = dev_alloc_skb(buflen + 2); /* +2 is attempt to align IP header */		if ( pb->ethhostbuf == NULL ) return 1;		skb_reserve( (struct sk_buff*)pb->ethhostbuf, 2);				skb_put( (struct sk_buff*)pb->ethhostbuf, buflen);	/* make room */		pb->ethbuf = ((struct sk_buff*)pb->ethhostbuf)->data;		pb->ethbuflen = buflen;/*		memset( pb->ethbuf, 0, buflen);	*/		/* zero for possible PAD */		/* set up the pointers */		pb->eth_hdr = (wlan_ethhdr_t*)pb->ethbuf;		pb->eth_llc = (wlan_llc_t*)(pb->ethbuf + sizeof(wlan_ethhdr_t));		pb->eth_snap = (wlan_snap_t*)			(pb->ethbuf + sizeof(wlan_ethhdr_t) + sizeof(wlan_llc_t));		pb->eth_payload = pb->ethbuf + sizeof(wlan_ethhdr_t);		pb->eth_payloadlen = llclen;		/* set up the 802.3 header */			pb->eth_hdr->type = htons(pb->eth_payloadlen);		memcpy( pb->eth_hdr->daddr, daddr, WLAN_ETHADDR_LEN);		memcpy( pb->eth_hdr->saddr, saddr, WLAN_ETHADDR_LEN);		/* now copy the data from the 80211 frame */		memcpy( pb->eth_payload, pb->p80211_payload, pb->p80211_payloadlen);	} else if ( pb->p80211_llc->dsap == 0xaa &&			pb->p80211_llc->ssap == 0xaa &&			pb->p80211_llc->ctl == 0x03 ) {		/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */		/* build a DIXII + RFC894 */		dixlen = pb->p80211_payloadlen - sizeof(wlan_llc_t) - sizeof(wlan_snap_t);		/* Test for an overlength frame */		if ( dixlen + WLAN_ETHHDR_LEN > WLAN_MAX_ETHFRM_LEN) {			/* A bogus length ethfrm has been sent. */			/* Is someone trying an oflow attack? */			return 1;		}		dixlen = pb->p80211_payloadlen - sizeof(wlan_llc_t) - sizeof(wlan_snap_t);		buflen = wlan_max( dixlen + sizeof(wlan_ethhdr_t), WLAN_MIN_ETHFRM_LEN);		pb->ethhostbuf = dev_alloc_skb(buflen + 2); /* +2 is attempt to align IP header */		if ( pb->ethhostbuf == NULL ) return 1;		skb_reserve( (struct sk_buff*)pb->ethhostbuf, 2);				skb_put( (struct sk_buff*)pb->ethhostbuf, buflen);	/* make room */		pb->ethbuf = ((struct sk_buff*)pb->ethhostbuf)->data;		pb->ethbuflen = buflen;/*		memset( pb->ethbuf, 0, buflen);	*/		/* zero for possible PAD */		/* set up the pointers */		pb->eth_hdr = (wlan_ethhdr_t*)pb->ethbuf;		pb->eth_llc = NULL;		pb->eth_snap = NULL;		pb->eth_payload = pb->ethbuf + sizeof(wlan_ethhdr_t);		pb->eth_payloadlen = dixlen;		/* make sure the llc and snap ptrs are set */		pb->p80211_llc = (wlan_llc_t*)pb->p80211_payload;		pb->p80211_snap = (wlan_snap_t*)			(pb->p80211_payload + sizeof(wlan_llc_t));		/* set up the DIXII header */			pb->eth_hdr->type = pb->p80211_snap->type;		memcpy( pb->eth_hdr->daddr, daddr, WLAN_ETHADDR_LEN);		memcpy( pb->eth_hdr->saddr, saddr, WLAN_ETHADDR_LEN);		/* now copy the data from the 80211 frame */		memcpy( pb->eth_payload, 				pb->p80211_payload + sizeof(wlan_llc_t) + sizeof(wlan_snap_t), 				dixlen);	} else {		/* 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 ( pb->p80211_payloadlen + WLAN_ETHHDR_LEN > WLAN_MAX_ETHFRM_LEN) {			/* A bogus length ethfrm has been sent. */			/* Is someone trying an oflow attack? */			return 1;		}		llclen = pb->p80211_payloadlen;		buflen = wlan_max( llclen + sizeof(wlan_ethhdr_t), WLAN_MIN_ETHFRM_LEN);		pb->ethhostbuf = dev_alloc_skb(buflen + 2); /* +2 is attempt to align IP header */		if ( pb->ethhostbuf == NULL ) return 1;		skb_reserve( (struct sk_buff*)pb->ethhostbuf, 2);				skb_put( (struct sk_buff*)pb->ethhostbuf, buflen);	/* make room */		pb->ethbuf = ((struct sk_buff*)pb->ethhostbuf)->data;		pb->ethbuflen = buflen;/*		memset( pb->ethbuf, 0, buflen);	*/		/* zero for possible PAD */		/* set up the pointers */		pb->eth_hdr = (wlan_ethhdr_t*)pb->ethbuf;		pb->eth_llc = (wlan_llc_t*)(pb->ethbuf + sizeof(wlan_ethhdr_t));		pb->eth_snap = (wlan_snap_t*)			(pb->ethbuf + sizeof(wlan_ethhdr_t) + sizeof(wlan_llc_t));		pb->eth_payload = pb->ethbuf + sizeof(wlan_ethhdr_t);		pb->eth_payloadlen = llclen;		/* set up the 802.3 header */			pb->eth_hdr->type = htons(pb->eth_payloadlen);		memcpy( pb->eth_hdr->daddr, daddr, WLAN_ETHADDR_LEN);		memcpy( pb->eth_hdr->saddr, saddr, WLAN_ETHADDR_LEN);		/* now copy the data from the 80211 frame */		memcpy( pb->eth_payload, pb->p80211_payload, pb->p80211_payloadlen);	}	return 0;}/*----------------------------------------------------------------* p80211pb_freeskb** Free method for wlan_pb's that have skbs in them.  Called* via ptr from p80211pb_free.  ** Arguments:*	buf	Ptr to an skb*	size	Passed in to match the ptr declaration.*		Unused in this function.** Returns: *	nothing*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/void p80211pb_freeskb( void *buf, int size ){	dev_kfree_skb( (struct sk_buff*)buf );}/*----------------------------------------------------------------* p80211pb_pbfreeskb** Free method for wlan_pb's that linux kmalloc'd buffers in them.  * Called via ptr from p80211pb_free.  ** Arguments:*	buf	Ptr to buffer*	size	Size of buffer** Returns: *	nothing*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/void p80211pb_kfree_s( void *buf, int size){	kfree_s( buf, size);}/*----------------------------------------------------------------* p80211pb_alloc** Allocs and zeros a wlan_pb structure.  Largely here for symmetry* with the pbfree routine.  Also handy w/ ports to platforms where* we have fixed alloc pools.** Arguments:*	none** Returns: *	The address of a zeroed wlan_pb on success, NULL otherwise.*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/wlan_pb_t* p80211pb_alloc(void){	wlan_pb_t	*pb;	pb = kmalloc( sizeof(wlan_pb_t), GFP_ATOMIC);	if ( pb != NULL ) {		memset(pb, 0, sizeof(wlan_pb_t));	}	return pb;}/*----------------------------------------------------------------* p80211pb_alloc_p80211** Allocates a buffer for an 80211 frame and sets the ptrs in a * given pb.  Primarily used by the receive path.  Handled* here so that the allocation used and the free method are set* in one place (helps with portability?).** Arguments:*	pb	ptr to a wlan_pb_t previously allocated w/ p80211pb_alloc*		if NULL, calls p80211pb_alloc.*	size	length of the 802.11 buffer to allocate.  Note that*		on some platforms w/ fixed size buffer pools, the size*		will be ignored for allocation but _will_ be set in*		the pb structure.** Returns: *	The address of the given or allocated wlan_pb on success, *	NULL otherwise.*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/wlan_pb_t* p80211pb_alloc_p80211(wlan_pb_t *pb, UINT len){	if ( pb == NULL ) {		pb = p80211pb_alloc();	}	if ( pb != NULL ) {		pb->p80211hostbuf = kmalloc( len, GFP_ATOMIC);		if ( pb->p80211hostbuf != NULL ) {			pb->p80211free = p80211pb_kfree_s;			pb->p80211buf = (UINT8*)pb->p80211hostbuf;			pb->p80211buflen = len;			pb->p80211frmlen = len;		/* initially assume frm is same as buf */			pb->p80211_hdr = (p80211_hdr_t*)pb->p80211buf;			pb->p80211_payload = pb->p80211buf + WLAN_HDR_A3_LEN;			pb->p80211_payloadlen = pb->p80211buflen - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;		}	}	return pb;}/*----------------------------------------------------------------* p80211pb_free** Frees the ethhostbuf and the p80211hostbuf elements of a wlan_pb* if there is a free method for each.  Then frees the wlan_pb itself.** Arguments:*	pb	ptr to a wlan_pb_t previously allocated w/ p80211pb_alloc*		or p80211pb_alloc_p80211.** Returns: *	nothing*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/void p80211pb_free(wlan_pb_t* pb){	if ( pb != NULL ) {		if ( pb->ethhostbuf != NULL && pb->ethfree != NULL)		{			(*(pb->ethfree))(pb->ethhostbuf, pb->ethbuflen);		}		if ( pb->p80211hostbuf != NULL && pb->p80211free != NULL)		{			(*(pb->p80211free))(pb->p80211hostbuf, pb->p80211buflen);		}		kfree_s(pb, sizeof(wlan_pb_t));	}}/*----------------------------------------------------------------* 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.	*/	return 1;}#if 0/* MSM: This function is currently unused.  Not sure if we'll ever need it. *//*----------------------------------------------------------------* p80211_stt_addproto** Add a protocol to the 802.1h Selective Translation Table.** Arguments:*	proto	protocl number (in host order) to search for.** Returns: *	nothing*	* Call context:*	May be called in interrupt or non-interrupt context----------------------------------------------------------------*/int p80211_stt_addproto(UINT16 proto){	return;}#endif

⌨️ 快捷键说明

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