📄 lat_vc.c
字号:
case STOP_SLSHUT: statable[j].ecb_error = ESHUTDOWN; break; case STOP_SLINVSLOT: statable[j].ecb_error = EMSGSIZE; break; case STOP_SLINVSERV: statable[j].ecb_error = ENODEV; break; case STOP_SLNORES: statable[j].ecb_error = EPROCLIM; break; case STOP_SLINUSE: statable[j].ecb_error = EBUSY; break; case STOP_SLNOSUCH: case STOP_SLDISABLED: statable[j].ecb_error = EADDRNOTAVAIL; break; case STOP_SLNOTOFF: statable[j].ecb_error = ENXIO; break; case STOP_SLNAME: case STOP_SLDELETE: statable[j].ecb_error = ENOENT; break; case STOP_SLPASSWD: case STOP_SLCORRUPT: case STOP_SLILLEGAL: case STOP_SLREQPAR: statable[j].ecb_error = EINVAL; break; case STOP_SLQUEUE: statable[j].ecb_error = ESPIPE; break; case STOP_SLREJ: case STOP_SLDENIED: statable[j].ecb_error = EACCES; break; /* * If an illegal error is received, return a generic * access error. */ default: statable[j].ecb_error = EACCES; break; } /* switch */ ttyflush(&lata[j],FREAD | FWRITE); } /* if */ } else { m_freem(m); return; } } m_freem(m); }/* * f i n d v c * * Find the virtual circuit defined by the LAT header on an incoming message. * * Outputs: Pointer to the virtual circuit descriptor * 0 if none. * * Inputs: None. */struct lat_vc *findvc(){ register struct lat_vc *vcir; register u_short remid = 0; int index = vhdr.vhd_dstid & 0377; if (index < LAT_MAXVC) { if (vcir = vc[index]) { if (vhdr.vhd_type != MSG_STOP) { remid = vcir->lvc_remid; } else remid = vhdr.vhd_srcid; /* srcid should be 0, just to be sure */ if ((vcir->lvc_locid == vhdr.vhd_dstid) && (remid == vhdr.vhd_srcid)) { return (vcir); } } } return (0);}/* * d u p l i c a t e v c * * Determine if the start message just received is a duplicate for an already * active virtual circuit. * * Outputs: Pointer to the duplicate virtual circuit * 0 if virtual circuit does not already exist. * * Inputs: None. */struct lat_vc *duplicatevc(){ register struct lat_vc *vcir; register int index; for (index = 1; index < LAT_MAXVC; index++) { if (vcir = vc[index]) { if (vhdr.vhd_srcid == vcir->lvc_remid) { if (bcmp(rcvaddr.lat_addr, vcir->lvc_addr.lat_addr, 6) == 0) { return (vcir); } } } } return (0);}/* * f r e e v c * * Attempt to send a stop virtual circuit message and then release the data * structures associated with the specified virtual circuit. * * Outputs: None. * * Inputs: * vcir = Pointer to the virtual circuit descriptor. * reason = Reason code for the stop virtual circuit message. * ( 0 if no need to send message ). */freevc( vcir,reason )register struct lat_vc *vcir;int reason;{ register struct mbuf *m; /* * Release any messages waiting to be sent. */ while (vcir->lvc_xmtq.q_head) { DEQUEUE(&vcir->lvc_xmtq, m); m_freem(m); } /* * Release any messages waiting for acknowledgement. */ while (vcir->lvc_ackq.q_head) { DEQUEUE(&vcir->lvc_ackq, m); wakeup(m); /* latmaster */ m_freem(m); } if (reason) { if (lat_master(vcir)) /* latmaster */ { register struct vc_hdr *hdr; register caddr_t ptr; if (m = m_get(M_DONTWAIT, MT_DATA)) { m->m_off = LATOFFSET; hdr = mtod(m, struct vc_hdr *); hdr->vhd_rrf = 0; hdr->vhd_mas = 1; hdr->vhd_type = MSG_STOP; hdr->vhd_slots = 0; hdr->vhd_dstid = vcir->lvc_remid; hdr->vhd_srcid = 0; hdr->vhd_seq = vcir->lvc_nxmt; hdr->vhd_ack = vcir->lvc_ack; ptr = (caddr_t)hdr + sizeof(struct vc_hdr); *ptr++ = reason; *ptr++ = 0; m->m_len = (int)ptr - (int)hdr; INC(lco_xmtframes); if (lat_traceso) ltt_trace(0,0,m,(vcir->lvc_addr).lat_addr); (*vcir->lvc_if->if_output)(vcir->lvc_if, m, &vcir->lvc_addr); } } else vcstop(vcir->lvc_if, vcir->lvc_locid, vcir->lvc_remid, reason ); } vc[vcir->lvc_locid & 0377] = 0; m_free(dtom(vcir));}/* * n e w v c * * Allocate the resources required for a new virtual circuit and link them * into the LAT virtual circuit table. * * Outputs: Pointer to the virtual circuit descriptor * 0 if no resources available. * * Inputs: None. */struct lat_vc *newvc(){ register int index; register struct mbuf *m; register struct lat_vc *vcir; for (index = 1; index < LAT_MAXVC; index++) { if (vc[index] == 0) { if (m = m_getclr(M_DONTWAIT, MT_PCB)) { vcir = mtod(m, struct lat_vc *); vcir->lvc_state = VST_STARTING; vcir->lvc_locid = (rand++ << 8) + index; vcir->lvc_lxmt = 0377; vcir->lvc_addr = rcvaddr; vcir->lvc_if = rcvif; vcir->lvc_mnl = latmnl; bcopy(latmn, vcir->lvc_mn, latmnl); vc[index] = vcir; return (vcir); } break; } } return (0);}/* * t e r m i n a t e v c * * Terminate the operation of a virtual circuit by first stopping all of the * slots which are active on the virtual circuit, sending a stop message (if * required) and releasing the virtual circuit descriptor. * * Outputs: None. * * Inputs: * vcir = Pointer to the virtual circuit descriptor. * reason = Reason code for the stop message * 0 if no stop message required. */terminatevc( vcir,reason )struct lat_vc *vcir;int reason;{ stopslots(vcir); freevc(vcir, reason);}/* * b u i l d v c h d r * * Build a LAT virtual circuit header in a buffer. * * Outputs: Pointer past the virtual circuit header. * * Inputs: * vcir = Pointer to the virtual circuit descriptor. * hdr = Pointer to header template. * slots = Number of slots in the message. * msgtype = Message type. * rrf = Value for rrf flag. */caddr_t buildvchdr( vcir,hdr,slots,msgtype,rrf )register struct lat_vc *vcir;register struct vc_hdr *hdr;int slots,msgtype,rrf;{ hdr->vhd_rrf = rrf; hdr->vhd_mas = 0; if (lat_master(vcir)) hdr->vhd_mas = 1; /* latmaster */ hdr->vhd_type = msgtype; hdr->vhd_slots = slots; hdr->vhd_dstid = vcir->lvc_remid; hdr->vhd_srcid = vcir->lvc_locid; hdr->vhd_seq = vcir->lvc_nxmt; vcir->lvc_hxmt = vcir->lvc_nxmt++; return ((caddr_t)hdr + sizeof(struct vc_hdr));}/* * v c r u n * * Try to build and send a run message. * * Outputs: None. * * Inputs: * vcir = Pointer to virtual circuit descriptor. */vcrun( vcir )register struct lat_vc *vcir;{ register struct mbuf *m,*pm,*page; int slots; if (vcir->lvc_rrf == 0) { vcir->lvc_resource = 0; if (m = m_get(M_DONTWAIT, MT_DATA)) { if (pm = m_get(M_DONTWAIT, MT_DATA)) { MCLGET(pm,page); if (page) { pm->m_len = 0; m->m_off = MMINOFF + LATOFFSET; m->m_next = pm; slots = buildslots(vcir, pm); if (slots == 0) { m->m_next = 0; m_free(pm); if (lat_master(vcir)) /* latmaster */ /* * do not send if balanced mode */ if (vcir->lvc_rcvact & 0x40) { m_freem(m); return; } } (void)buildvchdr(vcir, mtod(m, struct vc_hdr *), slots, MSG_RUN, (int)vcir->lvc_rrf); m->m_len = sizeof(struct vc_hdr); INC(lco_xmtframes); /* debug */ ENQUEUE(&vcir->lvc_xmtq, m); latsend(vcir); return; } m_free(pm); } m_free(m); } /* * Start resource recovery timer. */ vcir->lvc_resource = LAT_RTIMER; }}/* * v c s t a r t * * Try to send a start message in response to a received start message. * * Outputs: None. * * Inputs: * vcir = Pointer to virtual circuit descriptor. */vcstart( vcir )register struct lat_vc *vcir;{ register struct mbuf *m,*page; register caddr_t sptr,nptr; char ch; if (m = m_get(M_DONTWAIT, MT_DATA)) { MCLGET(m,page); if (page) { vcir->lvc_state = VST_RUNNING; sptr = buildvchdr(vcir, (struct vc_hdr *)page, 0, MSG_START, 0); bcopy((char *)&startvc, (char *)sptr, sizeof(struct vc_start)); sptr += sizeof(struct vc_start); if (*sptr++ = lat_hostnamelen) { nptr = lat_hostname; while (ch = *nptr++) { if (('a' <= ch) && (ch <= 'z')) ch = ch -'a' + 'A'; *sptr++ = ch; } } /* * Fill in a null system name and location. */ *sptr++ = 0; *sptr++ = 0; /* * Terminate the parameters. */ *sptr++ = 0; m->m_len = (int)sptr - (int)page; INC(lco_xmtframes); ENQUEUE(&vcir->lvc_xmtq, m); latsend(vcir); return; } m_free(m); }}/* * v c s t o p * * Try to build and send a virtual circuit stop message. * * Outputs: None. * * Inputs: * latif = Network interface to use. * srcid = Virtual circuit source id. * dstid = Virtual circuit destination id. * reason = Stop reason code. */vcstop( latif,srcid,dstid,reason )struct ifnet *latif;u_short srcid,dstid;int reason;{ register struct mbuf *m; register struct vc_hdr *hdr; register caddr_t ptr; if (m = m_get(M_DONTWAIT, MT_DATA)) { struct lat_vc *vcir; m->m_off = LATOFFSET; hdr = mtod(m, struct vc_hdr *); hdr->vhd_rrf = 0; hdr->vhd_mas = 0; hdr->vhd_type = MSG_STOP; hdr->vhd_slots = 0; hdr->vhd_dstid = dstid; hdr->vhd_srcid = 0; if (vcir = vc[srcid & 0377]) { hdr->vhd_seq = vcir->lvc_nxmt; hdr->vhd_ack = vcir->lvc_ack; } else hdr->vhd_seq = hdr->vhd_ack = 0; ptr = (caddr_t)hdr + sizeof(struct vc_hdr); *ptr++ = reason; *ptr++ = 0; m->m_len = (int)ptr - (int)hdr; INC(lco_xmtframes); if (lat_traceso) ltt_trace(0,0,m,rcvaddr.lat_addr); (*latif->if_output)(latif, m, &rcvaddr); }}/* * * c h e c k h o s t n a m e * * check to match host name * * Output: 1: host name matched * 0: host name not matched * * Input: * vst = Pointer to VC_START message */checkhostname(vst)char *vst;{ char *p = vst + sizeof(struct vc_start); int slavenamelen = (int)*p++; char *slave_name = p, *host_name = lat_hostname, s, h; if (slavenamelen > lat_hostnamelen) slavenamelen = lat_hostnamelen; if (slavenamelen != lat_hostnamelen) return (0); while (slavenamelen--) { h = *host_name, s = *slave_name; if (h != s) if ((h >= 'a' && h <= 'z' && ((h - 0x20) != s)) || (h >= 0x0e0 && h <= 0x0ff && ((h - 0x20) != h))) if ((s >= 'a' && s <= 'z' && ((s - 0x20) != h)) || (s >= 0x0e0 && s <= 0x0ff && ((s - 0x20) != h))) return (0); slave_name++, host_name++; } return (1);}/* * * c h e c k m a s t e r n a m e * * check for valid master name * * Output: 1: valid master name * 0: invalid master name * * Input: * vst = Pointer to VC_START message */checkmastername(vst)u_char *vst;{ u_char *p = vst + (u_char)sizeof(struct vc_start); int masternamelen = (int)*p++; p += masternamelen; /* skip slave name field */ masternamelen = (int)*p++; if (!masternamelen) return (0); latmnl = masternamelen; latmn = (char *)p; /* save for later */ for ( ;masternamelen--; p++) { if ((*p>='A' && *p<='Z') || (*p>='0' && *p<='9') || (*p>='a' && *p<='z') || (*p=='$') || (*p=='-') || (*p=='.') || (*p=='_') || (*p>=0x0c0 && *p<=0x0ff)) continue; else return (0); } return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -