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

📄 ldl.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 = 6;	ud->dl_dest_addr_offset = DL_UNITDATA_IND_SIZE;	ud->dl_src_addr_length = 6;	ud->dl_src_addr_offset = DL_UNITDATA_IND_SIZE + 6;	ud->dl_group_address = *dp->b_rptr & 1;	bp->b_wptr += DL_UNITDATA_IND_SIZE;	memcpy(bp->b_wptr, dp->b_rptr, 12);	bp->b_wptr += 12;	len = *(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 ipx_8023_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);	return 1;}/* * Token Ring 802.2 LLC * * The bound sap must match the dsap of the received frame but the * control field can be anything at all.  LLC uses _real_ control * fields for link layer protocol. * * For received data the entire header is returned even though we * extract the addresses into the unitdata indication header. * * For transmitted data the caller has built the header by the * time we get the frame.  We transmit the frame as-is. *//* * Token ring header. * * Note that there is no length field as there is in an Ethernet * header.  IP packet types have to be encoded inside a SNAP header * beyond the LLC header. */typedef struct tr_hdr{    u8        acf ;         u8        fcf ;         u8        dst_addr[6] ;    u8        src_addr[6] ;    /*     * Routing control bytes: Only present if the routing bit     * is set in the first byte of the src_addr.     */    u8        bl ;                    /* brdcst & lgth */    u8        df ;                    /* direction & lrgst frm bits */} tr_hdr_t ;/* * After a variable amount of routing data you come to the * LLC header. */typedef struct tr_llc_frm_hdr{    u8        llc_dsap ;              /* destination SAP address */    u8        llc_ssap ;              /* source SAP address */    u8        llc_ctl[1] ;            /* control field */} tr_llc_frm_hdr_t ;/*  * A few bits from the token ring header. */#define SADDR_0_RTE_PRES        0x80    /* 1=rte info present, 0=none */#define RCF_0_LLLLL             0x1F    /* length bits */#define FCF_FF          	0xC0    /* frame type bits */#define     FCF_MAC     	0x00    /* MAC frame */#define     FCF_LLC     	0x40    /* LLC frame */STATIC int tr_8022_want(struct dl *dl, unsigned char *fr, int len){					/* patterned after eth_8022_want */    tr_hdr_t		*trp ;    tr_llc_frm_hdr_t	*llcp ;    int			 rtelgth ;#if 0    {	int i ;	printk("tr_8022_want:\n") ;	for (i = 0; i < 16; i++)	    printk("%02x ", fr[i]) ;	printk("\n") ;	for (; i < 32; i++)	    printk("%02x ", fr[i]) ;	printk("\n") ;    }#endif    trp = (tr_hdr_t *) fr ;    ASSERT(dl->sap_len == 1);    if (len < sizeof(tr_hdr_t)-2 + sizeof(tr_llc_frm_hdr_t))	    return 0;    /*     * Decode the type of frame.  If a MAC frame, we don't want it.     * If an LLC frame, we will look at it.     */    if ((trp->fcf & FCF_FF) != FCF_LLC)		/* must be LLC type frame */	return(0) ;				/* we don't want it */    /*     * Find out how much routing info is present and skip over it.     * Establish llcp pointing to the LLC header.     *     * The length in the RCF includes the two bytes of routing control     * at the front of the RCF.  These two bytes are included in our     * header structure.     */    if (trp->src_addr[0] & SADDR_0_RTE_PRES)    {					/* has source route field */	rtelgth = trp->bl & RCF_0_LLLLL ;	if (rtelgth < 2)		/* count includes rte ctl fld */	    return 0 ;			/* ill-formed, don't want it */	if (rtelgth & 0x01)		/* must be pairs of bytes */	    return 0 ;			/* ill-formed, don't want it */	llcp = (tr_llc_frm_hdr_t *) (fr + sizeof(*trp)-2 + rtelgth) ;    }    else				/* no source route field */    {					/* don't skip as many bytes */	llcp = (tr_llc_frm_hdr_t *) (fr + sizeof(*trp)-2) ;    }    /*     * Now that we know where the SAPs are and that it's an LLC frame     * we can search for a dlsap match.     *     * 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 (!(dl->flags & LDLFLAG_RAW) && llcp->llc_ctl[0] != 0x03)	return 0 ;    if (dl->flags & LDLFLAG_PROMISC_SAP)	    return 1;				/* wants everything */    if (llcp->llc_dsap != dl->sap->sap.sap[0]) {	    struct sap *sap = dl->subs;	    while (sap != NULL) {		    if (llcp->llc_dsap == sap->sap.sap[0])			    break;		    sap = sap->next_sap;	    }	    if (sap == NULL)		    return 0;    }    return 1;}/* * Strip the token ring addresses from the frame.  Also strip out the * route information and the LLC header. */STATIC mblk_t *tr_8022_rcvind(struct dl *dl, mblk_t *dp){    mblk_t		*bp;    dl_unitdata_ind_t	*ud;    tr_hdr_t		*trp ;    tr_llc_frm_hdr_t	*llcp ;    int			 rtelgth = 0 ;    ASSERT(dl->sap_len == 1);    ASSERT(dl->addr_len == 6);    trp = (tr_hdr_t *) dp->b_rptr ;    if (trp->src_addr[0] & SADDR_0_RTE_PRES)    {					/* has source route field */	rtelgth = trp->bl & RCF_0_LLLLL ;    }    llcp = (tr_llc_frm_hdr_t *) (dp->b_rptr + sizeof(*trp)-2 + rtelgth) ;    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    = 0 ;    bp->b_wptr += DL_UNITDATA_IND_SIZE;    memcpy(bp->b_wptr, trp->dst_addr, 6);    bp->b_wptr += 6 ;    *bp->b_wptr++ = llcp->llc_dsap ;    memcpy(bp->b_wptr+6, trp->src_addr, 6);    bp->b_wptr += 6 ;    *bp->b_wptr++ = llcp->llc_ssap ;    dp->b_rptr += sizeof(*trp)-2 + rtelgth + sizeof(tr_llc_frm_hdr_t) ;    linkb(bp, dp);    return bp;}/* * Data buffer contains the data part of an LLC frame.  Add the LLC * header and the token ring MAC header. */STATIC int tr_8022_mkhdr(struct dl *dl, unsigned char *dst,			  int datalen, struct sk_buff *skb){    tr_hdr_t		*trp ;    tr_llc_frm_hdr_t	*llcp ;    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;    }    /*     * Omit the router control field and turn off the source route     * bit in the source address.  This may or may not prove to     * be correct.     */    trp = (tr_hdr_t *) skb_push(skb, sizeof(tr_hdr_t)-2 + sizeof(*llcp));    trp->acf = 0x10 ;				/* canned */    trp->fcf = 0x40 ;				/* canned */    memcpy(trp->dst_addr, dst, 6);    memcpy(trp->src_addr, dl->ndev->dev->dev_addr, 6);    trp->src_addr[0] &= ~SADDR_0_RTE_PRES ;	/* no route */    llcp = (tr_llc_frm_hdr_t *) ( ((char *)(trp+1)) - 2 ) ;    llcp->llc_dsap = dsap ;    llcp->llc_ssap = dsap ;    llcp->llc_ctl[0] = 0x03 ;    return 1;}/* *  HDLC Raw */STATIC int hdlc_raw_want(struct dl *dl, unsigned char *fr, int len){	return 1;		/* take everything */}STATIC mblk_t *hdlc_raw_rcvind(struct dl *dl, mblk_t *dp){	mblk_t *bp;	dl_unitdata_ind_t *ud;	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 = 0;	ud->dl_dest_addr_offset = 0;	ud->dl_src_addr_length = 0;	ud->dl_src_addr_offset = 0;	ud->dl_group_address = 0;	bp->b_wptr += DL_UNITDATA_IND_SIZE;	linkb(bp, dp);	return bp;}STATIC int hdlc_raw_mkhdr(struct dl *dl, unsigned char *dst,			  int datalen, struct sk_buff *skb){	return 1;}/* *  FDDI 802.2 */STATIC int fddi_8022_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(0);	return 0;}STATIC mblk_t *fddi_8022_rcvind(struct dl *dl, mblk_t *dp){	ASSERT(0);	return NULL;}STATIC int fddi_8022_mkhdr(struct dl *dl, unsigned char *dst,			   int datalen, struct sk_buff *skb){	ASSERT(0);	return 0;}/* *  FDDI SNAP */STATIC int fddi_snap_want(struct dl *dl, unsigned char *fr, int len){	ASSERT(0);	return 0;}STATIC mblk_t *fddi_snap_rcvind(struct dl *dl, mblk_t *dp){	ASSERT(0);	return NULL;}STATIC int fddi_snap_mkhdr(struct dl *dl, unsigned char *dst,			   int datalen, struct sk_buff *skb){	ASSERT(0);	return 0;}/****************************************************************************//*  End of: Frame type support routines.                                    *//****************************************************************************//****************************************************************************//*                                                                          *//*  Receive side Linux socket driver interface routines.                    *//*                                                                          *//****************************************************************************/STATIC INLINE void dl_rcv_put(mblk_t *dp, struct dl *dl, int copy){	mblk_t *mp;	if (dp == NULL) {		if (copy == 0)			freeb(dp);		++dl->lost_rcv;		return;	}	if (copy != 0 && (dp = dupb(dp)) == NULL) {		++dl->lost_rcv;		ginc(net_rx_drp_cnt) ;		return;	}	ginc(net_rx_cnt) ;	if ((dl->flags & LDLFLAG_RAW) == 0) {		if ((mp = dl->rcvind(dl, dp)) == NULL) {			freeb(dp);			++dl->lost_rcv;			return;		}	} else		mp = dp;#if 1	/*	 * Insert in our read queue and send upstream from the read	 * service routine.  Do not do putnexts from interrupt level.	 */	if (canput(dl->rq)) {		putq(dl->rq, mp);		ginc(unitdata_q_cnt) ;	} else {		freemsg(mp);		ginc(unitdata_drp_cnt) ;		++dl->lost_rcv;	}#else	if (qsize(dl->rq) == 0 && canputnext(dl->rq)) {		if (ldl_debug_mask & LDL_DEBUG_UDIND)		    ldl_mp_data_dump("ldl_unitdata_ind", mp,				     ldl_debug_mask & LDL_DEBUG_ALLDATA) ;		putnext(dl->rq, mp);		ginc(unitdata_ind_cnt) ;	} else if (canput(dl->rq)) {		putq(dl->rq, mp);		ginc(unitdata_q_cnt) ;	} else {		freemsg(mp);		ginc(unitdata_drp_cnt) ;		++dl->lost_rcv;	}#endif}/* *  Our "interrupt" function * *  This is called from the Linux networking code whenever *  a packet comes in from the device. * *  It is not a real interrupt function as the driver has *  returned from the hardware interrupt when this is called. * *  For speed, we should avoid queueing the packet on our read *  queue AND use dupmsg() if the packet is to be sent upstream *  on more than one interface. But we cannot just putnext() our *  message and dupmsg() it later (upstreams modules may have *  changed or deallocated the message in the meantime). *  To get around this problem we defer the putnext() until *  we have done our first dupmsg() or we know that no dupmsg() *  is needed. *  But we can only avoid queueing if the read queue is empty; *  otherwise our M_PROTO message could go upstream before any *  M_PCPROTO messages queued on our read queue. */STATIC int rcv_func(struct sk_buff *skb,		    struct ldldev *dev, struct packet_type *pt){	mblk_t *dp;	struct dl *dl, *last = NULL;	struct sap *sap;#if 0	struct ethhdr *hdr = (struct ethhdr *)skb->mac.raw;#endif	unsigned char *fr_ptr, fr_buf[LDL_MAX_HDR_LEN];	int fr_len;	ASSERT(dev->type == ARPHRD_ETHER || dev->type == ARPHRD_LOOPBACK	       || dev->type == ARPHRD_IEEE802 || IS_ARPHRD_IEEE802_TR(dev)	       || dev->type == ARPHRD_HDLC);		/*	ARPHRD_FDDI	*/	fr_len = skb->tail - skb->mac.raw;	if ((dp = allocb(2 + fr_len, BPRI_LO)) != NULL) {		/*		 *  Prepare the data block.		 *  The header is removed later for those that do no want it.		 *  The two extra unused bytes makes the data more processor		 *  cache-efficient in the higher level protocols (at least for		 *  ethernet).		 */		dp->b_rptr = dp->b_wptr += 2;		dp->b_datap->db_type = M_DATA;		memcpy(dp->b_wptr, skb->mac.raw, fr_len);		fr_ptr = dp->b_rptr;		dp->b_wptr += fr_len;	} else { /* We still need the frame type for correct drop stats */		fr_ptr = &fr_buf[0];		fr_len = lis_min(skb->end - skb->mac.raw, LDL_MAX_HDR_LEN);		ASSERT(fr_len > 0);		memcpy(fr_buf, skb->mac.raw, fr_len);	}	if (ldl_debug_mask & LDL_DEBUG_RCV_FUNC)	    ldl_skbuff_dump("ldl_rcv_func: skb", skb, 			     ldl_debug_mask & LDL_DEBUG_ALLDATA) ;#ifdef KERNEL_2_1	dev_kfree_skb(skb);#else	dev_kfree_skb(skb, FREE_WRITE);#endif	if (ldl_debug_mask & LDL_DEBUG_RCV_FUNC)	    ldl_bfr_dump("ldl_rcv_func", fr

⌨️ 快捷键说明

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