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

📄 lat_vc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)lat_vc.c	4.1.1.5	7/15/88";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History				* *									* *	Larry Cohen  -	09/16/85					* * 	    Update to new protsw format, ethernet addr struct change	* *									* *	Jeff Chase   -  03/12/86                                        * *	    Modified to handle the new MCLGET macro			* *									* *	Peter Harbo  -  04/15/86					* *	    Addition of LAT 5.1 support for application terminals:      * *	    interpret response and status messages.  Place status	* *	    message errors in appropriate entry of statable[].	        * *									* *	Chung Wong - 1/7/88 						* *	    Add check on master bit for conformance.			* *	    Add checkhostname() and checkmastername() for conformance.  * *	    Add m_freem(m) before exiting process_status().		* *	    Add 'wakeup((caddr_t)&lata[j].t_rawq)' in process_status(). * *									* ************************************************************************//*	lat_vc.c	0.0	11/9/84	*//*	lat_vc.c	2.0	04/15/86 */#include "../h/param.h"#include "../h/systm.h"#include "../h/mbuf.h"#include "../h/protosw.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/errno.h"#include "../h/conf.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/file.h"#include "../h/ioctl.h"#include "../h/tty.h"#include "../net/if.h"#include "../netinet/in.h"#include "../netinet/if_ether.h"#include "../lat/lat.h"#include "../lat/lat_protocol.h"#include "../lat/lat_var.h"extern struct ifqueue latintrq;extern struct lat_vc *vc[];extern u_char rand;extern struct vc_start startvc;extern struct ifnet *rcvif;extern struct lataddr rcvaddr;extern struct lat_counters latctrs;extern struct tty lata[];extern struct mbuf *demux();extern struct sclass class1;extern struct ecb statable[];extern int nLAT1;extern struct socket *lat_traceso;extern lat_debug; /* latmaster */extern char lat_hostname[];extern int lat_hostnamelen;int latmnl;char *latmn;static struct vc_hdr vhdr;/* * LAT virtual circuit management. */struct lat_vc *findvc(),*newvc(),*duplicatevc();/* *		l a t i n t r * * LAT domain input routine. This routine is 'called' from the network software * ISR routine to process incoming packets. The first MBUF in any chain * contains a LAT receive descriptor containing the received ethernet header * and a pointer to the interface structure. * * Outputs:		None. * * Inputs:		None. */latintr(){    register struct mbuf *m;    register struct latrecv *recv;    register struct lat_vc *vcir;    int s;next:    /*     * Try to pull an input message (MBUF chain) from the LAT input queue.     */    s = splimp();    IF_DEQUEUE(&latintrq, m);    splx(s);    if (m)    {	recv = mtod(m, struct latrecv *);	rcvif = recv->rcv_ifp;	bcopy((char *)recv->rcv_hdr.ether_shost,		(char *)rcvaddr.lat_addr, sizeof(rcvaddr.lat_addr));	m = m_free(m);	if (m = LAT_PULLUP(m, sizeof(struct vc_hdr)))	{	    if (lat_traceso)		ltt_trace(1,0,m,rcvaddr.lat_addr);	    INC(lco_rcvframes);	    vhdr = *mtod(m, struct vc_hdr *);	    	    /*	     * Handle response and status messages apart	     * from virtual circuit messages.	     */	    switch (vhdr.vhd_type)	    {		case MSG_RESP:	            if ( m = LAT_PULLUP(m,sizeof(struct response_1)) )		        class1.scl_response(m);		    else		    {		        INC(lco_badmsg);		        m_freem(m);		    }		    goto next;                case MSG_STAT:		    if ( m = LAT_PULLUP(m,sizeof(struct lat_stat)) )			process_status(m);		    else		    {		        INC(lco_badmsg);			m_freem(m);		    }		    goto next;                case MSG_DR1:                case MSG_SOL:		    m_freem(m);		    goto next;	    }	            	    m_adj(m, sizeof(struct vc_hdr));                  /*	     * latmaster: check for START message and START SLOT. 	     * All other message and slots are processed the same 	     * way in either slave mode or master mode.	     */            if (vhdr.vhd_mas == 0)             {                if (vhdr.vhd_type == MSG_START)                {                    mvcstart1(m,&vhdr);                    goto next;                }                if (vhdr.vhd_type == MSG_RUN)                {                    struct slot_hdr *slothdr;                    m = LAT_PULLUP(m, sizeof(struct slot_hdr));                    slothdr = mtod(m, struct slot_hdr *);                    if (slothdr->shd_type == SLOT_START)                    {                        mslotstart(slothdr);                        m_freem(m);                        goto next;                    }                }             }	    switch (vhdr.vhd_type)	    {		/*		 * The run message contains slots which should be given to the		 * slot demultiplexor.		 */		case MSG_RUN:		    process_vc_run(m);		    goto next;		/*		 * The start message requests that a virtual circuit be started		 * or restarted.		 */		case MSG_START:		    process_vc_start(m);		    goto next;		/*		 * The stop message requests that a virtual circuit be stopped.		 */		case MSG_STOP:		    process_vc_stop(m);		    goto next;		/*		 * Unknown message - if we can find an associated virtual		 * circuit, stop all the slots and tear down the virtual		 * circuit otherwise just toss the message.		 */		default:                    goto proto_error;		/*  INC(lco_badmsg);		    if (vcir = findvc())		    {			terminatevc(vcir, STOP_BADFORMAT);		    }		    m_freem(m);		    goto next;   */	    }	}    }return;/* * Protocol error - if we can find an associated virtual * circuit, stop all the slots and tear down the virtual * circuit otherwise just toss the message. */proto_error:    INC(lco_badmsg);    if (vcir = findvc())	terminatevc(vcir, STOP_BADFORMAT);    m_freem(m);    goto next;}/* *			p r o c e s s _ v c _ r u n * * Process a received run message. * * Outputs:		None. * * Inputs: *	m		= Pointer to MBUF chain with the run message. */process_vc_run( m )struct mbuf *m;{    register struct lat_vc *vcir;    struct mbuf *m0;    int i,msgnum;    if (vcir = findvc())    {	/* 	 * latmastrer: save rrf indicator,          * in case of master balance mode          */        if (!vhdr.vhd_rrf) vcir->lvc_rcvact |= 0x40;        else vcir->lvc_rcvact &= 0x0bf;	if (vcir->lvc_state != VST_STARTING)	{	    /* make sure master bit is set correctly */            if (!lat_master(vcir))            {                if (vhdr.vhd_mas == 0) goto proto_error;            }            else                if (vhdr.vhd_mas == 1) goto proto_error;	    /*	     * If the message is out of sequence, effectively throw the data it	     * contains away by zeroing the slot count and increment the 	     * duplicate message counter, otherwise, increment the 	     * acknowledgement number.	     */	    if (vhdr.vhd_seq != ((vcir->lvc_ack + 1) & 0377))	    {		vhdr.vhd_slots = 0;		INC(lco_rcvdup);	    }	    else vcir->lvc_ack++;	    /*	     * Process the acknowledgement number from the message.	     */	    msgnum = (vhdr.vhd_ack - vcir->lvc_lxmt) & 0377;	    if (msgnum <= ((vcir->lvc_hxmt - vcir->lvc_lxmt) & 0377))	    {		for (i = 0; i < msgnum; i++)		{		    DEQUEUE(&vcir->lvc_ackq, m0);		    if (m0 == 0)			break;		    m_freem(m0);		    vcir->lvc_lxmt++;		}	    }	    /*	     * If there are no messages awaiting acknowledgement, we	     * can cancel the retransmission timer and allow further	     * transmissions.  */	    if (vcir->lvc_ackq.q_head == 0)	    {		vcir->lvc_timer = 0;		vcir->lvc_rrf = 0;	    }	    else 	    {		rxmit_ackq(vcir);		if (lat_master(vcir))	/* latmaster waits for empty ackq */		    vcir->lvc_rcvact |= 0x40;	    }	    /*	     * If there are any slots present in the message hand them to the	     * slot demultiplexor.	     */	    if (vhdr.vhd_slots)		m = demux(vcir, m, (int)vhdr.vhd_slots);	    if ( !vc[vhdr.vhd_dstid & 0377] )		goto freembuf;	    /*	     * If we are trying to stop this virtual circuit, and there are no	     * messages awaiting transmission or acknowledgement we can stop it	     * now.	     */	    if ((vcir->lvc_state == VST_STOPING) && (vcir->lvc_ackq.q_head == 0) && (vcir->lvc_xmtq.q_head == 0))	    {		freevc(vcir, STOP_NOSLOTS);	    }	    else 		/* 	  	 * latmaster: slave always acknowledges 		 * the last message even when rrf not set.		 */                if (!lat_master(vcir) || !(vcir->lvc_rcvact & 0x40) ||                     ((vcir->lvc_rcvact&0x80) && vcir->lvc_ackq.q_head==0))                    vcrun(vcir); 	}	else latsend(vcir);    }freembuf:    m_freem( m );    return;proto_error:    INC(lco_badmsg);    terminatevc(vcir, STOP_BADFORMAT);    m_freem(m);}/* *		p r o c e s s _ v c _ s t a r t * * Process a received start message. * * Outputs:		None. * * Inputs: *	m		= Pointer to MBUF chain with the start message. */process_vc_start( m )struct mbuf *m;{    register struct lat_vc *vcir;    register struct vc_start *vst;    int reason = 0;    int vcstartlen = m->m_len;    struct mbuf *m0 = m->m_next;    while (m0) {        vcstartlen += m0->m_len;        m0 = m0->m_next;    }    if (m = LAT_PULLUP(m, vcstartlen))    {	vst = mtod(m, struct vc_start *);	if (vhdr.vhd_srcid != 0) 	{	    if ((vhdr.vhd_dstid == 0) && checkhostname(vst) && checkmastername(vst))	    {		if (vst->vst_pver >= LAT_VER)		{		    if (vcir = duplicatevc()) 		    {                        if (vcir->lvc_state == VST_STARTING)			    vcstart(vcir);                        else                            reason = STOP_BADFORMAT;		    }		    else		    {			if (vcir = newvc())			{			    vcir->lvc_dgsize = vst->vst_dgsize < CLBYTES ? vst->vst_dgsize : CLBYTES;			    vcir->lvc_remid = vhdr.vhd_srcid;			    vcir->lvc_kalive = vst->vst_kalive;			    vcstart(vcir);			}			else reason = STOP_NORESOURCE;		    }		}		else reason = STOP_BADFORMAT;	    }	    else reason = STOP_BADFORMAT;	}	m_freem(m);	if (reason)	{            if (reason == STOP_BADFORMAT)                 INC(lco_badmsg);	    vcstop(rcvif, vhdr.vhd_dstid, vhdr.vhd_srcid, reason);	}    }}/* *		p r o c e s s _ v c _ s t o p * * Process a received stop message. * * Outputs:		None. * * Inputs: *	m		= Pointer to MBUF chain with the stop message. */process_vc_stop( m )struct mbuf *m;{    register struct lat_vc *vcir;    if (vcir = findvc())    {	terminatevc(vcir, 0);    }    m_freem(m);}/*		p r o c e s s _ s t a t u s * * Process an incoming status message. * * Outputs:		None. * * Inputs: *		m =	Mbuf containing status message. */process_status(m)struct mbuf *m;{    struct lat_stat *statp;    int entries, namelen, i, j;    struct lat_statent *ent;    /*     * Strip off status message header, subject node name.     */    statp = mtod(m,struct lat_stat *);    entries = (int)statp->lstat_entries;    namelen = (int)statp->lstat_nodenamlen;    /* The name field is padded to an even number of bytes.     */    if (namelen % 2)	namelen++;    m_adj(m,sizeof(struct lat_stat));    m_adj(m,namelen);        /*     * For each entry in status message, if there is an error, place in     * entry control block for the lta associated with that reqid.     */    for(;entries;entries--)    {	if ( m = LAT_PULLUP(m,sizeof(struct lat_statent)) )	{	    ent = mtod(m,struct lat_statent *);	    for ( j = 0; ; j++ )	    {		if (j <= nLAT1)		{		    if (statable[j].ecb_reqid == ent->lent_reqid)		        break;		}		else	        {		    m_freem(m);		    return;	        }            }	    statable[j].ecb_statrecd = 1;	    statable[j].ecb_entryid = ent->lent_entryid;	    wakeup((caddr_t)&lata[j].t_rawq);			    	    if ( ent->lent_stat & 0200 )	    {		switch (ent->lent_err)		{		    case STOP_SLDISC:		    case STOP_SLNOSTART:			    statable[j].ecb_error = ECONNABORTED;			    break;

⌨️ 快捷键说明

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