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

📄 dli_input.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
    if ( loop_msg[loop_sc++] != DLI_LBACK_FWD || loop_msg[loop_sc++] != NULL )    {	return(m);    }    CALL_TO_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity);    error = rcv->rcv_ifp->if_ioctl(rcv->rcv_ifp, SIOCRPHYSADDR, (caddr_t)&ifd);    RETURN_FROM_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity);    if ( (error)	|| (bcmp(ifd.current_pa, rcv->rcv_hdr.rcv_ether.ether_shost, DLI_EADDRSIZE) == 0) )    {		m_freem(m);		return(NULL);    }    /*     * log passive loopback initiated event if not already given for     * present node.     */    timer_active = NULL;    smp_lock(&lk_dli, LK_RETRY);    for( i = 0; i < DLI_MAX_LBTIMR; i++)    {	if ( (lback_timers[i].tval != 0) &&      		bcmp(rcv->rcv_hdr.rcv_ether.ether_shost, lback_timers[i].actv_addr, DLI_EADDRSIZE) == NULL )	{		lback_timers[i].tval = DLI_LBEVL_WAIT;		timer_active = 1;		break;	}    }    if ( ! timer_active && establish_event( &rcv->rcv_hdr.rcv_ether, rcv ) )    {	smp_unlock(&lk_dli);	log_event(rcv->rcv_ifp, DLI_EVLOP_LBINI);    }    else	smp_unlock(&lk_dli);    /*     * forward loopback message.     */    dst_addr.dli_family = AF_DLI;    dst_addr.dli_substructype = DLI_ETHERNET;    *(struct ether_pa *) dst_addr.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *) (loop_msg+loop_sc);    dst_addr.choose_addr.dli_eaddr.dli_protype = rcv->rcv_hdr.rcv_ether.ether_type;    loop_sc += (DLI_EADDRSIZE - sizeof(loop_sc));    INS16(loop_msg, loop_sc);    CALL_TO_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity);    rcv->rcv_ifp->if_output(rcv->rcv_ifp, m->m_next, &dst_addr);    RETURN_FROM_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity);    m_free(m);    return(NULL);}/* *		l o o p b a c k _ p t o p _ m s g * *		This routine processes Point to Point loopback messages.   * * Outputs:		mbuf chain given to driver if message to be forwared. *			returns NULL if message looped, otherwise mbuf pointer returned. * * Inputs:		m = mbuf chain containing packet.   *			mop = 1 if MOP, 0 if not MOP mode *			rcv = pointer to data link header structure. */struct mbuf *loopback_ptop_msg( m, mop, rcv )register struct mbuf *m;int mop;register struct dli_recv *rcv;{	u_char *mop_code;	u_short i;	int saveaffinity;  /* for nonsym drivers.  8.18.88.us  */	struct sockaddr_dl dst_addr;	/*	 * make sure device is currently looping; if so, reset loopback timer;	 * if not, packet belongs to a user.	 */	smp_lock(&lk_dli, LK_RETRY); 	for( i = 0; i < DLI_MAX_LBTIMR; i++) 	{		if ( (lback_timers[i].tval != 0) &&  (rcv->rcv_ifp == lback_timers[i].ifp) )		{			lback_timers[i].tval = DLI_LBEVL_POP;			break;		}     	}	smp_unlock(&lk_dli);	if ( i == DLI_MAX_LBTIMR && ! mop )	{		return(m);	}	/*	 * pull MOP code into second mbuf if not already there	 */	if ( ! pull_header(m, 1) )	{		return(NULL);	}	else if ( *(mop_code = mtod(m->m_next, u_char *)) == DLI_LBACK_LOOP )	{		/* free first mbuf which has no relevant data */		m = m_free(m);		/*		 * forward loopback message.		 */		dst_addr.dli_family = AF_DLI;		dst_addr.dli_substructype = DLI_POINTOPOINT;		*mop_code = (u_char) DLI_LBACK_LOOPED;		CALL_TO_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity);		rcv->rcv_ifp->if_output(rcv->rcv_ifp, m, &dst_addr);		RETURN_FROM_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity);		return(NULL);	}	else	{		return(m);	}}/* *		l o g _ e v e n t * *	This subroutine logs a passive loopback message to evl. * * Outputs:		None. * * Inputs:		None.   */log_event(ifp, evl_op)register struct ifnet *ifp;u_char evl_op;{    struct protosw *evl_ptr;    static struct event events[DLI_MAXPROC];#define event events[CURRENT_CPUDATA->cpu_num]    register int i;    /*     * log event only if evl is present     */    if ( ! (evl_ptr = pffindproto( AF_DECnet, DNPROTO_EVR )) )    {	return;    }    /*     * init event structure.     */    event.e_class = DLI_LBEVL_CLASS;    event.e_type = DLI_LBEVL_TYPE;    event.e_ent_type = DLI_LBEVL_ETYPE;    i = fetch_decnet_devname( ifp, event.e_ent_id );    event.e_ent_id[i++] = ifp->if_unit + '0';    event.e_ent_id[i] = NULL;    event.e_data[0] = DLI_EVLOP_CODE;    event.e_data[1] = NULL;    event.e_data[2] = DLI_EVLOP_DESC;    event.e_data[3] = evl_op;    event.e_data_len = 4;    /*     * log event     */    (evl_ptr->pr_input)( &event );    return;#undef event}/* *		s c m p * *	This subroutine compares two strings. * * Outputs:		0 if strings unequal, 1 if strings equal. * * Inputs:		s1, s2 = pointers to strings to be compared.   */scmp(s1, s2)register char *s1, *s2;{    while ( *s1 == *s2++ )	if ( *s1++ == NULL )		return(1);    return(0);}/* *		p u l l _ h e a d e r * *		This routine pulls up a header into the second mbuf.   * 		NOTE: first mbuf contains info placed by dli_ifinput. * * Outputs:		1 if successful, 0 if failure. * * Inputs:		m = mbuf chain containing packet.   *			hsiz = size of header to be pulled up. */pull_header( m, hsiz )register struct mbuf *m;register short hsiz;{    register int i = 0;    register struct mbuf *tm = m->m_next;    if ( hsiz <= m->m_next->m_len )	return(1);    while ( tm )    {	i += tm->m_len;	tm = tm->m_next;    }    if ( (m->m_next = m_pullup(m->m_next, ((i < hsiz) ? i : hsiz))) == NULL )    {	m_freem(m);	return(NULL);    }    return(1);}/* *		e s t a b l i s h _ e v e n t * *	This routine sets up a loopback event in the *	loopback timer table. * * Note:  DLI protocol lock must be asserted before this *	  routine is called. * * Inputs:		header = address of packet header.   *				 (zeroed out for point to point) *			rcv = pointer to data link header structure. * * Outputs:		1 if success, otherwise NULL. */establish_event( eh, rcv )register struct ether_header *eh;register struct dli_recv *rcv;{	int i = -1;	while (lback_timers[++i].tval != 0 && i < DLI_MAX_LBTIMR) ;	if ( i < DLI_MAX_LBTIMR )	{		lback_timers[i].tval = DLI_LBEVL_WAIT;		lback_timers[i].ifp = rcv->rcv_ifp;	     	*(struct ether_pa *) lback_timers[i].actv_addr = *(struct ether_pa *) eh->ether_shost;		return(1);	}	else	{		return(0);	}}/* *		f e t c h _ d e c n e t _ d e v n a m e * *	This routine translates the ULTRIX device name into the DECnet *	device name. * * Inputs:		dn_devname = pointer where DECnet device name is to  *					placed. * * Outputs:		dn_devname = DECnet device name. * * Returns:		number of characters in device name. * */fetch_decnet_devname( ifp, dn_devname )register struct ifnet *ifp;register u_char *dn_devname;{    register int i = 0;    if ( scmp(ifp->if_name, "qe") )    {	bcopy( "QNA-", dn_devname, (i = 4) );    }    else if ( scmp(ifp->if_name, "de") )    {	bcopy( "UNA-", dn_devname, (i = 4) );    }    else if ( scmp(ifp->if_name, "ni") )    {	bcopy( "BNT-", dn_devname, (i = 4) );    }    else if ( scmp(ifp->if_name, "xna") )    {        bcopy( "XNA-", dn_devname, (i = 4) );    }    else if ( scmp(ifp->if_name, "ln") )    {        bcopy( "SVA-", dn_devname, (i = 4) );    }    else if ( scmp(ifp->if_name, "dmc") )    {	bcopy( "DMC-", dn_devname, (i = 4) );    }    else if ( scmp(ifp->if_name, "dmv") )    {	bcopy( "DMV-", dn_devname, (i = 4) );    }    else    {	i = 0;	while ( ifp->if_name[i] )	{		dn_devname[i] = ifp->if_name[i];		if ( dn_devname[i] >= 'a' )			dn_devname[i] = dn_devname[i] - ('a' - 'A');		i++;	}	dn_devname[i++] = '-';    }    return(i);}#ifdef notdef/* *		m b u f _ l e n * * Compute the number of bytes in a (non-empty) MBUF chain. * * Returns:		The number of bytes in the chain. * * Inputs: *	m		= Pointer to the MBUF chain. */mbuf_len( m )register struct mbuf *m;{    register struct mbuf *m0 = m;    register int len = 0;	while( m0 )    {		len += m0->m_len;		m0 = m0->m_next;    }    return (len);}#endif/* *		d l i _ p r o c _ r e q s y s i d * * This routine is called to process requests for sysid  * If this is a request for a sysid from a node *    find the matching sysid_to struct to tx on *    copy requestor node address to the target *    transmit the sysid  * * Outputs:		None. * * Inputs:		pointer to mbuf chain from driver *              pointer to dli_recv structure. * * Version History: * 1.0	JA * */dli_proc_reqsysid(m, recv)struct mbuf *m;struct dli_recv *recv;{	register int i, nsiz = 0;	u_short msglen;        	/*    	 * If to multicast, make sure its the correct one.    	 */    	if ( recv->rcv_hdr.rcv_ether.ether_dhost[0] & MCASTADDR )		if (bcmp( recv->rcv_hdr.rcv_ether.ether_dhost, sysid_mcast, DLI_EADDRSIZE) != 0)		{			m_freem(m);			return;		}	msglen = EXT16(mtod(m->m_next, u_char *));	if ( msglen < 4 )	{		m_freem(m);		return;	}	while( *(((u_char *) recv->rcv_ifp->if_name)+nsiz) != NULL )		nsiz++;	i = -1;	while ( mop_dev_code[++i].devtyp )		if( bcmp(mop_dev_code[i].devnam, recv->rcv_ifp->if_name, nsiz) == 0 )		{			smp_lock(&lk_dli, LK_RETRY);			*(struct ether_pa *)sysid_dst.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *)recv->rcv_hdr.rcv_ether.ether_shost; 			dli_snd_sysid(recv->rcv_ifp, EXT16((mtod(m->m_next, u_char *) + 4)), mop_dev_code[i].devtyp);			*(struct ether_pa *)sysid_dst.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *) sysid_mcast; 			smp_unlock(&lk_dli);			break;		}	m_freem(m);}/* *		d l i _ p r o c _ r e q  c t r s * * This routine is called to process requests for data link counters  * * Outputs:		None. * * Inputs:		pointer to mbuf chain from driver *              	pointer to dli_recv structure. * * Version History: * 1.0	JA * */dli_proc_reqctrs(m, recv)struct mbuf *m;struct dli_recv *recv;{    struct ctrreq ctrs;    u_short receipt, msglen;    register u_char *bmsg, *msg = mtod(m, u_char *);    int saveaffinity;  /* for nonsym drivers.  8.18.88.us  */    int error;    struct sockaddr_dl dst_addr;    struct mbuf *recv_hdr;   /*    * If to multicast, make sure its the correct one.    */    if ( recv->rcv_hdr.rcv_ether.ether_dhost[0] & MCASTADDR )	if (bcmp(recv->rcv_hdr.rcv_ether.ether_dhost, sysid_mcast, DLI_EADDRSIZE) != 0)	{		m_freem(m);		return;	}    /*     * pull MOP message  into second mbuf if not already there     */    if ( ! pull_header(m, 5) )    {	return;    }    msglen = EXT16(mtod(m->m_next, u_short *));    if ( msglen < 3 )    {	m_freem(m);	return;    }    /*     * Save receipt from message and then delete remainder of message,     * saving one mbuf for transmission of counters.     */    receipt = EXT16((mtod(m->m_next, u_char *) + sizeof(u_short) + 1));    m_freem(m->m_next);    m->m_next = NULL;    CALL_TO_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity);    error = ( recv->rcv_ifp->if_ioctl(recv->rcv_ifp, SIOCRDCTRS, (caddr_t)&ctrs));    RETURN_FROM_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity);    if ( error )    {	m_freem(m);	return;    }    /*     * place counters in mbuf and transmit     */     bmsg = msg;     msg += sizeof(u_short);     *msg++ = DLI_CTRS;     INS16(msg, receipt);     msg += sizeof(u_short);     switch ( ctrs.ctr_type )     {	case CTR_ETHER:		/* ethernet device  - format counters */		INS16(msg, ctrs.ctr_ether.est_seconds);		msg += sizeof(ctrs.ctr_ether.est_seconds);		INS32(msg, ctrs.ctr_ether.est_bytercvd);		msg += sizeof(ctrs.ctr_ether.est_bytercvd);		INS32(msg, ctrs.ctr_ether.est_bytesent);		msg += sizeof(ctrs.ctr_ether.est_bytesent);		INS32(msg, ctrs.ctr_ether.est_blokrcvd);		msg += sizeof(ctrs.ctr_ether.est_blokrcvd);		INS32(msg, ctrs.ctr_ether.est_bloksent);		msg += sizeof(ctrs.ctr_ether.est_bloksent);		INS32(msg, ctrs.ctr_ether.est_mbytercvd);		msg += sizeof(ctrs.ctr_ether.est_mbytercvd);		INS32(msg, ctrs.ctr_ether.est_mblokrcvd);		msg += sizeof(ctrs.ctr_ether.est_mblokrcvd);		INS32(msg, ctrs.ctr_ether.est_deferred);		msg += sizeof(ctrs.ctr_ether.est_deferred);		INS32(msg, ctrs.ctr_ether.est_single);		msg += sizeof(ctrs.ctr_ether.est_single);		INS32(msg, ctrs.ctr_ether.est_multiple);		msg += sizeof(ctrs.ctr_ether.est_multiple);		INS16(msg, ctrs.ctr_ether.est_sendfail);		msg += sizeof(ctrs.ctr_ether.est_sendfail);		INS16(msg, ctrs.ctr_ether.est_sendfail_bm);		msg += sizeof(ctrs.ctr_ether.est_sendfail_bm);		INS16(msg, ctrs.ctr_ether.est_recvfail);		msg += sizeof(ctrs.ctr_ether.est_recvfail);		INS16(msg, ctrs.ctr_ether.est_recvfail_bm);		msg += sizeof(ctrs.ctr_ether.est_recvfail_bm);		INS16(msg, ctrs.ctr_ether.est_unrecog);		msg += sizeof(ctrs.ctr_ether.est_unrecog);		INS16(msg, ctrs.ctr_ether.est_overrun);		msg += sizeof(ctrs.ctr_ether.est_overrun);		INS16(msg, ctrs.ctr_ether.est_sysbuf);		msg += sizeof(ctrs.ctr_ether.est_sysbuf);		INS16(msg, ctrs.ctr_ether.est_userbuf);		msg += sizeof(ctrs.ctr_ether.est_userbuf);    		/*		 * Place message size at beginning, create dest addr,		 * and transmit		 */		m->m_len = (short) (msg - bmsg);     		INS16(bmsg, (u_short) (m->m_len - sizeof(u_short)));    		dst_addr.dli_family = AF_DLI;    		dst_addr.dli_substructype = DLI_ETHERNET;    		*(struct ether_pa *) dst_addr.choose_addr.dli_eaddr.dli_target = 			*(struct ether_pa *) recv->rcv_hdr.rcv_ether.ether_shost;    		dst_addr.choose_addr.dli_eaddr.dli_protype = recv->rcv_hdr.rcv_ether.ether_type;		break;     	case CTR_DDCMP:		/* point to point device */	default:		m_freem(m);		return;		break;    }    CALL_TO_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity);    recv->rcv_ifp->if_output(recv->rcv_ifp, m, &dst_addr);    RETURN_FROM_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity);    return;}

⌨️ 快捷键说明

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