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

📄 lat_hic.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)lat_hic.c	4.3	7/28/88";#endif/************************************************************************ *									* *			Copyright (c) 1988 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				* *									* *	Chung Wong - 1/7/88   First version.                            * *		Subroutines to provide transparent host initiated       * *              connection, with algorithm similar to the handling of   * *              ioctls LIOCINI, LIOCSOL, LIOCRES and LIOCCMD.           * *		Provision for LAT master.				* *                                                                      * ************************************************************************//*	lat_hic.c	0.0	12/11/84	*/#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/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/file.h"#include "../h/gnode.h"#include "../h/proc.h"#include "../net/if.h"#include "../net/netisr.h"#include "../netinet/in.h"#include "../netinet/if_ether.h"#include "../lat/lat.h"#include "../lat/lat_protocol.h"#include "../lat/lat_var.h"#include "../h/ioctl.h"#include "../h/tty.h"extern struct socket *lat_traceso;extern struct sclass *sclass[];extern struct sclass class1;extern struct ecb statable[];extern u_short reqid;extern int wakeup();extern caddr_t buildvchdr();extern struct lat_vc *newvc(), *findvc(); extern struct lat_vc *vc[]; extern struct lat_slot sl[];extern struct tty lata[];extern struct ecb statable[];extern struct sclass *sclass[];extern struct vc_start startvc;extern u_char slotsinuse;extern struct lat_counters latctrs;extern int nLAT1;extern struct hic_entity lat_obj[];struct mbuf *lat_hicres();/* * LAT host-initiated connection routines. */ /*  *		l a t _ h i c i n i  *  * Process initialization for LAT host-initiated connection   *  * Returns:		0 if success  *			error code if not  *  * Inputs:  *	paths		= Pointer to parameters (subj port, obj name/port)  *                       (in format: /dev/ttyxx:server_name:server_port)  *     pathlen 	= length of path name for subject port  *	unit		= index to "statable" (= minor device number)  *	cmdbyte		= LIOCINI command byte  */lat_hicini(paths,pathlen,unit,cmdbyte)char *paths;int pathlen,unit;u_char cmdbyte;{    struct hic_entity *lptr = &lat_obj[unit];    struct ecb *ecbp = &statable[unit];    int i;    /* return error if device busy    if ((ecbp->ecb_inuse & ECB_INUSE) || (lata[unit].t_addr))        return(EBUSY); */    lptr->status &= ~(HIC | MHIC);    if (cmdbyte != '\001') return (0);    /*     * if no objects specified, return     */    if (paths[pathlen-1] != ':') return(0);    /*      * save subject port name and length     */    paths[pathlen-1] = '\0';    if ((lptr->subj_portlen = pathlen - 1) > MAXNAM)         return(EADDRNOTAVAIL);    bcopy(paths, lptr->subj_port, pathlen);    paths[pathlen-1] = ':';    lptr->status |= SUBJPORT;    /*     * save object name     */    paths += pathlen;    if ((pathlen = lat_pathlen(paths)) == 1) return(0);    if (paths[pathlen-1] != ':') return(0);    if ((lptr->obj_namelen = pathlen - 1) > MAXNAM)        return(EADDRNOTAVAIL);    bcopy(paths, lptr->obj_name, pathlen-1);    lptr->obj_name[pathlen-1] = 0;    lptr->status |= OBJNAME;    /*     * save object port     */    paths += pathlen;    if ((pathlen = lat_pathlen(paths)) == 1) return(0);    if ((lptr->obj_portlen = pathlen - 1) > MAXNAM)        return(EADDRNOTAVAIL);    #ifdef LATMASTER    if (*paths == '.') /* latmaster */    {        char *hex, ch1, ch2;        paths++;        for (i=0; *paths!='.'; i++,paths++)         {            ch1 = *paths++;            ch2 = *paths;            if (ch1<='9') ch1 &= 0x0f;            else ch1 = (ch1 & 0x07) + 9;            if (ch2<='9') ch2 &= 0x0f;            else ch2 = (ch2 & 0x07) + 9;            lptr->obj_port[i] = (ch1 << 4) + ch2;        }        lptr->obj_port[i] = '\0';        lptr->obj_portlen = i;        lptr->status |= HOSTMASTER;    }     else#endif    {        bcopy(paths, lptr->obj_port, pathlen-1);        lptr->status |= OBJPORT;    }    ecbp->ecb_hostinit = LAT_HIC;    return(0);} /*  *		l a t _ h i c o p e n  *  * Process latopen request in case of host initiated connection  *  * Returns:		0 if success  *			error code if not  *  * Inputs:  *	unit		= index to "statable" (= minor[subj port])  */lat_hicopen(unit,tp)int unit;struct tty *tp;{    int s, err;    u_short solid;    struct hic_entity *h = &lat_obj[unit];    struct mbuf *m0,*m1;    struct solicit_1 *solptr;    struct response_1 *resptr;    struct ecb *ecbp = &(statable[unit]);    struct ifnet *ifp = ifnet;    struct proc *pp = u.u_procp;    /*     * if defined as master, return     */     if (h->status & HOSTMASTER) return(0);     /*     * check if host-initiated connection fully defined     */     if (ecbp->ecb_hostinit != LAT_HIC) return(0);     if (((h->status & HIC) != HIC)) return(EDESTADDRREQ);     /*     * LAT open should be exclusive, unless multiplexing added     */     if (ecbp->ecb_inuse & ECB_INUSE)     {         if (ecbp->ecb_inuse & ECB_NONHIC) return (0);         return(EBUSY);     }     if (tp->t_addr) return(EBUSY);    /*     * if lat not running, return error     */     if (class1.scl_state != LST_RUNNING) return(ENOPROTOOPT);     ecbp->ecb_inuse |= ECB_INUSE;     s = splnet();    /*     * For each network interface,  build solicit msg      * with object name, then wait for response.  Send     * command msg to the first server that responded.     */    while (ifp)    {	if ((ifp->if_flags & (IFF_BROADCAST|IFF_DYNPROTO|IFF_UP)) == (IFF_BROADCAST|IFF_DYNPROTO|IFF_UP))	{            if (!(m0 = m_get(M_DONTWAIT, MT_DATA)))	    {                err = ENOBUFS;                goto badret;	    }            m0->m_len = sizeof(struct solicit_1);            solptr = mtod(m0, struct solicit_1 *);            solptr->sol1_dstnodelen = h->obj_namelen;            bcopy(h->obj_name, solptr->sol1_dstnode, h->obj_namelen);            class1.scl_solicit(m0, ifp);            solid = *(u_short *)solptr->sol1_solid;            sleep(solptr->sol1_solid, TTIPRI);            /*             * get response msg             */            if (m1 = lat_hicres(solid))                goto gotres;	}	ifp = ifp->if_next;    }    err = EADDRNOTAVAIL;badret:    ecbp->ecb_inuse &= ~ECB_INUSE;    splx(s);    return (err);    gotres:    /*     * send command msg     */    err = lat_hiccmd(h,ifp,m1,unit);    if (!err) lata[unit].t_pgrp = pp->p_pgrp;    splx(s);    return (err);    }/* *		l a t _ h i c r e s * * Get response msg with matched id * * Returns:		mbuf with the response msg *			0 if no match found * * Inputs: *	solid		= id in the solicit msg * */struct mbuf *lat_hicres(solid)u_short solid;{    struct mbuf *n, *prev;    struct response_1 *res_que;    n = class1.scl_rmsg.q_head;    /*     * Find response information structure in response     * queue matching solicit ID of user structure     */    while (n) {        res_que = mtod(n, struct response_1 *);        if ( solid == *(u_short *)res_que->rs1_solid )        {	    if (n == class1.scl_rmsg.q_head)   	    {	        if ( (class1.scl_rmsg.q_head = n->m_act) == 0)		    class1.scl_rmsg.q_tail = 0;	    }	    else 	    {		if (n == class1.scl_rmsg.q_tail)		{		     class1.scl_rmsg.q_tail = prev;		     prev->m_act = 0;		}		else	             prev->m_act = n->m_act;	     }             return(n);         }	 else	 {	      prev = n;	      n = n->m_act;	 }    } /* while n */    /*     * response mas not found     */    return( (struct mbuf *) 0);}/* *		l a t _ h i c c m d * * Send command msg to request a connection * * Returns:		0 if success *			error code if not * * Inputs: *	h		= pointer to the hic_entity structure *	ifp		= pointer to the network interface structure *	m1		= pointer to mbuf with response msg *	unit		= index to "statable" (= minor[subj port]) */lat_hiccmd(h,ifp,m1,unit)struct hic_entity *h;struct ifnet *ifp;struct mbuf *m1;int unit;{    caddr_t commsg, dptr;    u_char u_len;    struct mbuf *m0, *cm;    struct response_1 *resptr = mtod(m1,struct response_1 *);    struct lat_cmd *commsgp;    struct lataddr objaddr;    struct ecb *ecbp = &(statable[unit]);    /*     * Copy Ethernet address of object node.     */    bcopy((caddr_t)resptr->rs1_srcnode,(caddr_t)objaddr.lat_addr,6);    objaddr.lat_family = AF_LAT;    m_freem(m1);    m0 = m_get(M_DONTWAIT,MT_DATA);    commsgp = mtod(m0,struct lat_cmd *);    /*     * Build command message header.     */    commsgp->lcm_type = MSG_CMD << 2;    commsgp->lcm_protofmt = 0;    commsgp->lcm_Hver = commsgp->lcm_Cver = LAT_VER;    commsgp->lcm_Lver = LAT_VER_LOW;    commsgp->lcm_eco = LAT_ECO;    *(u_short *)commsgp->lcm_framesize = LAT_FRAMESIZE;    *(u_short *)commsgp->lcm_reqid = reqid;    *(u_short *)commsgp->lcm_entryid = (u_short)0;    /*      *  set up command type and command modifier     */    if (lata[unit].t_state & TS_ONDELAY)     {	/* for no delay, get non-queue service */        commsgp->lcm_cmdtype = 1;        commsgp->lcm_cmdmod = 0;    }    else     {	/* queue service, with periodic return status */        commsgp->lcm_cmdtype = 2;        commsgp->lcm_cmdmod = 1;    }    commsg = (caddr_t)commsgp;    commsg += sizeof(struct lat_cmd);    /*     * object node name      */    u_len = h->obj_namelen;    *commsg++ = (char)h->obj_namelen;    bcopy(h->obj_name,commsg,(int)u_len);    commsg += u_len;    /*     * Add source node group identifier list, node name     * directly from class1.scl_dmsg     */    dptr = mtod(class1.scl_dmsg,caddr_t);    dptr = (caddr_t)dptr + sizeof(struct direct_1);    u_len = *commsg++ = *dptr++ ;    (void)bcopy((caddr_t)dptr,commsg,(int)u_len);    dptr += u_len, commsg += u_len;    u_len = *commsg++ = *dptr++;    (void)bcopy((caddr_t)dptr,commsg,(int)u_len);    commsg += u_len;			    /*     * subject port     */    u_len = h->subj_portlen;    *commsg++ = u_len;    bcopy(h->subj_port, commsg, (int)u_len);    commsg += u_len;    /*     * subject description =0,  object service = 0     */    *commsg++ = 0;    *commsg++ = 0;    /*     * object port     */    u_len = h->obj_portlen;    *commsg++ = u_len;    bcopy(h->obj_port, commsg, (int)u_len);    commsg += u_len;    /*     * null termination     */    *commsg++ = 0;    m0->m_len = (short)(commsg - (caddr_t)commsgp);    ecbp->ecb_cmdmsg = m0;    ecbp->ecb_reqid = *(u_short *)commsgp->lcm_reqid;    ecbp->ecb_if = ifp;    bcopy((caddr_t)objaddr.lat_addr, (caddr_t)(ecbp->ecb_addr.lat_addr),6);    ecbp->ecb_addr.lat_family = AF_LAT;    ecbp->ecb_statrecd = 0;    /*     * invoke network interface     */    if (lat_traceso)	ltt_trace(0,0,m0,objaddr.lat_addr);    if (cm = m_copy(m0,0,M_COPYALL))        (*ifp->if_output)(ifp,cm,&objaddr);    /*      * Increment reqid, which must not be 0.     */    reqid = ( (reqid == 0xffff) ? 1 : reqid + 1);    return(0);} /*  *		l a t _ p a t h l e n  *

⌨️ 快捷键说明

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