📄 lat_scl1.c
字号:
#ifndef lintstatic char *sccsid = "@(#)lat_scl1.c 4.1.1.9 6/27/88";#endif lint/************************************************************************ * * * Copyright (c) 1984, 1986, 1987 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 * * * * Peter Harbo - 4/15/86 * * Added routines to send solicit info, retrieve response * * information messages (both called by LAT socket ioctls),* * changes to newslot() to accept new 5.1 start format. * * * * Chung Wong - 7/17/87 * * Added '*dptr++ = 0' in sdatab_class1() to ensure packet * * end with 0's. * * * * Tim Burke - 12/1/87 * * Changed to examine parameters in termios data structure.* * Look for start and stop character in termios t_cc. * * * * Chung Wong - 1/7/88 * * Added 'wakeup(sol->sol1_solid)' for host initiated * * connection. * * Changed solicit timer to individual device based, using * * storage after the data in the solicit mbuf. * * When start a new slot, check for specific service and * * save object and subject port names. * * In sdatab_class1(), send disable flow control when in * * RAW mode or flow control characters are not ^S/^Q. Also * * added break signal bit when requested. TTY speeds also * * sent to the DECserver (the existing DECserver does not * * yet set port speeds, though). * * * * Chung Wong - 6/15/88 * * For service rating, check if terminal is available for * * the service. If not, set service rating to 1. * * * ***********************************************************************/ /* lat_scl1.c 2.0 4/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/proc.h"#include "../h/ioctl.h"#include "../h/file.h"#include "../h/tty.h"#include "../net/if.h"#include "../netinet/in.h"#include "../netinet/if_ether.h"#include "../vax/cpu.h"#include "../lat/lat.h"#include "../lat/lat_protocol.h"#include "../lat/lat_var.h"extern struct lataddr LATmcast;extern struct sclass *sclass[];extern struct ecb statable[];extern int nLAT1;extern struct tty lata[];extern u_short mtimer;extern u_short soltimer, solxmit;extern u_char slotsinuse;extern struct socket *lat_traceso;extern struct hic_entity lat_obj[]; extern struct lat_service lat_service[]; extern int lat_debug; /* latmaster */int ttrstrt(),direct_class1(),solicit_class1(),response_class1(), new_class1(),rdataa_class1(),rdatab_class1(),rother_class1(), sdataa_class1(),sdatab_class1(),sother_class1(),hangup_class1();/* * LAT service class 1 support routines. *//* * Service class 1 definition structure. */struct sclass class1 = { LST_OFF, direct_class1, solicit_class1, response_class1, new_class1, rdataa_class1, rdatab_class1, rother_class1, sdataa_class1, sdatab_class1, sother_class1, hangup_class1 };/* * Processor rating weight indexed by processor type. */static u_char weight[VAX_MAX+1] = { 12, /* ??? */ 12, /* 11/780 */ 16, /* 11/750 */ 32, /* 11/730 */ 12, /* ??? */ 12, /* ??? */ 12, /* ??? */ 32, /* MicroVax I */ 16 /* MicroVax II */ };static int class1_rating = 256;static u_short solid; /* Solicitation information msg ID number *//* * d i r e c t _ c l a s s 1 * * Modify the directory message stored in the class 1 structure (if any) * and transmit it. * * Outputs: None. * * Inputs: * ifp = Pointer to network interface descriptor. */direct_class1( ifp )struct ifnet *ifp;{ struct mbuf *m; int services,rate = 2,serviceid,serviceid1,available,i; register struct direct_1 *dir; register caddr_t dptr; if (class1.scl_dmsg) { dir = mtod(class1.scl_dmsg, struct direct_1 *); dir->dr1_type = MSG_DR1 << 2; dir->dr1_Hver = dir->dr1_Lver = dir->dr1_Cver = LAT_VER; dir->dr1_eco = LAT_ECO; *(u_short *)dir->dr1_framesize = LAT_FRAMESIZE; dir->dr1_nodetimer = mtimer; dptr = (caddr_t)((int)dir + sizeof(struct direct_1)); /* * skip over the node groups, the node name and the node description. */ dptr += *dptr++; dptr += *dptr++; dptr += *dptr++; if (services = *dptr++) { /* * Compute the rating for this node. */ if (cpu <= VAX_MAX) { rate = weight[cpu]; } rate = 255 - (rate * avenrun[0]); rate = rate > 0 ? rate : 1; /* if (rate != class1_rating) */ { class1_rating = rate; dir->dr1_change ^= CHA_SRVRAT; dir->dr1_inc++; } /* * scan the services filling in the current service rating. */ serviceid = 0; while (services--) { available = 0; serviceid1 = serviceid; if (serviceid) serviceid1 += LAT_SERVICEID - 1; /* * check if at least one terminal available for this service */ for (i = 0; i <= nLAT1; i++) { if (lata[i].t_addr == 0 && (lata[i].t_state & TS_WOPEN) && statable[i].ecb_hostinit == serviceid1) { available++; break; } } serviceid++; /* if no terminal available, set service rating to 1 */ *dptr++ = available ? class1_rating : 1; dptr += *dptr++; dptr += *dptr++; } } if (m = m_copy(class1.scl_dmsg, 0, M_COPYALL)) { if (lat_traceso) ltt_trace(0,0,m,LATmcast.lat_addr); (*ifp->if_output)(ifp, m, &LATmcast); } }}/* * s o l i c i t _ c l a s s 1 * * Modify the solicit information message stored in the mbuf and * transmit it. * * Outputs: None. * * Inputs: * m = mbuf containing solicit information message. * ifp = pointer to network interface structure. * */solicit_class1(m,ifp)struct mbuf *m;struct ifnet *ifp;{ register struct solicit_1 *sol; register caddr_t solptr, dirptr; struct que *solque; struct mbuf *sm; u_char len; /* * Build an up-to-date Solicit information message. * An ioctl() has already placed a solicit_1 struct in * the class_1 structure. */ sol = mtod(m, struct solicit_1 *); sol->sol1_type = MSG_SOL << 2; sol->sol1_protofmt = 0; sol->sol1_Hver = sol->sol1_Cver = LAT_VER ; sol->sol1_Lver = LAT_VER_LOW ; sol->sol1_eco = LAT_ECO ; *(u_short *)sol->sol1_framesize = LAT_FRAMESIZE; *(u_short *)sol->sol1_solid = solid++; *(u_short *)sol->sol1_resptimer = LAT_RESPTIMER ; solptr = (caddr_t)&(sol->sol1_dstnodelen); /* * Skip over destination node name and length */ solptr += *solptr++; /* * Add source node group identifier list, node name directly from * class1.scl_dmsg */ dirptr = mtod(class1.scl_dmsg,caddr_t); dirptr = (caddr_t)dirptr + sizeof(struct direct_1); len = *solptr = *dirptr ; solptr++, dirptr++; (void)bcopy((caddr_t)dirptr,(caddr_t)solptr,(int)len); dirptr += len; solptr += len; len = *solptr = *dirptr; solptr++, dirptr++; (void)bcopy((caddr_t)dirptr,(caddr_t)solptr,(int)len); solptr += len; /* * No services supported in this msg. */ *solptr++ = 0; /* * No parameters. */ *solptr++ = 0; m->m_len = (short)(solptr - (caddr_t)sol); *solptr++ = LAT_SOLTIMER * 2; *solptr++ = LAT_SOLXMIT; if (lat_traceso) ltt_trace(0,0,m,LATmcast.lat_addr); if (sm = m_copy(m,0,M_COPYALL)) { (*ifp->if_output)(ifp,sm,&LATmcast); } solque = &(class1.scl_smsg); ENQUEUE(solque,m); /* soltimer is used to clean up response queue, see lat_slowtimo() */ soltimer = LAT_SOLTIMER * 2 * LAT_SOLXMIT + 2;} /* solicit_1 *//* * * r e s p o n s e _ c l a s s 1 * * Match the incoming message to a solicit info message on the queue and * place in the response queue. * * Outputs: None. * * Inputs: * m = Incoming response message. */response_class1(m)struct mbuf *m;{ struct response_1 *res,*start; struct solicit_1 *sol; struct mbuf *n, *prev, *p; struct que *resque; res = mtod(m,struct response_1 *); n = class1.scl_smsg.q_head; while ( n ) { sol = mtod(n,struct solicit_1 *); /* * Solicit ID matches solicit ID in queue. */ if (*(u_short *)sol->sol1_solid == *(u_short *)res->rs1_solid) { if (n == class1.scl_smsg.q_head) { if ( (class1.scl_smsg.q_head = n->m_act) == 0) class1.scl_smsg.q_tail = 0; } else { if (n == class1.scl_smsg.q_tail) { class1.scl_smsg.q_tail = prev; prev->m_act = 0; } else prev->m_act = n->m_act; } resque = &(class1.scl_rmsg); if (n->m_type != MT_FREE) m_freem(n); /* * If the first message on the queue is more than * 10 messages behind the one that just came in, drop it * (limit the queue to ten mbufs). */ if (class1.scl_rmsg.q_head) { start = mtod(class1.scl_rmsg.q_head,struct response_1 *); if (*(u_short *)start->rs1_solid + 10 < *(u_short *)res->rs1_solid) { DEQUEUE(resque,p); m_freem(p); } } ENQUEUE(resque,m); wakeup(sol->sol1_solid); return; } else /* not found */ { prev = n; n = n->m_act; } } /* while */ /* * The incoming response message was not solicited. * Free associated mbufs. */ if (m) m_freem(m);}/* * n e w _ c l a s s 1 * * Allocate service class dependent resources for a new slot. * * Outputs: Pointer to service class dependent data structure * 0 if no resources. * * Inputs: * vcir = Pointer to virtual circuit descriptor. * slot = Pointer to slot descriptor. * sst = Pointer to slot start. * reason = Reason code for failure to open LAT tty. *//*ARGSUSED*/new_class1( vcir,slot,sst,reason,shd_count)struct lat_vc *vcir; struct lat_slot *slot; struct slot_start *sst;int *reason; u_char shd_count;{ int i; short shd_length; u_short req; caddr_t sst_ptr; char *servname,*destname=0,*portname=0; int servnamelen, servid; struct lat_service *ls = &lat_service[0]; struct hic_entity *lp; int dstnamecnt, portnamecnt; /* Skip over slot_start structure, save object service and * skip subject node descriptions. */ sst_ptr = (caddr_t)((int)sst + (sizeof(struct slot_start))); shd_length = shd_count - (sizeof (struct slot_start)); servnamelen = *sst_ptr; servname = sst_ptr + 1; shd_length -= (*sst_ptr + 1); sst_ptr += *sst_ptr++; shd_length -= (*sst_ptr + 1); sst_ptr += *sst_ptr++; /* If a request ID is present (parameter 2), then allocate LAT * terminal requested in statable[] entry */ for (req = 0;shd_length > 0;) { if ( *sst_ptr == '\002' ) { sst_ptr += 2; req = *(u_short *)sst_ptr; break; } else { if ( ( *sst_ptr == '\000' ) || ( *sst_ptr > 7 ) ) { break; } else { if ( *sst_ptr == '\004' ) destname = sst_ptr; /* save object port name */ if ( *sst_ptr == '\005' ) portname = sst_ptr; /* save source port name */ sst_ptr++; shd_length -= (*sst_ptr + 1); sst_ptr += *sst_ptr++; continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -