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

📄 ldl.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *  (But if bufcall fails mp is freed and a bogus DONE is returned *   to avoid hanging.) */STATIC int reply_error_ack(struct dl *dl, msgb_t *mp, dl_ulong primitive,			   dl_ulong err, dl_ulong uerr){	if (!reuse_msg(mp, DL_ERROR_ACK_SIZE)) {		mblk_t *bp;		if ((bp = allocb(DL_ERROR_ACK_SIZE, BPRI_HI)) == NULL)			return dl_bufcall(dl, mp, DL_ERROR_ACK_SIZE);		freemsg(mp);		mp = bp;	}	make_dl_error_ack(mp, primitive, err, uerr);	putnext(dl->rq, mp);	ginc(error_ack_cnt) ;	return DONE;}/****************************************************************************//*                                                                          *//*  Frame type support routines.                                            *//*                                                                          *//*  For every different kind of data link framing, we set up three          *//*  functions to handle it:                                                 *//*                                                                          *//*  int xxx_want(struct dl *dl, unsigned char *fr, int len);                *//*    Given a raw frame, return 0 or 1 to indicate if the given stream      *//*    wants to receive this frame. In case of a memory allocation failure,  *//*    the frame may have been truncated, but this function is still called  *//*    in order to get correct frame drop statistics.                        *//*                                                                          *//*  mblk_t *xxx_rcvind(struct dl *dl, mblk_t *dp);                          *//*    On entry, dp contains a raw data link frame that the stream has       *//*    indicated it wants to receive (xxx_want function above)               *//*    This function should remove the data link header from dp and create   *//*    an DL_UNITDATA_IND message.                                           *//*    If succesfull, a pointer to the resulting DL_UNITDATA_IND message     *//*    is returned.                                                          *//*    In case of failure, dp should be freed, and NULL should be returned.  *//*                                                                          *//*  int xxx_mkhdr(struct dl *dl, unsigned char *src, unsigned char *dst,    *//*                int datalen, struct sk_buff *skb);                        *//*    On entry, src and dst are pointers to the source and destination      *//*    DLSAPs, and skb is a pointer to a sk_buff that has just been          *//*    allocated and has had dl->machdr_reserve bytes reserved at the        *//*    beginning.                                                            *//*    The length of src and dst has been validated, but the function must   *//*    validate their contents and fill in the header.                       *//*    If succesfull, the header has been filled in and 1 is returned.       *//*    In case of failure, 0 is returned.                                    *//*                                                                          *//****************************************************************************//* *  Ethernet II */STATIC int eth_ii_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(dl->sap_len == 2);	if (len < 14)		return 0;	if (*(short *)(fr + 12) != *(short *)dl->sap->sap.sap) {		struct sap *sap = dl->subs;		while (sap != NULL) {			if (*(short *)(fr + 12) == *(short *)sap->sap.sap)				break;			sap = sap->next_sap;		}		if (sap == NULL)			return 0;	}	if (memcmp(fr, dl->ndev->dev->dev_addr, 6) &&	    memcmp(fr, dl->ndev->dev->broadcast, 6))		return 0;	return 1;}STATIC mblk_t *eth_ii_rcvind(struct dl *dl, mblk_t *dp){	mblk_t *bp;	dl_unitdata_ind_t *ud;	unsigned short dsap = ntohs(*(unsigned short *)(dp->b_rptr + 12));	ASSERT(dl->sap_len == 2);	ASSERT(dl->addr_len == 6);	if ((bp = allocb(DL_UNITDATA_IND_SIZE + 16, BPRI_LO)) == NULL) {		freeb(dp);		return NULL;	}	bp->b_datap->db_type = M_PROTO;	ud = (dl_unitdata_ind_t *)bp->b_rptr;	ud->dl_primitive = DL_UNITDATA_IND;	ud->dl_dest_addr_length = 8;	ud->dl_dest_addr_offset = DL_UNITDATA_IND_SIZE + 8;	ud->dl_src_addr_length = 8;	ud->dl_src_addr_offset = DL_UNITDATA_IND_SIZE;	ud->dl_group_address = *dp->b_rptr & 1;	bp->b_wptr += DL_UNITDATA_IND_SIZE;	memcpy(bp->b_wptr, dp->b_rptr + 6, 6);	bp->b_wptr += 6;	*(unsigned short *)(bp->b_wptr) = dsap;	bp->b_wptr += 2;	memcpy(bp->b_wptr, dp->b_rptr, 6);	bp->b_wptr += 6;	*(unsigned short *)(bp->b_wptr) = dsap;	bp->b_wptr += 2;	dp->b_rptr += 14;	linkb(bp, dp);	return bp;}STATIC int eth_ii_mkhdr(struct dl *dl, unsigned char *dst,		        int datalen, struct sk_buff *skb){	unsigned char *hdr;	unsigned short dsap;	dsap = htons(*(unsigned short *)(dst + 6));	hdr = skb_push(skb, 14);	memcpy(hdr, dst, 6);	memcpy(hdr + 6, dl->ndev->dev->dev_addr, 6);	*(unsigned short *)(hdr + 12) = dsap;	if (dsap != *(unsigned short *)dl->sap->sap.sap) {		struct sap *sap;		for (sap = dl->subs; sap; sap = sap->next_sap)			if (dsap == *(unsigned short *)sap->sap.sap)				return 1;		return 0;	}	return 1;}/* *  Ethernet 802.2 */STATIC int eth_8022_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(dl->sap_len == 1);	/*	 * The LDLFLAG_RAW check will disappear when we	 * get the RAW LLC frametype to work.	 * It means that when running in RAW mode, any value of the	 * control field will be accepted.	 */	if (len < 17 || (!(dl->flags & LDLFLAG_RAW) && *(fr + 16) != 0x03))		return 0;	if (ntohs(*(unsigned short *)(fr + 12)) < 3)		return 0;	if (dl->flags & LDLFLAG_PROMISC_SAP)		return 1;	if (*(fr + 14) != dl->sap->sap.sap[0]) {		struct sap *sap = dl->subs;		while (sap != NULL) {			if (*(fr + 14) == sap->sap.sap[0])				break;			sap = sap->next_sap;		}		if (sap == NULL)			return 0;	}#if 0	{       		int i ; 		printk("eth_8022_want: SAP checked, MAC@ not yet ...") ;		for (i = 0; i < 16; i++) printk("%02x ", fr[i]) ;		printk("\n") ;	}       #endif	/*	 * Start filtering on MAC addresses ...	 */	if (!memcmp(fr, dl->ndev->dev->dev_addr, 6))		return 1;	if (!memcmp(fr, dl->ndev->dev->broadcast, 6))		return 1;	/*	 * Check the registered multicast address list ...	 */	{		struct dev_mc_list *dmi = dl->ndev->dev->mc_list;		while (dmi != NULL)			if (!memcmp(fr, dmi->dmi_addr, 6))			       return 1;			else dmi = dmi->next;		}       	return 0;}STATIC mblk_t *eth_8022_rcvind(struct dl *dl, mblk_t *dp){	mblk_t *bp;	dl_unitdata_ind_t *ud;	unsigned short len;	ASSERT(dl->sap_len == 1);	ASSERT(dl->addr_len == 6);	if ((bp = allocb(DL_UNITDATA_IND_SIZE + 14, BPRI_LO)) == NULL) {		freeb(dp);		return NULL;	}	bp->b_datap->db_type = M_PROTO;	ud = (dl_unitdata_ind_t *)bp->b_rptr;	ud->dl_primitive = DL_UNITDATA_IND;	ud->dl_dest_addr_length = 7;	ud->dl_dest_addr_offset = DL_UNITDATA_IND_SIZE + 7;	ud->dl_src_addr_length = 7;	ud->dl_src_addr_offset = DL_UNITDATA_IND_SIZE;	ud->dl_group_address = *dp->b_rptr & 1;	bp->b_wptr += DL_UNITDATA_IND_SIZE;	memcpy(bp->b_wptr, dp->b_rptr + 6, 6);	bp->b_wptr += 6;	*bp->b_wptr++ = *(dp->b_rptr + 15);	memcpy(bp->b_wptr, dp->b_rptr, 6);	bp->b_wptr += 6;	*bp->b_wptr++ = *(dp->b_rptr + 14);	len = ntohs(*(unsigned short *)(dp->b_rptr + 12)) - 3;	dp->b_rptr += 17;	if (dp->b_wptr - dp->b_rptr > len)		dp->b_wptr = dp->b_rptr + len;	linkb(bp, dp);	return bp;}STATIC int eth_8022_mkhdr(struct dl *dl, unsigned char *dst,			  int datalen, struct sk_buff *skb){	unsigned char *hdr;	unsigned char dsap;	dsap = *(dst + 6);	if (dsap != dl->sap->sap.sap[0]) {		struct sap *sap;		for (sap = dl->subs; sap; sap = sap->next_sap)			if (dsap == sap->sap.sap[0])				break;		if (sap == NULL)			return 0;	}	hdr = skb_push(skb, 17);	memcpy(hdr, dst, 6);	memcpy(hdr + 6, dl->ndev->dev->dev_addr, 6);	*(unsigned short *)(hdr + 12) = htons(datalen + 3);	*(hdr + 14) = *(hdr + 15) = dsap;	*(hdr + 16) = 3;	return 1;}/* *  Ethernet RAW 802.2 */STATIC int eth_raw8022_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(dl->sap_len == 1);	if (len < 17 || ntohs(*(unsigned short *)(fr + 12)) < 3)		return 0;	if (*(unsigned short *)(fr + 14) == 0xffff)		return 0; /* "raw" 802.3 IPX */	if (dl->flags & LDLFLAG_PROMISC_SAP)		return 1;	if (*(fr + 14) != dl->sap->sap.sap[0]) {		struct sap *sap = dl->subs;		while (sap != NULL) {			if (*(fr + 14) == sap->sap.sap[0])				break;			sap = sap->next_sap;		}		if (sap == NULL)			return 0;	}	if (memcmp(fr, dl->ndev->dev->dev_addr, 6) &&	    memcmp(fr, dl->ndev->dev->broadcast, 6))		return 0;	return 1;}STATIC mblk_t *eth_raw8022_rcvind(struct dl *dl, mblk_t *dp){	mblk_t *bp;	dl_unitdata_ind_t *ud;	unsigned short len;	ASSERT(dl->sap_len == 1);	ASSERT(dl->addr_len == 6);	if ((bp = allocb(DL_UNITDATA_IND_SIZE + 14, BPRI_LO)) == NULL) {		freeb(dp);		return NULL;	}	bp->b_datap->db_type = M_PROTO;	ud = (dl_unitdata_ind_t *)bp->b_rptr;	ud->dl_primitive = DL_UNITDATA_IND;	ud->dl_dest_addr_length = 7;	ud->dl_dest_addr_offset = DL_UNITDATA_IND_SIZE + 7;	ud->dl_src_addr_length = 7;	ud->dl_src_addr_offset = DL_UNITDATA_IND_SIZE;	ud->dl_group_address = *dp->b_rptr & 1;	bp->b_wptr += DL_UNITDATA_IND_SIZE;	memcpy(bp->b_wptr, dp->b_rptr + 6, 6);	bp->b_wptr += 6;	*bp->b_wptr++ = *(dp->b_rptr + 15);	memcpy(bp->b_wptr, dp->b_rptr, 6);	bp->b_wptr += 6;	*bp->b_wptr++ = *(dp->b_rptr + 14);	len = ntohs(*(unsigned short *)(dp->b_rptr + 12));	dp->b_rptr += 14;	if (dp->b_wptr - dp->b_rptr > len)		dp->b_wptr = dp->b_rptr + len;	linkb(bp, dp);	return bp;}STATIC int eth_raw8022_mkhdr(struct dl *dl, unsigned char *dst,			  int datalen, struct sk_buff *skb){	unsigned char *hdr;	hdr = skb_push(skb, 14);	memcpy(hdr, dst, 6);	memcpy(hdr + 6, dl->ndev->dev->dev_addr, 6);	*(unsigned short *)(hdr + 12) = htons(datalen);	*(hdr + 14) = *(dst + 6);	*(hdr + 15) = dl->sap->sap.sap[0];	return 1;}/* *  Ethernet SNAP */STATIC int eth_snap_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(dl->sap_len == 2);	if (len < 22 ||	    ntohs(*(unsigned short *)(fr + 12)) < 8 ||	    *(unsigned short *)(fr + 14) != 0xAAAA ||	    *(fr + 16) != 0x03 ||	    memcmp(dl->oui, fr + 17, 3))		return 0;	if (memcmp(fr + 20, dl->sap->sap.sap, 2)) {		struct sap *sap = dl->subs;		while (sap != NULL) {			if (!memcmp(fr + 20, sap->sap.sap, 2))				break;			sap = sap->next_sap;		}		if (sap == NULL)			return 0;	}	if (memcmp(fr, dl->ndev->dev->dev_addr, 6) &&	    memcmp(fr, dl->ndev->dev->broadcast, 6))		return 0;	return 1;}STATIC mblk_t *eth_snap_rcvind(struct dl *dl, mblk_t *dp){	mblk_t *bp;	dl_unitdata_ind_t *ud;	unsigned short len;	unsigned short dsap = ntohs(*(unsigned short *)(dp->b_rptr + 17));	ASSERT(dl->sap_len == 2);	ASSERT(dl->addr_len == 6);	if ((bp = allocb(DL_UNITDATA_IND_SIZE + 22, BPRI_LO)) == NULL) {		freeb(dp);		return NULL;	}	bp->b_datap->db_type = M_PROTO;	ud = (dl_unitdata_ind_t *)bp->b_rptr;	ud->dl_primitive = DL_UNITDATA_IND;	ud->dl_dest_addr_length = 8;	ud->dl_dest_addr_offset = DL_UNITDATA_IND_SIZE + 8;	ud->dl_src_addr_length = 8;	ud->dl_src_addr_offset = DL_UNITDATA_IND_SIZE;	ud->dl_group_address = *dp->b_rptr & 1;	bp->b_wptr += DL_UNITDATA_IND_SIZE;	memcpy(bp->b_wptr, dp->b_rptr + 6, 6);	bp->b_wptr += 6;	*(unsigned short *)(bp->b_wptr) = dsap;	bp->b_wptr += 2;	memcpy(bp->b_wptr, dp->b_rptr, 6);	bp->b_wptr += 6;	*(unsigned short *)(bp->b_wptr) = dsap;	bp->b_wptr += 2;	len = ntohs(*(unsigned short *)(dp->b_rptr + 12)) - 8;	dp->b_rptr += 22;	if (dp->b_wptr - dp->b_rptr > len)		dp->b_wptr = dp->b_rptr + len;	linkb(bp, dp);	return bp;}STATIC int eth_snap_mkhdr(struct dl *dl, unsigned char *dst,			  int datalen, struct sk_buff *skb){	unsigned char *hdr;	unsigned short dsap;	dsap = *(unsigned short *)(dst + 6);	if (dsap != *(unsigned short *)dl->sap->sap.sap) {		struct sap *sap = dl->subs;		while (sap != NULL) {			if (dsap == *(unsigned short *)sap->sap.sap)				break;			sap = sap->next_sap;		}		if (sap == NULL)			return 0;	}	hdr = skb_push(skb, 22);	memcpy(hdr, dst, 6);	memcpy(hdr + 6, dl->ndev->dev->dev_addr, 6);	*(unsigned short *)(hdr + 12) = htons(datalen + 8);	*(unsigned short *)(hdr + 14) = 0xaaaa;	*(hdr + 16) = 3;	memcpy(hdr + 17, dl->oui, 3);	*(unsigned short *)(hdr + 20) = dsap;	return 1;}/* *  Ethernet 802.3 IPX */STATIC int ipx_8023_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(dl->sap_len == 0);	/* Must have a complete IPX header */	if (len < 44 || ntohs(*(unsigned short *)(fr + 12)) < 30)		return 0;	/* Must have no IPX checksum */	if (ntohs(*(unsigned short *)(fr + 14)) != 0xffff)		return 0;	if (memcmp(fr, dl->ndev->dev->dev_addr, 6) &&	    memcmp(fr, dl->ndev->dev->broadcast, 6))		return 0;	return 1;}STATIC mblk_t *ipx_8023_rcvind(struct dl *dl, mblk_t *dp){	mblk_t *bp;	dl_unitdata_ind_t *ud;	unsigned short len;	ASSERT(dl->sap_len == 0);	ASSERT(dl->addr_len == 6);	if ((bp = allocb(DL_UNITDATA_IND_SIZE + 12, BPRI_LO)) == NULL) {		freeb(dp);		return NULL;	}

⌨️ 快捷键说明

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