Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_1_19910112
-
7/ft3/monitor/stanford/mnetdv.chi
There are no other files named mnetdv.chi in the archive.
;[MACBETH.STANFORD.EDU]SRC:<7.FT3.MONITOR.STANFORD>MNETDV.CHI.3, 7-Dec-88 12:01:35, Edit by A.ALDERSON
; Make Crispin's correction at GTHHNN+2 (P2 +> P1)
;[MACBETH.STANFORD.EDU]SRC:<7.FT3.MONITOR.STANFORD>MNETDV.MAC.2, 19-Aug-88 15:43:01, Edit by A.ALDERSON
; Make call to DOMINI depend on running ISI rather than MIT GTDOM% code...
;[MACBETH.STANFORD.EDU]SRC:<7.FT2.MONITOR.STANFORD>MNETDV.MAC.3, 20-Jun-88 18:48:27, Edit by A.ALDERSON
; V7.0 FT Clock tape
;[MACBETH]SRC:<7.FT2.MONITOR.STANFORD>MNETDV.MAC.2, 6-Apr-88 03:40:17, Edit by A.APPLEHACKS
; FT7.2 Merge
;[MACBETH]SRC:<7.FT1.MONITOR.STANFORD>MNETDV.MAC.2, 25-Jan-88 22:06:29, Edit by A.APPLEHACKS
; FT7 Merge
;;SIERRA::SRC:<6.1.MONITOR.STANFORD>MNETDV.MAC.6, 19-Jan-87 21:18:05, Edit by GROSSMAN
;; Install SRA's fix for field length overflows.
;;<6-1-MONITOR.FT6>MNETDV.MAC.5, 27-Aug-85 10:35:12, Edit by WHP4
;;Stanford changes:
;; Buffer input for HSTINI to greatly speed up host table parsing (3 x faster)
;; If DBUGIP/2, turn on networks irrespective of DBUGSW
;; MNTSTS prints a more useful message
;; FNDNCT and NETNCT know about the possibility of multiple interfaces
;; Fix MNTSET to actually start/stop/cycle the interface
;; MEIS support for 3MB and 10MB Ethernet
;; Initialize ISI domain service at system startup
;; Add locking on host table access
;; ULTRIX is a synonym for UNIX
;;Pup changes:
;; ATNVT% for Pup NVT's
;
; UPD ID= 8689, RIP:<7.MONITOR>MNETDV.MAC.6, 18-Mar-88 10:52:50 by GSCOTT
;TCO 7.1261 - Set NOADDR to be not normally dumpable.
; UPD ID= 8670, RIP:<7.MONITOR>MNETDV.MAC.5, 26-Feb-88 10:36:52 by GSCOTT
;TCO 7.1243 - Use SYSTEM:HOSTS.DEBUG if DBUGSW is greater than one.
; UPD ID= 8554, RIP:<7.MONITOR>MNETDV.MAC.4, 11-Feb-88 11:03:14 by GSCOTT
;TCO 7.1218 - Update copyright date.
; UPD ID= 8425, RIP:<7.MONITOR>MNETDV.MAC.3, 4-Feb-88 13:29:58 by GSCOTT
;TCO 7.1210 - Set NOHSTN normally not dumpable.
; UPD ID= 2123, SNARK:<6.1.MONITOR>MNETDV.MAC.11, 5-Jun-85 09:58:02 by MCCOLLUM
;TCO 6.1.1406 - Update copyright notice.
; UPD ID= 1957, SNARK:<6.1.MONITOR>MNETDV.MAC.10, 12-May-85 14:54:53 by PAETZOLD
;TCO 6.1.1380 - Make HOSTN larger.
; UPD ID= 1608, SNARK:<6.1.MONITOR>MNETDV.MAC.9, 8-Mar-85 11:53:53 by PAETZOLD
;Document BUGxxx's
; UPD ID= 1570, SNARK:<6.1.MONITOR>MNETDV.MAC.8, 26-Feb-85 17:17:32 by PAETZOLD
;document BUGxxx's
; UPD ID= 1235, SNARK:<6.1.MONITOR>MNETDV.MAC.7, 22-Dec-84 11:43:29 by PAETZOLD
;More TCO 6.1.1079 - Make the XJRST conditional based on REL6 switch for 5.4.
; UPD ID= 1178, SNARK:<6.1.MONITOR>MNETDV.MAC.6, 11-Dec-84 13:15:23 by PAETZOLD
;TCO 6.1.1079 - Use an XJRST referecing TVTJFN in ATNVT.
; UPD ID= 1038, SNARK:<6.1.MONITOR>MNETDV.MAC.5, 12-Nov-84 15:25:34 by PAETZOLD
;TCO 6.1041 - Move ARPANET to XCDSEC
; UPD ID= 999, SNARK:<6.1.MONITOR>MNETDV.MAC.4, 7-Nov-84 14:46:40 by PRATT
;TCO 6.1.1030 - Add IPCI to INTNAM for communicating over the CI
; UPD ID= 917, SNARK:<6.1.MONITOR>MNETDV.MAC.3, 23-Oct-84 19:49:20 by PAETZOLD
; UPD ID= 312, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.11, 18-Oct-84 15:41:24 by PAETZOLD
;TCO 6.1.1024 - Add .GTHLA function to GTHST%.
; UPD ID= 304, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.10, 15-Oct-84 14:46:20 by PAETZOLD
;Fix alphabetical order problem in OPSTAB.
; UPD ID= 287, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.9, 24-Sep-84 13:55:04 by PURRETTA
;Update copyright notice.
; UPD ID= 163, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.8, 3-Jun-84 17:26:35 by PAETZOLD
;Make MNTHLT reset NETON for each interface so that it stays down.
;Clean up MNTHLT in general. Remove MNTKIL since no one uses it.
;Add VMS, TACs, and MSDOS to OPSTAB.
; UPD ID= 159, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.7, 1-Jun-84 11:35:17 by PAETZOLD
;AOS INTFLG in MNTSET.
; UPD ID= 156, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.6, 31-May-84 11:25:18 by PAETZOLD
;Use indirects in MNTRSV
; UPD ID= 155, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.5, 31-May-84 10:58:54 by PAETZOLD
;Add MNTRSV. Add some ENDSV.'s.
; UPD ID= 129, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.4, 14-May-84 16:13:25 by PAETZOLD
;MNTHLT needs an EA.ENT.
; UPD ID= 33, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.3, 7-Apr-84 13:15:19 by PAETZOLD
;Remove some spaces in initial HSTINI message.
; UPD ID= 31, SNARK:<TCPIP.5.4.MONITOR>MNETDV.MAC.2, 5-Apr-84 22:46:02 by PAETZOLD
;Add IPNI to INTNAM. Change SITE-ADDRESS.TXT to INTERNET.ADDRESS. Clean
;up MNTSTS output. Use NETPRT to print out network numbers. Add
;informational message during startup when calling HSTINI.
; UPD ID= 4022, SNARK:<6.MONITOR>MNETDV.MAC.13, 31-Mar-84 16:20:59 by PAETZOLD
;TCO 6.2019 - Use ADJSPs
; UPD ID= 3941, SNARK:<6.MONITOR>MNETDV.MAC.12, 18-Mar-84 13:15:57 by PAETZOLD
;More TCO 6.1733 - Do not check for dots in GTHSIL.
; UPD ID= 3935, SNARK:<6.MONITOR>MNETDV.MAC.11, 17-Mar-84 13:01:33 by PAETZOLD
;More TCO 6.1733 - Add Fuzzballs to OPSTAB
; UPD ID= 3921, SNARK:<6.MONITOR>MNETDV.MAC.10, 14-Mar-84 10:17:06 by PAETZOLD
;More TCO 6.1733 - Add Foonex to OPSTAB as Tenex
; UPD ID= 3901, SNARK:<6.MONITOR>MNETDV.MAC.9, 11-Mar-84 14:28:21 by PAETZOLD
;More TCO 6.1733 - 5.3 needs a EA.ENT in MNTINI
; UPD ID= 3894, SNARK:<6.MONITOR>MNETDV.MAC.8, 11-Mar-84 10:36:16 by PAETZOLD
;More TCO 6.1733 - Allow JFNs in ATNVT%. New HSTINI preference scheme.
;Make HSTINI set up gateway (HS%GAT) and network (HS%NET) entries.
;Make RDFLD fold case to upper. Add TAC and WAITS to OPSTAB. Check and
;dispatch for Pup JFN in .ATNVT.
; UPD ID= 3826, SNARK:<6.MONITOR>MNETDV.MAC.7, 29-Feb-84 18:15:40 by PAETZOLD
;More TCO 6.1733 - ANBSEC and MNTSEC removal. Bug fixes. Cleanup.
;<TCPIP.5.3.MONITOR>MNETDV.MAC.4, 6-Dec-83 23:53:55, Edit by PAETZOLD
;Call CHKI7 from MNTCHK
;TCO 6.1867 - Use SAVEAC and not SAVP1
;Add subtitles. Make code that was RSCOD SWAPCD.
;More TCO 6.1733 - Fix day one off by one bug with NUMOPS
;More TCO 6.1733 - NCPFRK has gone away. HSTLUK Changes. HSTINI changes.
;<TCPIP.5.1.MONITOR>MNETDV.MAC.42, 5-Jul-83 08:28:09, Edit by PAETZOLD
;New host table support
;IP debuging switch support
;Use ANAUNV as the universal
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976, 1988.
; 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 THAT IS NOT SUPPLIED BY DIGITAL.
SEARCH ANAUNV,PROLOG
TTITLE (MNETDV,MNETDV,< - Internet Multinet Interface>)
Subttl Table of Contents
; Table of Contents for MNETDV
;
; Section Page
;
;
; 1. MNTINI - Initialization . . . . . . . . . . . . . . . 3
; 2. MNETON - Turn Networks On if They Have Never Been On . 4
; 3. MNTCHK - CHKR Fork Routine . . . . . . . . . . . . . . 5
; 4. MNTSTS - Report Network State Changes . . . . . . . . 6
; 5. NETPRT - Print Network Name or Number . . . . . . . . 7
; 6. Low and High Priority Packet Output Queueing . . . . . 8
; 7. NTWPKT - Packet Queueing Routine . . . . . . . . . . . 9
; 8. NTSNDI - Queue an Internet Packet . . . . . . . . . . 10
; 9. Routines to Find NCTs . . . . . . . . . . . . . . . . 11
; 10. HSTHSH - Find Host Table Entries . . . . . . . . . . . 12
; 11. Host, Network Status and Configuration Routines . . . 13
; 12. Routines Dealing With Network Shutdown . . . . . . . . 15
; 13. Routines Dealing With Network States . . . . . . . . . 16
; 14. Routine to Resolve Interface State . . . . . . . . . . 17
; 15. Host Table Initialization . . . . . . . . . . . . . . 18
; 16. GTFIL - GTJFN Routine for HSTINI and ADRINI . . . . . 29
; 17. ADRINI - Routine to Read SYSTEM:SITE-ADDRESS.TXT . . . 30
; 18. CVHST% JSYS - Convert Host Number to String . . . . . 37
; 19. GTHST% JSYS . . . . . . . . . . . . . . . . . . . . . 38
; 20. GTHST% JSYS - Individual Functions . . . . . . . . . . 39
; 21. ATNVT% JSYS and NETRDY GETAB Table . . . . . . . . . . 43
; 22. HSTLUK - Lookup Host Names . . . . . . . . . . . . . . 44
SUBTTL MNTINI - Initialization
XSWAPCD
;Called at system startup, initializes tables and storage needed by
;Multinet.
XNENT (MNTINI,G)
CALL NETINI ; initialize the 1822 buffers
MOVEI T1,BMNTLK ; Beginning of pages needed to lock down
SETSEC T1,INTSEC ; In proper section
MOVEI T2,EMNTLK ; End of area to lock
SETSEC T2,INTSEC ; Same section
CALL LKSTOR ; Lock storage
SETZM DEFADR ; Clear default address field
SETZM PRFADR ; Clear preferred address field
SETZM PRFNFD ; Also clear preferred shifted network
SETZM PRFNET ; And preferred network
SETZM NETSUP ; Networks not yet up
MOVSI T1,-%NETS ; Get number of networks we handle
SKIPA P1,NCTVT ; get link to the first NCT
MNTIN0: LOAD P1,NTLNK,(P1) ; get next on list
MOVE T2,NCTVT+1(T1) ; Get next pointer
STOR T2,NTLNK,(P1) ; Link it to this one
AOBJN T1,MNTIN0 ; Loop through all
SETZRO NTLNK,(P1) ; Clear last pointer (End of list)
CALL ADRINI ; Init addresses
BUG.(INF,NOADDR,MNETDV,SOFT,<ADRINI failed to find address file>,,<
Cause: The SYSTEM:INTERNET.ADDRESS file was either not found or is corrupted.
>,,<DB%NND>) ;[7.1261]
IFN STANSW,<
SETOM GTHLCK ; Init lock on host table
IFN FTDOM,<
CALL DOMINI ; Initialize domain service
BUG.(INF,DMIFNF,MNETDV,SOFT,<GTDOM - domain service not initialized>)
>;IFN FTDOM
>;IFN STANSW
TMSG <
[Loading Internet host names]>
CALL HSTINI ;GET THE SYSTEM TO KNOW NAMES OF SITES
TRNA ; skip on error
JRST MNTIN1 ; no error
BUG.(INF,NOHSTN,MNETDV,SOFT,<HSTINI failed to find host name file>,,<
Cause: The SYSTEM:HOSTS.TXT file was not found. The file SYSTEM:HOSTS.DEBUG
is used if DBUGSW is 2 or greater.
>,,<DB%NND>) ;[7.1261]
JRST MNTIN2 ; continue with flow
MNTIN1:
TMSG < [OK]
>
MNTIN2:
CALL NETHSI ; Initialize the network hash table
IFE STANSW,<
MOVE T1,DBUGSW ; Get system switch
CAIG T1,1 ; are we stand alone?
TDZA T1,T1 ; we are not stand alone
MOVEI T1,1 ; we are stand alone
SKIPE DBUGIP ; IP Debuging?
XORI T1,1 ; yes so reverse flag
SKIPN T1 ; System normal?
>;IFE STANSW
IFN STANSW,<
;;;DBUGIP/0 means turn on nets iff not standalone
;;;DBUGIP/1 means turn on nets iff standalone
;;;DBUGIP/2 means turn on nets always (new functionality added by this change)
CAILE T1,1 ; are we stand alone?
TDZA T1,T1 ; we are stand alone
MOVEI T1,1 ; we are not stand alone
XOR T1,DBUGIP ; consider this per DBUGIP
SKIPE T1 ; System normal?
>;IFN STANSW
SKIPN DEFADR ; Did addresses initialize properly?
JRST MNTINX ; No, return now
JRST MNTON1 ; Go turn on networks
;LKSTOR - Lock down a region of core
;1 - Xtended address of start
;2 - Xtened address of end
LKSTOR:
TRZ T1,777 ; Round down to nearest page
LKST1:
PUSH P,T1 ; Save start
PUSH P,T2 ; and end
CALLX (MSEC1,MLKMA) ; Lock down the page
POP P,T2 ; Restore ACs
POP P,T1 ; ...
ADDI T1,PGSIZ ; Increment to next page
CAMG T1,T2 ; Past last address?
JRST LKST1 ; Loop
RET
SUBTTL MNETON - Turn Networks On if They Have Never Been On
;Turn networks on if NETSUP has been off. Called by CALL MNETON$X
XNENT (MNETON,G)
MNTON1:
SKIPA P1,NCTVT ; Point to vector table
MNTON2: LOAD P1,NTLNK,(P1) ; get next in list
JUMPE P1,MNTINY ; Return when done
MNTCALL NTINI ; Initialize network device
SETOM NETON(P1) ; Turn it on
SETZM NTPRIO(P1) ; Clear priority cell
MNTCALL NTRSRT ; get it going
JRST MNTON2 ; and loop
MNTINY: SETOM NETSUP ; Networks are now initialized
MNTINX: RET ; And return
SUBTTL MNTCHK - CHKR Fork Routine
;CHKR Fork routine for keeping things going on all nets. Called every
;four minutes or whenever JB0FLG is non-zero.
XNENT (MNTCHK,G)
SKIPA P1,NCTVT ; Point to the vector table
MNTCH0: LOAD P1,NTLNK,(P1) ; Get next in list
JUMPE P1,MNTCH2 ; Go check the rest
SKIPE NTSTCH(P1) ; Change of state?
CALL MNTSTS ; Yes
SKIPN NETON(P1) ; If network off
JRST MNTCH0 ; Loop
; Want net on
MNTCALL NTSCHK ; Check status, keep stuff consistent
JFCL ; Ignore error return
SKIPG NETON(P1) ; If needs restarting
SKIPL NTRDY(P1) ; Or isn't ready
MNTCALL NTRSRT ; Restart it
MOVE T1,TODCLK ; Get time now
CAML T1,NTTOUT(P1) ; Output timed out?
SKIPN NTTOUT(P1) ; Output actually going?
JRST MNTCH1 ; No timeout
BUG.(INF,NTOHNG,MNETDV,SOFT,<Network output hung>,<<P1,D>>,<
Cause: Multinet has declared the output interface for a network hung.
>)
MNTCALL NTRSRT ; If timeout, reset net
MNTCH1: MNTCALL NTISRT ; Make sure input is happening
MOVE T1,SCTLW ; System shutdown?
TXNN T1,<1B3>
JRST MNTCH0 ; No, loop through all
; System shutdown
SETZM NTRDY(P1) ; Imp off
SETZM NETON(P1) ; Net off
SETZM NTORDY(P1) ; output off
SETO T1, ; Abort entry
MNTCALL NTKILL ; Drop ready line
JRST MNTCH0 ; and loop through the rest
MNTCH2:
SKIPE IMPGDM ; Any "imp going down" messages?
CALL CHKI7 ; Yes, go print it
RET ; And return
SUBTTL MNTSTS - Report Network State Changes
IFE STANSW,<
MNTSTS: ; Log network change of state
MOVE T2,NTLADR(P1) ; Get number
JUMPL T2,R ; Don't report if no address set
HRROI T1,[ASCIZ /
[Internet Network /]
PSOUT
CALL NETPRT ; Print out the network number
HRROI T1,[ASCIZ / on/] ; Assume it is on
SKIPN NETON(P1) ; Is it on?
HRROI T1,[ASCIZ / off/] ; no
PSOUT ; output it
HRROI T1,[ASCIZ /, Output /] ;delimit
PSOUT ; output it
HRROI T1,[ASCIZ /on/] ; assume on
SKIPN NTORDY(P1) ; is output on?
HRROI T1,[ASCIZ /off/] ; no
PSOUT ; output it
MOVEI T1," " ; delimit
PBOUT ; output it
SETZM NTSTCH(P1) ; reset the state change time
CALL LGTAD ; get time of this change
SKIPGE T2,T1 ; If time known
JRST MNTC5X ; Not known.
MOVEI T1,.PRIOU ; Still on CTY
MOVEI T3,0 ; this time
ODTIM ; output it
MNTC5X: TMSG <]
>
SKIPN NTORDY(P1) ; Did the hardware come up?
CALLRET INTDWN ; No, signal it's down
CALLRET INTUP ; Signal that it's available for use
>;IFE STANSW
IFN STANSW,<
MNTSTS: SKIPG NTLADR(P1) ;Skip if initialized
RET ;Else ignore this interface
CALLX (MSEC1,TIMSMP) ;Print time stamp
TMSG < Internet: Interface >
LOAD T2,NTNUM,(P1)
CALL DECOUT ;Say which interface is involved
HRROI T1,[ASCIZ/ is up/]
SKIPN NTORDY(P1)
HRROI T1,[ASCIZ/ is down/]
PSOUT% ;Say whether host is up or down
TMSG <, host number >
LDB T2,[POINT 8,NTLADR(P1),11]
CALL DECDOT ;First octet
LDB T2,[POINT 8,NTLADR(P1),19]
CALL DECDOT ;Second octet
LDB T2,[POINT 8,NTLADR(P1),27]
CALL DECDOT ;Third octet
LDB T2,[POINT 8,NTLADR(P1),35]
CALL DECOUT ;Forth octet
TMSG <
>
SETZM NTSTCH(P1) ;No more change of state
SKIPN NTORDY(P1) ;Did the hardware come up?
CALLRET INTDWN ;No, signal it's down
CALLRET INTUP ;Signal that it's available for use
DECDOT: TDZA T4,T4 ;Here if we want a trailing dot
DECOUT: SETO T4, ;Here for an unadorned decimal number
MOVX T1,.PRIOU ;To the console
MOVX T3,^D10 ;Decimal
NOUT% ;Print it
NOP
JUMPN T4,R ;Return now if no dot
MOVEI T1,"."
PBOUT% ;Print the dot
RET
>;IFN STANSW
SUBTTL NETPRT - Print Network Name or Number
NETPRT: ; Print the network number for current NCT
STKVAR <NPRTX,NPRBP>
MOVEI T1,.PRIOU ; Primary output
DOBE% ; dismiss until output done
ERJMP .+1 ; Handle errors
MOVE T1,NTNET(P1) ; Get the network number
LSH T1,10 ; Move it over one byte
CAMG T1,[BYTE (4)0(8)0,377,377,377] ; Class A or B?
LSH T1,10 ; yes move it over one more byte
CAMG T1,[BYTE (4)0(8)0,377,377,377] ; Class A?
LSH T1,10 ; yes move it over one more byte
MOVEM T1,NPRTX ; save it
MOVEI T1,.GTHNS ; Get host name function
MOVEI T2,.PRIOU ; Output to CTY
MOVE T3,NPRTX ; Get the network number
GTHST% ; Output the network number
ERJMP NETPR1 ; on error assume no name
RET ; and return
NETPR1: ; here when we do not have a network name
MOVX T1,<POINT 8,NPRTX,3> ; get the byte pointer
MOVEM T1,NPRBP ; and save it
MOVEI T4,4 ; four octets
NETPR2: ; output loop
ILDB T2,NPRBP ; get a byte
MOVEI T1,.PRIOU ; output to cty
MOVEI T3,12 ; in decimal
NOUT% ; output the octet
ERJMP .+1 ; handle errors
SOJE T4,R ; on the last one return
MOVEI T1,"." ; otherwise get a dot
PBOUT% ; output it
JRST NETPR2 ; and do the rest
ENDSV.
SUBTTL Low and High Priority Packet Output Queueing
;NTHSND - Put packet on High priority Q.
;T2/ packet pointer
;P1/ NCT address
;Returns+1 Refused
;Returns+2 Packet succesfully queued
XRESCD
NTSNDX: BUG.(CHK,BADADR,MNETDV,SOFT,<No NCT for address>,<<T1,ADR>>,<
Cause: The multinet output queuing mechanism was called for a local
address that has not been defined.
>)
RET ; return
NTHSND::SAVEAC <P1>
CALL FNDNCT
JSP CX,NTSNDX ; Nope
XMOVEI T1,NTHOBO(P1) ; Point to Q
JRST NTQPKT ; And queue it
;NTLSND - Put packet on low priority Q
;T2/ packet pointer
;P1/ NCT address
;Returns+1 Refused
;Returns+2 Packet succesfully queued
NTLSND::SAVEAC <P1>
CALL FNDNCT
JSP CX,NTSNDX ; Not found
XMOVEI T1,NTLOBO(P1)
JRST NTQPKT
SUBTTL NTWPKT - Packet Queueing Routine
;NTWPKT - Put packet on FIFO Q
;T1/ pointer to Q head
;T2/ packet pointer
;P1/ NCT address
;Returns+1 Refused
;Returns+2 Packet succesfully queued
NTQPKT: SKIPN NTORDY(P1) ; Output allowed?
RET ; No, fail
TRNN T2,-1 ; Is the address good?
BUG.(HLT,BADBUF,MNETDV,SOFT,<Null buffer address>,,<
Cause: Multinet has been called to queue an output buffer with a null
address.
>)
HRRZS 0(T2) ; Make sure succesor chain is NIL
PIOFF ; Insure intergrety of queues
SKIPE T3,1(T1) ; Q empty?
JRST NTQPK2 ; No, put on tail
MOVEM T2,0(T1) ; Yes, set head pointer
SKIPA ; Don't chain, no predecessor
NTQPK2: STOR T2,NBQUE,(T3) ; Chain from predecessor to new guy
MOVEM T2,1(T1) ; This is new tail of Q
PION ; Allow interrupts again
MNTCALL NTOSRT ; Start output if needed
RETSKP ; And return succesfully
SUBTTL NTSNDI - Queue an Internet Packet
;NTSNDI - Default routine for enquing an internet packet
; T1/ Local host
; T2/ packet pointer
; P1/ NCT address
;Returns+1 Refused, T1 has an ICMP error code
;Returns+2 Packet succesfully queued
NTSNDI::MNTCALL NTOTOK ; Can this packet be sent?
RET ; No, T1 has reason
MNTCALL NTLLDR ; Make a local header
XMOVEI T1,NTIOBO(P1) ; Point to right Q
CALL NTQPKT ; And Q the packet
CAIA ; Failed
RETSKP ; Success
MOVX T1,<ICM%SQ> ; Back off a minute, interface unusable
RET ; return
SUBTTL Routines to Find NCTs
;FNDNCT - Host number to NCT
;T1/ Host address
;Returns+1 No NCT for that net
;Returns+2 P1/ pointer to the NCT for a (usable) interface on that net
FNDNCT::SAVET ; Save temps
IFN STANSW,<
STKVAR <HOST> ; Declare local storage
MOVEM T1,HOST ; Save host number
>;IFN STANSW
NETNUM T2,T1 ; Get the network number
CALL NETHSH ; Look it up in the tables
RET ; No, knowledge of that net
SKIPL P1,NETGWY(T2) ; Get the interface
RET ; Not directly connected
IFN STANSW,<
MOVE T1,HOST ; Get back that host number
CALL FNDINT ; Ensure best interface to this network
>;IFN STANSW
RETSKP ; And skip return
IFN STANSW,<
ENDSV. ; Flush STKVAR definition
>;IFN STANSW
;NETNCT - Host or Net to NCT of a (possibly down) interface on that net.
;T1/ Host address or Net number
;Returns+1 No NCT for that net
;Returns+2 P1/ pointer to the NCT for a (usable) interface on that net
NETNCT::SAVET ; Save temps
IFE STANSW,<
TXNN T1,-1B11 ; Host address?
JRST NETNC0 ; No
NETNUM T1,T1 ; Get the network number
NETNC0: XMOVEI P1,NCTVT ; Point to the table
NETNCL: LOAD P1,NTLNK,(P1) ; Get net in the chain
JUMPE P1,R ; No more
CAMN T1,NTNET(P1) ; Same network?
RETSKP ; yes, success
JRST NETNCL ; else loop
>;IFE STANSW
IFN STANSW,<
SETZ T2, ; Assume not a host address
TXNN T1,-1B11 ; Host address?
JRST NETNC0 ; No
MOVE T2,T1 ; Yes, stash a copy in T2
NETNUM T1,T1 ; Get the network number
NETNC0: XMOVEI P1,NCTVT ; Point to the table
NETNCL: LOAD P1,NTLNK,(P1) ; Get net in the chain
JUMPE P1,R ; No more
CAME T1,NTNET(P1) ; Same network?
JRST NETNCL ; no, loop
SKIPE T1,T2 ; If we were looking for a host's NCT
CALL FNDINS ; Then find the best interface, strict match
RETSKP ; Return success
>;IFN STANSW
SUBTTL HSTHSH - Find Host Table Entries
;Given a host number in T1 finds entry for that number in host
;tables. Does skip return if found. is table index, or -1 if no more
;room in tables.
HSTHSH::
MOVE T2,T1 ;DO A HASH
IDIVI T2,NHOSTS ;GET INITIAL GUESS, DIV BY PRIME
EXCH T2,T3 ;2/ FIRST GUESS
IDIVI T3,NHOSTS ;DIV BY PRIME AGAIN
CAIN T4,0 ;GET INCREMENT
MOVEI T4,1
MOVEI T3,NHOSTS ;COUNTER FOR GUESSES
SETSEC T2,INTSEC ;LOOK IN THE RIGHT SECTION
HSTHLP: SKIPG HOSTNN(T2) ;NO HOST THERE?
RET ;NO, 2/ WHERE TO PUT IT
CAMN T1,HOSTNN(T2) ;MATCH?
RETSKP
ADDI T2,(T4) ;STEP BY INCREMENT
CAML T2,[XWD INTSEC,NHOSTS] ;CHECK FOR OVERFLOW
SUBI T2,NHOSTS ;WRAP AROUND IF NEEDED
SOJG T3,HSTHLP ;COUNT DOWN GUESSES
SETO T2, ;-1 TABLE FULL
RET ;RETURN ERROR
SUBTTL Host, Network Status and Configuration Routines
XSWAPCD
;NETCHK - Check if our interface on a given net is up
;T1/ Host number
;Returns+1 if interface is down
;Returns+2 if it is up
NETCHK::SAVEAC <P1>
CALL NETNCT ; Find the NCT
TRNA ; No such Net
SKIPL NTRDY(P1) ; Network up?
RET ; No
RETSKP ; Yes, return good
;NETCMP - Check if a host is on a given interface.
;T1/ Host number
;P1/ Pointer to NCT
;Returns+1 if host is not on that interface
;Returns+2 if it is
NETCMP::SAVET ; Save temps
NETNUM T1,T1 ; Get the net number
MOVE T2,NTNET(P1) ; And that of this NCT
CAME T2,T1 ; Same?
RET ; No
RETSKP ; Yes
;LCLNET - Check if a host address is on a net we're connected to.
;T1/ Host address
;Returns+1 If no intersecting network
;Returns+2 If we have an intersecting network
;(Note that this doesn't mean that the interface is currently usable)
LCLNET::SAVET ; Save temps
NETNUM T1,T1 ; Get the net number
XMOVEI T3,NCTVT ; Point to the interface table
LCLNT0: LOAD T3,NTLNK,(T3) ; get the next in the list
JUMPE T3,R ; end of the list
CAMN T1,NTNET(T3) ; On this network?
RETSKP ; yes, return success
JRST LCLNT0 ; loop through all
;LCLHST
;Check if a given address (possibly with non-zero logical host
;field) is one of ours
;T1/ 32 bit address
;Returns+1 if it is not one of ours
;Returns+2 if it is
LCLHST::SAVEAC <P1>
PUSH P,T1 ; Save address
SKIPA P1,NCTVT ; First interface
LCLHS0: LOAD P1,NTLNK,(P1) ; Next interface
JUMPE P1,LCLHS9 ; No more
MOVE T1,(P) ; Address again
ANDCM T1,NTNLHM(P1) ; without logical host field
CAME T1,NTLADR(P1) ; Is this one of ours?
JRST LCLHS0 ; No, loop through all
AOS -1(P) ; Success! it's me, skip return
LCLHS9: POP P,T1 ; Restore address
RET
SUBTTL Routines Dealing With Network Shutdown
;T1/ Reason, a la 1822
;T2/ GTAD when back up
XNENT (MNTHLT,G)
; Tell all interfaces we are going away.
SAVEAC <P1>
STKVAR <<MHLTRS,2>>
DMOVEM T1,MHLTRS ; save the time and reason
MOVX T1,<377777777777> ; Stop pings
MOVEM T1,PINGTM ; Save new ping time
; shutdown each interface
SKIPA P1,NCTVT ; Get pointer to tables
MNTHL2: LOAD P1,NTLNK,(P1) ; Get next NCT
JUMPE P1,R ; done?
SETZM NETON(P1) ; No, say that we want this interface off.
DMOVE T1,MHLTRS ; Get why/when.
MNTCALL NTKILL ; Do halt instruction
JRST MNTHL2 ; Loop through all
SUBTTL Routines Dealing With Network States
;MNTSET - Set a network status.
; T1/ Network number, or host address
; T2/ value
; Possible values are: <0 = on
; 0 = off
; >0 = request cycle
MNTSET::SAVEAC <P1>
CALL NETNCT ; Find the NCT
RET ; If none
SKIPGE T2
SETO T2, ; Either -1
IFE STANSW,<
SKIPE T2 ; or 0
>;IFE STANSW
IFN STANSW,< ;;Don't turn -1 into 0,,-1
SKIPLE T2 ; or 0
>;IFN STANSW
HRRZI T2,-1 ; or 0,,-1
MOVEM T2,NETON(P1) ; Set function
IFN STANSW,<
IFE. T2
SETOB T1,T2 ; Arguments are -1
MNTCALL NTKILL ; Shut off the hardware
ELSE.
IFG. T2
SETOB T1,T2 ; Want to cycle hardware.
MNTCALL NTKILL ; Shut off the hardware, fall thru to restart
ENDIF.
MNTCALL NTRSRT ; Restart the hardware
MNTCALL NTISRT ; Make sure input is happening
ENDIF.
>;IFN STANSW
AOS INTFLG ; Ask for the internet fork
RETSKP ; Success return
MNTRED:: ; ROUTINE TO RETURN NETWORK STATE
SAVEAC <P1>
SETZ T2, ; ASSUME NET IS DOWN
CALL NETNCT ; GET THE NCT
RET ; NO NCT
MOVE T2,NETON(P1) ; GET THE STATE
RETSKP ; SUCCESS RETURN
SUBTTL Routine to Resolve Interface State
MNTRSV:: ; Resolve interface state (P1/ NCT)
SKIPL NETON(P1) ; do we want it up?
JRST MNTRS2 ; no
SKIPE NTRDY(P1) ; yes. is it up?
RET ; want up and is up so return.
CALL @NTRSRT(P1) ; want up and is down so make it up.
RET ; and return
MNTRS2: ; Here when not wanted up.
SKIPE NETON(P1) ; want it down?
JRST MNTRS3 ; no must want it cycled.
SKIPN NTRDY(P1) ; is it down?
RET ; want down and is down so return.
CALL @NTKILL(P1) ; want down and is up so take it down.
RET ; and return to caller
MNTRS3: ; here when we want to cycle
SKIPE NTRDY(P1) ; is it up now?
CALL @NTKILL(P1) ; yes so make it down
SETOM NETON(P1) ; and say that we want it up
RET ; and return to caller
SUBTTL Host Table Initialization
COMMENT \
Initialize the Host tables. Called at system startup (And possibly
other times). Reads in system Hostname file and sets up the host
tables from it. In order to save Section 0/1 space Host tables are
put in INTSEC. This is the new Internet host table parser. This is
intended as a stopgap measure to allow TOPS-20's to use the Internet
format host table until they can really take advantage of it.
Structures in the Host tables For reference the Host tables have the
following formats:
Tables indexed by a hash of the host number:
HOSTNN - The 32 bit host number
HSTSTS - Status bits
HOSTPN - index in HOSTN of primary name for this number
Tables indexed by order in the host name file:
HOSTN - LH 18 bit address in HSTNAM
RH Index into hashed tables
HSTNAM - a block NHSTN long which holds the null terminated name strings
\
IFN STANSW,<
ND LNBFLN,<^D160/5>+1 ;Length of buffer for GBCH and GETBUF
TMPBLN==^D100 ;Number of characters in TMPBUF (including
; terminating null).
>;IFN STANSW
HSTINI::
SAVEAC <P1>
IFE STANSW,<
TRVAR <HTBJFN,<TMPBUF,10>,NAMPTR,NAMIDX,NAMSPC,NAMCNT,SAVEP,BOL,TERM,HSTS,HBEST,HGOOD,NAMLST,NUMLST,NETMSK,ENTTYP>
>;IFE STANSW
IFN STANSW,<
TRVAR <HTBJFN,<TMPBUF,<<TMPBLN+4>/5>>,NAMPTR,NAMIDX,NAMSPC,NAMCNT,SAVEP,BOL,TERM,HSTS,HBEST,HGOOD,NAMLST,NUMLST,NETMSK,ENTTYP,<LINBUF,LNBFLN>,LINPTR,LINCNT,LINPBC,GBEOF>
>;IFN STANSW
MOVEM P,SAVEP ;SAVE A STACK FENCE IN CASE OF ERRORS
IFN STANSW,<
CALL LCKGTH ;LOCK HOST TABLE AGAINST OTHER ACCESS
>;IFN STANSW
MOVX T1,GJ%SHT!GJ%OLD ;GTJFN FLAGS. FILE MUST EXIST.
MOVE T2,DBUGSW ;[7.1243] Load debug switch
CAILE T2,1 ;[7.1243] Is it 2 or above?
SKIPA T2,[-1,,[ASCIZ/SYSTEM:HOSTS.DEBUG/]] ;[7.1243] Yes, use debug ver
HRROI T2,[ASCIZ/SYSTEM:HOSTS.TXT/] ;[7.1243] No, usual filename
GTJFN% ;LOOK FOR THE FILE
IFE STANSW,<
ERJMP R ;FILE NOT FOUND
>;IFE STANSW
IFN STANSW,<
RETBAD(,<CALL ULKGTH>) ;FILE NOT FOUND, UNLOCK AND RETURN
>;IFN STANSW
MOVEM T1,HTBJFN ;SAVE THE JFN
MOVX T2,7B5!OF%RD ;WE NEED READ ACCESS
OPENF% ;OPEN UP THE JFN
ERJMP HSTIE1 ;HANDLE ERRORS
PUTSEC T1,INTSEC ;INITIAL HOSTN INDEX
MOVEM T1,NAMIDX
MOVEI T1,NHOSTN ;SIZE OF HOSTN
MOVEM T1,NAMCNT ;SAVE
MOVNI T1,NHSTN ;SIZE OF NAME SPACE
MOVEM T1,NAMSPC ;SAVE
PUTSEC T1,INTSEC ;INITIAL INDEX INTO NAME SPACE
MOVEM T1,NAMPTR ;SAVE
;...
MOVE T1,[XWD INTSEC,HSTNAM] ;CLEAR THE CURRENT TABLES
SETZM 0(T1) ;CLEAR FIRST WORD OF NAME SPACE
MOVE T2,[XWD HSTNAM,HSTNAM+1] ;GET THE BLT AC
BLT T2,NHSTN-1(T1) ;ZAP
MOVE T1,[XWD INTSEC,HOSTN] ;GET THE ADDRESS OF HOSTN
SETZM 0(T1) ;ZERO THE FIRST WORD
MOVE T2,[XWD HOSTN,HOSTN+1] ;GET THE BLT AC
BLT T2,NHOSTN-1(T1) ;ZERO THE REST OF THE TABLE
PUTSEC T1,INTSEC ;GET AN INDEX INTO THE CORRECT SECTION
SETZM HOSTNN(T1) ;ZERO THE FIRST WORD OF HOSTNN
MOVE T2,[HOSTNN,,HOSTNN+1] ;GET THE BLT AC
BLT T2,HOSTNN+NHOSTS-1(T1) ;ZERO THE REST OF HOSTNN
SETZM HSTSTS(T1) ;ZERO THE FIRST WORD OF HSTSTS
MOVE T2,[HSTSTS,,HSTSTS+1] ;GET THE BLT AC
BLT T2,HSTSTS+NHOSTS-1(T1) ;ZERO THE REST OF HSTSTS
SETZM HOSTPN(T1) ;ZERO THE FIRST WORD OF HOSTPN
MOVE T2,[HOSTPN,,HOSTPN+1] ;GET THE BLT AC
BLT T2,HOSTPN+NHOSTS-1(T1) ;ZERO THE REST OF HOSTNN
MOVE T1,PRFNET ;GET PREFERRED NETWORK NUMBER
MOVX T2,<MASKB 4,27> ;NETWORK MASK FOR CLASS C NETWORK
LSH T1,^D8 ;SHIFT INTO POSITION FOR CLASS C NETWORK
CAMN T1,PRFNFD ;CLASS C?
IFSKP.
MOVX T2,<MASKB 4,19> ;NETWORK MASK FOR CLASS B NETWORK
LSH T1,^D8 ;SHIFT INTO POSITION
CAMN T1,PRFNFD ;CLASS B?
ANSKP.
MOVX T2,<MASKB 4,11> ;NETWORK MASK FOR CLASS A NETWORK
LSH T1,^D8
CAME T1,PRFNFD ;CLASS A?
BUG.(HLT,HSTNET,MNETDV,SOFT,<PRFNFD or PRFNET incorrect>,,<
Cause: The preferred network number is messed up. This probably indicates
that the SYSTEM:INTERNET.ADDRESS file is messed up.
>)
ENDIF.
MOVEM T2,NETMSK ;SAVE HOST MASK FOR LATER
IFN STANSW,<
SETZM LINPTR ;NO POINTER TO LINE BUFFER YET
SETZM LINBUF ;NO LINE BUFFER CONTENTS YET
SETZM LINCNT ;NO COUNT OF CHARS IN LINE BUFFER YET
SETZM LINPBC ;NO "PUT BACK" CHAR FROM BACKING UP
SETZM GBEOF ;HAVEN'T HIT EOF IN GETBUF YET
>;IFN STANSW
HSTIN6: ;LOOP FOR PROCESSING ENTRIES
MOVE P,SAVEP ;RESET STACK FENCE
CALL GBOLX ;SKIP TO START OF NEXT NON-BLANK,
;NON-COMMENT LINE @ FIRST NON-WHITE
CALL RDFLD ;READ A VALUE
MOVE T1,TMPBUF ;GET FIRST WORD
SETZ T2, ;ZERO MEANS UNKNOWN TYPE OF ENTRY
CAMN T1,[ASCIZ/HOST/] ;HOST?
MOVX T2,HS%SRV ;YES
CAMN T1,[ASCIZ/NET/] ;NETWORK?
MOVX T2,HS%NET ;YES
CAMN T1,[ASCIZ/GATEW/] ;GATEWAY?
MOVX T2,HS%GAT ;YES
JUMPE T2,HSTIN6 ;FLUSH IF AN UNKNOWN ENTRY TYPE
MOVEM T2,ENTTYP ;SAVE ENTRY TYPE
;Should also check if it is a gateway, and if so fill in in routing
;tables....
MOVEM P,NUMLST ;SAVE POINTER TO NUMBERS
HSTIN7: ;LOOP FOR READING IN ALL THE NUMBERS
CALL RDHNUM ;READ A HOST NUMBER
CALL HSTHSH ;HASH IT INTO THE TABLES
NOP ;IGNORE SKIP RETURN
JUMPL T2,HSTIE2
MOVEM T1,HOSTNN(T2) ;SAVE THE NUMBER
PUSH P,T2 ;AND THE INDEX
MOVE T1,TERM ;GET FIELD TERMINATOR
CAIE T1,":" ;END?
JRST HSTIN7
PUSH P,[-1] ;FLAG END OF LIST
;...
;...
;HERE WITH ALL ADDRESSES ON THE STACK
MOVEM P,NAMLST ;START OF NAME LIST
HSTIN9:
CALL RDFLD ;READ THE NEXT FIELD
JUMPE T1,HSTIE3
ADDI T1,1 ;COUNT THE NULL TERMINATOR
IDIVI T1,5 ;CONVERT CHAR COUNT TO WORD COUNT
SKIPE T2 ;ROUND UP IF NEEDED
ADDI T1,1 ;...
PUSH P,T1 ;SAVE
ADDM T1,NAMSPC ;DECREMENT NAME SPACE LEFT
SKIPLE NAMSPC ;TABLE FULL?
JRST HSTIE4
MOVE T1,0(P) ;GET COUNT BACK
XMOVEI T2,TMPBUF ;POINT TO NAME READ
MOVE T3,NAMPTR ;NEXT EMPTY SPACE IN TABLE
ADDI T3,HSTNAM ;...
CALL XBLTA ;MOVE THE NAME
POP P,T1 ;RESTORE COUNT
PUSH P,NAMPTR ;SAVE THIS INDEX
ADDM T1,NAMPTR ;UPDATE TABLE
MOVE T1,TERM ;GET TERMINATOR
CAIE T1,":" ;END OF LIST?
JRST HSTIN9 ;NO, ONWARD FOR THE NEXT
PUSH P,[-1] ;FLAG END OF LIST
MOVE T2,ENTTYP ;GET ENTRY TYPE
CAME T2,[HS%SRV] ;SKIP IF A HOST ENTRY
JRST HST12A ;NETS AND GW'S SKIP MACHINE TYPE/OS/PROTOCOLS
CALL SKPFLD ;SKIP MACHINE TYPE
CALL RDFLD ;READ OPERATING SYSTEM
SETZ T2,
JUMPE T1,HSTI12
MOVEI T1,OPSTAB ;OPERATING SYSTEM TYPE TABLE
MOVE T2,[POINT 7,TMPBUF] ;POINT TO NAME
TBLUK%
ERJMP .+1
TXNE T2,TL%NOM!TL%AMB ;NO MATCH?
TDZA T2,T2 ;THEN NO OPSYS
HRRZ T2,(T1) ;ELSE GET TABLE VALUE
HSTI12:
TXO T2,HS%SRV ;PRETEND THEY'RE ALL SERVERS
HST12A:
MOVEM T2,HSTS ;SAVE IT
;Now things are set up as follows: NUMLST points to a list of HOSTNN
;indices for this host. NAMLST points to a list of HSTNAM indices for
;its names. HSTS holds the operating system type.
HRRZ T3,NUMLST ;POINT TO LIST OF NUMBERS
MOVE T2,NAMIDX ;INDEX OF PRIMARY NAME IN HOSTN
;Select the primary address. We will always prefer the PRFADR address
;in the event this is our local host. Failing that, we prefer an
;address that is on PRFADR's network, which is presumably the best
;network to reach that host. Failing that, we prefer any network we
;are directly connected to, so we can avoid gateways. If all else
;fails, we'll take the first listed address.
SETZM HBEST ;INITIALLY NO BEST INDEX
SETZM HGOOD ;NOR A GOOD INDEX
;...
HSTI13: ;...
SKIPG T4,1(T3) ;GET AN INDEX
JRST HSTI14 ;DONE WITH THE LIST
MOVEM T2,HOSTPN(T4) ;SAVE
MOVE T1,HSTS ;AND OPSYS TYPE
MOVEM T1,HSTSTS(T4) ;...
MOVE T1,HOSTNN(T4) ;GET THE NUMBER
CAMN T1,DEFADR ;OUR DEFAULT ADDRESS IS ALWAYS BEST
JRST HSTI15 ;SO SET IT AS BEST UNCONDITIONALLY
CAMN T1,PRFADR ;(PROBABLY UNNECESSARY) PREFERRED ADDRESS IS
JRST HSTI15 ; ALMOST AS GOOD
SKIPE HBEST ;HAVE A BEST ADDRESS YET?
JRST HSTI16 ;YES, NO NEED TO CONSIDER ANY OTHERS
AND T1,NETMSK ;NO, GET NETWORK BYTES ONLY
CAME T1,PRFNFD ;IS THIS ADDRESS ON PREFERRED NETWORK?
JRST HSTI17
HSTI15: MOVEM T4,HBEST ;YES, CONSIDER IT BEST
JRST HSTI16
HSTI17:
SKIPE HGOOD ;NOT ON DEFAULT NET, HAVE A GOOD ADDRESS YET?
JRST HSTI16
MOVE T1,HOSTNN(T4) ;NO, GET ADDRESS AGAIN
CALL NETNCT ;HAVE AN INTERFACE ON THAT NET?
JRST HSTI16
MOVEM T4,HGOOD ;YES, CONSIDER IT A GOOD ADDRESS
HSTI16:
AOJA T3,HSTI13 ;LOOP THROUGH NUMBER LIST
HSTI14:
HRRZ T2,NAMLST ;GET NAME LIST
MOVE T3,NAMIDX ;GET INDEX INTO NAME TABLE
SKIPE T1,HBEST ;GET BEST NUMBER INDEX
JRST HSTI18
SKIPE T1,HGOOD ;NO BEST INDEX, GET A GOOD INDEX
JRST HSTI18
HRRZ T1,NUMLST ;NO GOOD INDEX, POINT TO LIST OF NUMBERS
MOVE T1,1(T1) ;USE FIRST AS DEFAULT
HSTI18:
SKIPG T4,1(T2) ;GET NEXT NAME ON THE LIST
JRST HSTI19 ;DONE
STOR T4,HSTNMP,(T3) ;SET NAME POINTER
STOR T1,HSTIDX,(T3) ;SAVE NUMBER INDEX
MOVX T4,1B0 ;NICKNAME FLAG
HRRZ CX,NAMLST ;START OF LIST
CAME T2,CX ;THIS THE FIRST NAME?
IORM T4,HOSTN(T3) ;NO, FLAG AS A NICKNAME
ADDI T3,1 ;INCREMENT NAME TABLE INDEX
SOSG NAMCNT ;COUNT DOWN TOTAL NUMBER OF NAMES
JRST HSTIE5
AOJA T2,HSTI18 ;AND NAME LIST INDEX
HSTI19:
MOVEM T3,NAMIDX ;SAVE NEW INDEX INTO NAME TABLE
JRST HSTIN6 ;ONWARD
; TBLUK% table for operating system names
OPSTAB: XWD NUMOPS,NUMOPS
XWD [ASCIZ/ANTS/],.HSANT
XWD [ASCIZ/ELF/],.HSELF
XWD [ASCIZ/FOONEX/],.HS10X
XWD [ASCIZ/FUZZ/],.HSFUZ
XWD [ASCIZ/ITS/],.HSITS
XWD [ASCIZ/MSDOS/],.HSDOS
XWD [ASCIZ/MTIP/],.HSMTP
XWD [ASCIZ/MULTICS/],.HSMLT
XWD [ASCIZ/TAC/],.HSTAC
XWD [ASCIZ/TENEX/],.HS10X
XWD [ASCIZ/TIP/],.HSTIP
XWD [ASCIZ/TOPS10/],.HSDEC
XWD [ASCIZ/TOPS20/],.HST20
XWD [ASCIZ/TOPS20AN/],.HST20
IFN STANSW,<
XWD [ASCIZ/ULTRIX/],.HSUNX
>;IFN STANSW
XWD [ASCIZ/UNIX/],.HSUNX
XWD [ASCIZ/VMS/],.HSVMS
XWD [ASCIZ/WAITS/],.HSDEC
NUMOPS=.-OPSTAB-1
;GBOLX - Move to start of next line
;returns BOL - file pointer of start of this line
IFE STANSW,<
GBOLX: MOVE T1,HTBJFN ;GET JFN BACK
GBOLX1: BIN% ;READ A BYTE
ERJMP HFILDN ;END OF FILE
CAIE T2,.CHLFD ;EOL?
JRST GBOLX1 ;LOOP
RFPTR% ;READ FILE POSITION
ERJMP HFILER ;FATAL
MOVEM T2,BOL ;SAVE START OF THIS LINE
GBOLX2: BIN% ;READ START OF NEXT LINE
ERJMP HFILDN ;END OF FILE
CAIE T2,";" ;COMMENT?
CAIN T2,.CHCRT ;OR BLANK LINE?
JRST GBOLX1 ;SKIP
CAIE T2," " ;LSWP?
CAIN T2,.CHTAB ;?
JRST GBOLX2 ;YES
BKJFN% ;BACK UP
ERJMP .+1
RET ;RETURN
>;IFE STANSW
IFN STANSW,<
GBOLX: MOVE T1,HTBJFN
GBOLX1: CALL GBCH
JRST HFILDN
CAIE T2,.CHLFD ;EOL?
JRST GBOLX1 ;LOOP
RFPTR% ;READ FILE POSITION
ERJMP HFILER ;FATAL
SUB T2,LINCNT ;ADJUST FOR CHARACTERS BUFFERED
MOVEM T2,BOL ;SAVE START OF THIS LINE
GBOLX2: CALL GBCH ;READ START OF NEXT LINE
JRST HFILDN ;DONE WITH FILE
CAIE T2,";" ;COMMENT?
CAIN T2,.CHCRT ;OR BLANK LINE?
JRST GBOLX1 ;SKIP
CAIE T2," " ;LSWP?
CAIN T2,.CHTAB ;?
JRST GBOLX2 ;YES
CALL PBBCH ;BACK UP POINTER AND PUT BACK CHAR
RET ;AND RETURN
;PUT BACK BUFFERED CHAR
PBBCH: SAVEAC <T3,T4>
AOS T3,LINCNT ;ADJUST COUNT OF CHARACTERS
CAILE T3,LNBFLN*5-1
IFSKP.
SETOM T3
MOVE T4,LINPTR
ADJBP T3,T4 ;BACK UP POINTER BY ONE
MOVEM T3,LINPTR
ELSE.
MOVEM T2,LINPBC ;SAVE CHAR IF BACKING UP BEFORE BUFFER HEAD
ENDIF.
RET ;RETURN
;GET BUFFERED CHARACTER
GBCH: SOSG LINCNT ;ANYTHING LEFT IN BUFFER
IFNSK. ;NO,
CALL GETBUF ;GET ANOTHER BUFFER-FUL
RET ;BLEW IT, PASS ALONG FAILURE RETURN
ENDIF.
SKIPE T2,LINPBC ;DID WE PUT A CHARACTER BACK?
IFSKP. ;NO PUT BACK CHAR, SLURP ONE FROM BUFFER
ILDB T2,LINPTR
ELSE. ;WAS A PUT BACK CHAR
SETZM LINPBC ;DON'T RE-USE IT
ENDIF.
RETSKP ;SUCCESS RETURN, WE GOT A CHARACTER
;GETBUF - GET ANOTHER BUFFERFUL FOR GBCH
;TAKES T1/ JFN FOR INPUT FILE
;RETURNS +1 IF FAILURE, GBEOF SET TO -1
; +2 IF SUCCESSFUL, LINPTR, LINCNT UPDATED, GBEOF SET IF EOF HIT
GETBUF: SKIPE GBEOF ;HAVE WE SEEN EOF?
RET ;YES, FAILURE RETURN
SAVEAC<T3,T4>
MOVE T2,[POINT 7,LINBUF] ;POINT AT OUR BUFFER
MOVNI T3,LNBFLN*5-1 ;THIS MANY CHARACTERS
SIN%
IFJER.
SETOM GBEOF ;PROBABLY HIT EOF, FLAG IT
ENDIF.
ADDI T3,LNBFLN*5-1 ;MAX CHARS + UPDATED VALUE IN T3 = NUMBER READ
MOVEM T3,LINCNT ;FIX BUFFERED BYTE COUNT UP
HRROI T3,LINBUF ;RESET LINPTR
HRLI T3,(<POINT 7,>)
MOVEM T3,LINPTR
SKIPE LINCNT ;DID WE READ SOME CHARACTERS?
RETSKP ;YES, SUCCESS RETURN
SETOM GBEOF ;NO, SIGNAL EOF
RET ;FAILURE RETURN
>;IFN STANSW
;RDFLD - Read next field. Terminated by a "," or ":".
;Returns
;T1/ number of characters read
;TERM -- terminating character
;TMPBUF -- holds string (Null terminated)
RDFLD: STKVAR <COUNT,PTR>
SETZM COUNT ;CLEAR FIELD LENGTH
MOVE T1,[POINT 7,TMPBUF] ;POINT TO START OF BUFFER
MOVEM T1,PTR ; TO STORE STRING IN
SETZM TMPBUF ;FIRST WORD OF BUFFER MBZ
MOVE T1,HTBJFN ;GET FILE HANDLE
; SKIP LWS
IFE STANSW,<
RDFLD1: BIN% ;READ A BYTE
ERJMP PEOF
>;IFE STANSW
IFN STANSW,<
RDFLD1: CALL GBCH ;READ A BYTE
JRST PEOF
>;IFN STANSW
CAIL T2,140 ;LOWER CASE?
TRZ T2,40 ;YES SO MAKE IT UPPERCASE
CAIE T2,.CHTAB ;TAB?
CAIN T2," " ;BLANK?
JRST RDFLD1 ;YES
RDFLD2: CAIE T2,":" ;END OF FIELD?
CAIN T2,"," ;?
JRST RDFLDD ;YES
CAIE T2," " ;?
CAIN T2,.CHTAB ;?
JRST RDFLDD ;YES
CAIN T2,.CHCRT ;EOL?
JRST PEOLX ;ERROR
CAIL T2,140 ;LOWER CASE?
TRZ T2,40 ;YES, RAISE
IDPB T2,PTR ;SAVE CHARACTER
IFE STANSW,<
AOS COUNT ;COUNT IT
BIN% ;READ THE NEXT
ERJMP PEOF ;PREMATURE END OF FILE
>;IFE STANSW
IFN STANSW,<
AOS T2,COUNT ;COUNT IT
CAILE T2,TMPBLN-1 ;ANY ROOM FOR THIS ONE?
JRST PEOLL ; NO, FIELD TOO LONG
CALL GBCH ;READ THE NEXT
JRST PEOF ;PREMATURE END OF FILE
>;IFN STANSW
JRST RDFLD2 ;CONTINUE
RDFLDD: CAIE T2,"," ;FIELD TERMINATOR SEEN?
CAIN T2,":" ;?
JRST RDFLDX ;YES
CAIN T2,.CHCRT ;EOL?
JRST PEOLX ;ERROR
IFE STANSW,<
BIN% ;SKIP TWS
ERJMP PEOF
>;IFE STANSW
IFN STANSW,<
CALL GBCH ;SKIP TWS
JRST PEOF
>;IFN STANSW
JRST RDFLDD ;LOOP
RDFLDX: MOVEM T2,TERM ;SAVE TERMINATOR
SETZ T2,
IDPB T2,PTR ;NULL TERMINATE THE STRING
MOVE T1,COUNT ;GET SIZE OF FIELD
RET
ENDSV.
;SKPFLD - Skip to next field (next ":").
SKPFLD: MOVE T1,HTBJFN
IFE STANSW,<
SKPFL1: BIN% ;READ A BYTE
ERJMP PEOF
>;IFE STANSW
IFN STANSW,<
SKPFL1: CALL GBCH ;READ A BYTE
JRST PEOF
>;IFN STANSW
CAIN T2,":" ;START OF NEW FIELD?
RET ;YES, DONE
CAIN T2,.CHCRT ;END OF LINE?
JRST PEOLX ;YES SO ERROR
JRST SKPFL1 ;NO, CONTINUE
;RDHNUM - Read a host number.
;returns number in T1
RDHNUM: STKVAR <COUNT,HOST>
CALL RDFLD ;Read in a field
JUMPE T1,RDHNE1
MOVEI T1,4 ;Size of a number (bytes)
MOVEM T1,COUNT ;Save
SETZM HOST
MOVE T1,[POINT 7,TMPBUF]
MOVX T3,^D10 ;Read in decimal
RDHNM3:
NIN% ;Read part of number
ERJMP RDHNE2
EXCH T2,HOST ;Get part read so far
LSH T2,^D8 ;Shift over
ADDM T2,HOST ;Add in new part
SOSLE COUNT ;Decrement count
JRST RDHNM3 ;Loop
MOVE T1,HOST ;Get number back
RET ;And return
ENDSV.
;ERROR handlers for HSTINI and friends
HSTIE1: ;ERROR ON OPENF
MOVE T1,HTBJFN ;RECOVER THE JFN
RLJFN% ;RELEASE THE JFN
ERJMP .+1 ;IGNORE ERRORS
IFN STANSW,<
CALL ULKGTH ;UNLOCK HOST TABLE
>;IFN STANSW
RET ;RETURN TO CALLER
HSTIE2: TMSG <Number tables full before end of file
>
JRST HFILER
HSTIE3: TMSG <Null name not allowed
>
JRST HFILER
HSTIE4: TMSG <NAME SPACE FULL BEFORE END OF FILE
>
JRST HFILER
HSTIE5: TMSG <Name table full before end of file
>
JRST HFILER
RDHNE1:
TMSG <Null host number
>
JRST HFILER
RDHNE2: TMSG <Bad host number format
>
JRST HFILER
;PEOF -- premature end of file
PEOF: TMSG <Premature end of file
>
JRST HFILER
PEOLX:
TMSG <Premature end of line
>
JRST HFILER
IFN STANSW,<
;PEOLL -- Field too long
PEOLL:
TMSG <Field too long
>
JRST HFILER
>; End of IFN STANSW
;HFILER - Error printout routine.
HFILER: MOVE T1,HTBJFN ;Get JFN
RFPTR% ;Read current file position
ERJMP .+1
IFN STANSW,<
SUB T2,LINCNT ;Adjust for buffered characters
>;IFN STANSW
PUSH P,T2 ;Save
MOVE T2,BOL ;Get start of line pointer
SFPTR% ;...
ERJMP .+1
SUBM T2,0(P) ;Difference
HFILE2:
MOVE T1,HTBJFN
BIN% ;Read a byte
ERJMP HFILDN ;End of file
MOVX T1,.PRIOU
BOUT% ;Write to primary output
ERJMP .+1
SOSE 0(P) ;Count down to error position
JRST HFILE3
MOVEI T2,"^"
BOUT%
ERJMP .+1
HFILE3:
CAIE T2,.CHLFD ;End of line?
JRST HFILE2 ;Loop
;HFILDN - Routine to finish up HOSTS.TXT
HFILDN: ;Here when finished
HRRZ T1,NAMIDX ;Get count of host names
MOVNM T1,MHOSTS ;Save
MOVE T1,HTBJFN ;Get back JFN
CLOSF%
ERJMP .+1
IFN STANSW,<
CALL ULKGTH ;UNLOCK HOST TABLE
>;IFN STANSW
MOVE P,SAVEP ;Get back stack fence
RETSKP ;And return
ENDTV.
;PERROR - Print out the erring line in the file.
;Called P1 - JFN
;P2 - Byte index of BOL
PERROR: MOVE T1,P1
RFPTR ; Read where we are
TRN
MOVE T3,T2 ; Save it in T3
MOVE T2,P2 ; Get BOL pointer
SFPTR ; set back to beginning of line
TRN
PERLP: MOVE T1,P1
RFPTR ; Read where we are
TRN
CAMN T2,T3 ; Are we where error occured?
CALL PMARK ; Yes, Mark it
CALL GCH1 ; Get a character
MOVEI T2,.CHLFD ; Fake EOL if done
CAIN T2,.CHLFD ; End of line?
JRST PERLPX ; Yes, exit
MOVE T1,T2 ; Get caharacter
PBOUT ; Type it out
JRST PERLP ; And loop
; PMARK, Mark where error occured
PMARK: PUSH P,T1 ; Save AC1
MOVEI T1,"^" ; A convenient character
PBOUT ; Write it out
POP P,T1 ; And restore it
RET ; And back to caller
; PERLPX - Done with error line
PERLPX: HRROI T1,[ASCIZ /
/]
PSOUT ; Write a carridge return
RET ; Return when done
;GBOL - Get Set pointer to the beginning of a line.
;Returns +1 if EOF hit
;else +2 with T1 - JFN
;P2 - Byte number of beginning of line
GBOL: MOVE T1,P1 ; Get JFN
CALL GCH ; Get a character
RET
CAIN T2,.CHLFD ; Line feed?
JRST GBOL ; Yes, blank line
BKJFN ; Backup over that character
MOVE T1,P1 ; Restore JFN
RFPTR ; get pointer
NOP
MOVE P2,T2 ; Save it
RETSKP ; And return with it
;GCH - read the next non-comment, non-blank character.
;returns +2 if character (character in T2)
;+1 if EOF
GCH: MOVE T1,P1 ; Get JFN
GCH2: CALL GCH1 ; Get a byte
RET ; EOF
CAIN T2,";" ; Comment,
JRST GCHSMC ; ignore it
CAIE T2,.CHTAB ; TAB?
CAIN T2," " ; or SPACE?
JRST GCH2 ; Skip it
RETSKP ; Else return with character
GCH1: CALL GBIN ; BIN a byte
RET ; EOF
CAIE T2,.CHCRT ; Ignore
CAIN T2,.CHFFD ; and form-feed
JRST GCH1 ; ..
RETSKP ; return with character
GCHSMC: CALL GBIN ; Get a byte
RET ; EOF
CAIN T2,.CHLFD ; Until end of line
RETSKP ; when we return
JRST GCHSMC ; Else lop
GBIN: BIN ; get a char
ERJMP R ; If end of file return +1
JUMPN T2,RSKP ; If good
JRST GBIN ; flush NULLS
SUBTTL GTFIL - GTJFN Routine for HSTINI and ADRINI
;Get a JFN for a file, and setup ACs, used in HSTINI and ADRINI,
;called with T2 pointing to file name returns +2 if successful with
;AC's setup P1 - Contains JFN
GTFIL: MOVX T1,<GJ%OLD+GJ%SHT> ; Olf file, short
GTJFN ; GEt JFN
RET ; Can't file not found
MOVE P1,T1 ;Save JFN in P1
MOVX T2,7B5+OF%RD ; Open for reading
OPENF ; ..
JRST [ MOVE T1,P1 ; If fails, get JFN back
RLJFN ; Release it
NOP
RET]
RETSKP ; Succesful return
SUBTTL ADRINI - Routine to Read SYSTEM:SITE-ADDRESS.TXT
;ADRINI
;Reads in the file SYSTEM:SITE-ADDRESS.TXT and initializes the
;interface tables from it. Called from HSTINI at system startup, does
;skip return if successful.
; AC usage
; P1 - JFN of input file
; P2 - Local address once read
; P3 - NCT associated with that address, if any
ADRINI:: ; Read interface descriptor file
SAVEPQ ; Save registers clobbered
STKVAR <NONUM,<BUFFER,10>>
HRROI T2,[ASCIZ /SYSTEM:INTERNET.ADDRESS/]
CALL GTFIL ; Get the file
RET
SETZ T1, ; clear an index
ADRIN1: SKIPN NLHOST(T1) ; slot used?
JRST ADRLP0 ; no, done with table, enter main loop
SETOM NLHOST(T1) ; empty that slot
AOJA T1,ADRIN1 ; and loop
ADRLP0: CALL GBOL ; Start off a line
JRST ADRDUN ; Done with file
MOVE T1,P1 ; Get JFN
; Now read in the interface type
MOVE T3,[POINT 7,BUFFER] ; point to temp buffer
ADGINM: CALL GCH
JRST ADREOF ; enf of file
CAIN T2,"#" ; end of name?
JRST [ SETZM NONUM ; flag that there is a number
JRST ADGINX] ; and leave loop
CAIN T2,.CHLFD ; end of line?
JRST ADIERR ; error
CAIN T2,"," ; or field delimiter?
JRST [ SETOM NONUM ; flag that number is 0
JRST ADGINX] ; and join below
IDPB T2,T3 ; save character in string
JRST ADGINM ; and loop
; Here if error in interface descriptor
ADIERR: HRROI T1,[ASCIZ /Error in interface descriptor/]
JRST ADRERR ; goto error printer
ADGINX: SETZ T2, ; put a null
IDPB T2,T3 ; at end
MOVEI T1,INTNAM ; point to type table
MOVE T2,[POINT 7,0] ; make a pointer
ADDI T2,BUFFER ; to the string buffer
TBLUK ; and look it up
TXNE T2,TL%NOM!TL%AMB ; match?
JRST ADIERR ; error
HRRZ T4,(T1) ; get entry
SETZ P3, ; assume no NCT
MOVE T1,P1 ; GET JFN
SKIPE NONUM ; is there a number?
JRST [ SETZ T2, ; no, use 0
JRST ADGIN2] ; and skip reading it
MOVEI T3,^D10 ; read in decimal
NIN
JRST ADIERR ; error
ADGIN2: BKJFN ; Backup over terminator
NOP ; Shouldn't fail
CAIN T4,NT.NIN ; No particular interface?
JRST ADGNUM ; right, No NCT associated with it
; Now find the NCT for the interface
XMOVEI P3,NCTVT ; point to vector table
ADFINT: MOVE P3,(P3) ; get next in list
JUMPE P3,ADIERR ; error if no more
LOAD T1,NTDEV,(P3) ; get interface type
CAIE T1,(T4) ; Same as we're looking for?
JRST ADFINT ; No, try next
SOJGE T2,ADFINT ; Try another if not right number
; Read in the address on that interface
ADGNUM: CALL NXTFLD ; read to the next field
HRROI T4,[ASCIZ/ Invalid address /]
CALL ADG4DB ; Get 4 decimal bytes into T1
; Goes ADRERR on error
MOVEM T1,P2 ; Get into right register
CALL HSTHSH ; Hash it into table
JUMPL T2,NETFUL ; No room for number
MOVEM P2,HOSTNN(T2) ; Put number in table
MOVX CX,HS%UP!HS%SLF!HS%VAL ; It is me , and valid status
IORM CX,HSTSTS(T2) ; Mark it so
; ...
; ...
SETZ T2, ; clear an index
ADGNM1: SKIPLE NLHOST(T2) ; anything in this slot?
AOJA T2,ADGNM1 ; No, try next
SKIPL NLHOST(T2) ; empty?
JRST NETFUL ; No, table overflow.
MOVEM P2,NLHOST(T2) ; save number
JUMPE P3,ADGNM2 ; Skip next if no NCT associated with number
MOVEM P2,NTLADR(P3) ; Set local address
NETNUM T1,P2 ; Get the network number
MOVEM T1,NTNET(P3) ; Set it in NCT
ADGNM2:
MOVE T1,P1 ; get JFN back
BKJFN ; Back over last terminator
NOP
ADRLP3: CALL GCH ; Read it in
JRST ADREOF ; Eof error
CAIN T2,.CHLFD ; Was it a linefeed?
JRST ADRLP0 ; Yes, loop
; Must be a comma, means a type name
MOVE T3,[POINT 7,BUFFER] ; point to buffer
ADGTYP: ; Here to read in a modifier
CALL GCH ; Get first char of keyword
JRST ADREOF ; Error
CAIE T2,"," ; end of field?
CAIN T2,.CHLFD ; line feed?
JRST ADGTYX ; got full field
CAIN T2,":" ; Value?
JRST ADGTYX ; yes
IDPB T2,T3 ; else save in string
JRST ADGTYP ; and loop
ADGTYX: SETZ T2, ; put a null
IDPB T2,T3 ; at end of string
MOVEI T1,TYPNAM ; point to type table
MOVE T2,[POINT 7,0] ; and to string
ADDI T2,BUFFER ; in the buffer
TBLUK ; and look it up in table
TXNE T2,TL%NOM!TL%AMB ; good name?
JRST [ HRROI T1,[asciz /Bad network type descriptor/]
JRST ADRERR] ; no
MOVE T1,(T1) ; get routine address
CALL (T1) ; go to it
MOVE T1,P1 ; Get JFN
BKJFN ; Back up
NOP ; shouldn't fail
JRST ADRLP3 ; and loop
ADDFLT: ; Here on DEFAULT keyword
NETNUM T1,P2 ; Get the network number
MOVEM T1,DEFNET ; Save as default network number
SKIPN PRFNET ; Preferred network set up?
MOVEM T1,PRFNET ; Save as preferred network number
MOVE T2,P2 ; Get number
ANDX T2,-1B27 ; mask off network number (Class C)
CAIG T1,177777 ; Class B or A?
ANDX T2,-1B19 ; Mask for class B
CAIG T1,377 ; Class A?
ANDX T2,-1B11 ; yes, mask appropriately
MOVEM T2,NETFLD ; Set as default network field
MOVEM P2,DEFADR ; Save as default address
SKIPN PRFNFD ; Preferred network field set up?
MOVEM T2,PRFNFD ; Set as preferred network field
SKIPN PRFADR ; Preferred address set up?
MOVEM P2,PRFADR ; Save as preferred address
; Kludge up the 8 bit host address
MOVE T2,P2 ; get number again
ROTC T2,-6 ; Save IMP number
LSH T2,-^D10 ; Flush middle bits
ROTC T2,6 ; Combine Host and IMP
ANDI T2,377 ; Round to 8 bits
MOVEM T2,NOHOST ; Save in proper cell
RET ; and return
ADDPRF: ; Here on PREFERRED keyword
NETNUM T1,P2 ; Get the network number
MOVEM T1,PRFNET ; Save as preferred network number
MOVE T2,P2 ; Get number
ANDX T2,-1B27 ; mask off network number (Class C)
CAIG T1,177777 ; Class B or A?
ANDX T2,-1B19 ; Mask for class B
CAIG T1,377 ; Class A?
ANDX T2,-1B11 ; yes, mask appropriately
MOVEM T2,PRFNFD ; Set as preferred network field
MOVEM P2,PRFADR ; Save as preferred address
RET
ADNCP: ; Here on NCP keyword
MOVEI T1,NT.NCP ; get NCP network type
STOR T1,NTTYP,(P3) ; save in NCT
MOVE T1,NTNET(P3) ; Get the network number
CAILE T1,^D255 ; Valid type A address?
JFCL ; error ***
; once host tables are right, find hosts for this net and set in NCP tables
RET ; and done
IFN STANSW,<
; Here on the ETHERNET and ETHER3MB keywords
ADD3MB: SKIPA T1,[NT.3MB] ; network type is 3MB Ethernet
ADDETH: MOVEI T1,NT.ETH ; network type is 10MB Ethernet
STOR T1,NTTYP,(P3) ; save in NCT
RET ; no more to do
; Here on the HARDWARE keyword to read our 10MB Ethernet hardware address
ADDHDW: HRROI T4,[ASCIZ/ Invalid hardware address /]
CALL ADG4DB ; Get first four bytes of hardware address
STOR T1,HRDW0,(P3) ; Store in NCT
HRROI T4,[ASCIZ/ Invalid hardware address /]
CALL ADG2DB ; Get last two bytes of hardware address
STOR T1,HRDW1,(P3) ; Store in NCT
RET ; return to caller
>;IFN STANSW
; Here on PACKET-SIZE keyword, next parameter is the maximum packet
; size for this interface in decimal bytes
ADPSIZ: MOVE T1,P1 ; Get JFN
MOVEI T3,^D10 ; decimal
NIN
JRST [ HRROI T1,[ASCIZ /Invalid PACKET-SIZE /]
JRST ADRERR] ; error
MOVEM T2,NTPSIZ(P3) ; save the size
RET ; and return
; Here on LOGICAL-HOST-MASK keyword, next parameter is the 32-bit mask
; for this interface in decimal bytes
ADLHM: HRROI T4,[ASCIZ / Invalid LOGICAL-HOST-MASK value field/]
CALL ADG4DB ; Read 4 decimal bytes
; Goes ADRERR on error
MOVEM T1,NTNLHM(P3) ; Save the mask
RET ; and return
; ADG4DB - Read in 4 decimal bytes
; T4/ String pointer to error message
; P1/ JFN
; Returns+1 Success, T1 has address
; ADRERR Error detected
IFN STANSW,<
;ADG2DB - entry point used by ADDHDW to read two decimal bytes
ADG2DB: PUSH P,BHC ; Push a zero onto the stack
MOVEI Q1,2 ; Want only two decimal bytes
JRST ADG4D2 ; Join main code
>;IFN STANSW
ADG4DB: PUSH P,BHC ; Save a blank
MOVEI Q1,4 ; There are 4 fields to an address
ADG4D2: MOVE T1,P1 ; Get JFN back
MOVX T3,^D10 ; Again decimal
NIN
JRST [ADJSP P,-2 ; Pop address & return
MOVE T1,T4 ; Error message
JRST ADRERR] ; Error exit
IORM T2,0(P) ; Merge in latest part
SOJLE Q1,ADG4D8 ; All parts read?
MOVE T2,0(P) ; No, get so far
LSH T2,^D8 ; Shift over one byte
MOVEM T2,0(P) ; Store back
JRST ADG4D2 ; Loop through all 4 fields
ADG4D8: POP P,T1 ; Get full address
RET
; Error handler routine
NETFUL: POP P,T4 ; Clean stack
BUG.(HLT,NORMIA,MNETDV,SOFT,<No room in host tables for local address>,,<
Cause: Multinet is unable to allocate space in the network hash table for
a local address from the SYSTEM:INTERNET.ADDRESS file.
>)
HRROI T1,[ASCIZ /No room in host tables for local address/]
ADRERR: PSOUT ; Write error string
HRROI T1,[ASCIZ / In ADDRESS file
/]
PSOUT
CALL PERROR ; Print offending line
JRST ADRLP0 ; And loop
ADREOF: HRROI T1,[ASCIZ /Premature EOF in ADDRESS file/]
PSOUT
CALL PERROR ; Print bad line
ADRDUN: CLOSF ; Close the JFN
NOP ; Don't worry if fails
MOVE P2,NLHOST+0 ; Get default default network
SKIPN DEFADR ; was default address set?
CALL ADDFLT ; No, use this one
RETSKP ; And return succesfully
; Here to skip to the next field of keyword
NXTFLD: CALL GCH ; Get character
RET ; Return now if EOF
CAIE B,"," ; comma?
CAIN B,.CHLFD ; EOL?
RET ; yes, return now
JRST NXTFLD ; else read more
; Tables for address file keywords
; Start a table definition
DEFINE TABLE(NAME)<
NAME: XWD ..'NAME,..'NAME
..TABLE==0 ; Init count
>
DEFINE TABEND(NAME)
< ..'NAME==..TABLE>
DEFINE KEY(NAME,DATA)
< XWD [ASCIZ /NAME/],DATA
..TABLE==..TABLE+1 ; Increment the count of entries
>
; Table of interface type names
TABLE(INTNAM)
KEY AN20,NT.ANX ; AN20 Interface
KEY IPCI,NT.CIP ; KLIPA Interface
KEY IPNI,NT.NIP ; KLNI Interface
IFN STANSW,<
KEY MEIS,NT.MEI ; MEIS Interface
>;IFN STANSW
TABEND(INTNAM)
; Take of modifiers
TABLE(TYPNAM)
KEY DEFAULT,ADDFLT ; This is the 'primary' address for host
IFN STANSW,<
KEY ETHER3MB,ADD3MB ; 3MB Ethernet protocols
KEY ETHERNET,ADDETH ; 10MB Ethernet protocols
KEY HARDWARE,ADDHDW ; 10MB Ethernet hardware address
>;IFN STANSW
KEY LOGICAL-HOST-MASK,ADLHM ; Logical host mask for this network
KEY NCP,ADNCP ; network uses Arpanet NCP protocal
KEY PACKET-SIZE,ADPSIZ ; Maximum packet size allowed
KEY PREFERRED,ADDPRF ; This is the 'preferred' address for host
TABEND(TYPNAM)
SUBTTL CVHST% JSYS - Convert Host Number to String
REPEAT 1,< ;THIS JSYS IS VERY TEMPORARY
XNENT (.CVHST,G)
MCENT
SETOB P1,P2 ;NO NAME YET
MOVE T1,T2 ;GET HOST NUMBER IN RIGHT PLACE
CALL GTHNTS ;CONVERT NUMBER TO STRING
JUMPL P1,[EMRETN(CVHST1)] ;STRING NOT FOUND
LOAD P4,HSTNMP,(P1) ;GET THE NAME POINTER
SETSEC P4,INTSEC ;INTO PROPER SECTION
ADDI P4,HSTNAM ;POINT TO NAME
MOVE P3,[<POINT 7,0>!1B12] ;EXTENDED POINTER WORD
UMOVE T1,1 ;GET DESINATION
CALL GTHSOU ;WRITE STRING TO USER SPACE
UMOVEM T1,1 ;WRITE UPDATED POINTER TO USER SPACE
JRST SKMRTN
>
SUBTTL GTHST% JSYS
;The GTHST% JSYS, Get information on a Host or Network, Moved here
;from NETWRK because expansion allows it to be general over all
;Interfaces rather than just NCP. Called as in JSYS documentation
;The following register conventions are used in it
;
;P1 - Index into Name tables
;P2 - Index into Hash tables
;P3,P4 - Byte pointers (extended or otherwise)
;P5,P6 - Scratch
IFE STANSW,<
XNENT (.GTHST,G)
MCENT
SKIPL T1 ;CHECK RANGE OF FUNCTION CODE
CAIL T1,GTHMAX
RETERR (ARGX02) ;BAD FUNCTION CODE
SETOB P1,P2 ;NO NUMBER NOR NAME
XCT GTHDSP(T1) ;DO THE FUNCTION
GTHDSP: JRST GTHSIZ ;(00)GET NAME TABLE SIZE
JRST GTHIDX ;(01)INDEX INTO NAME SPACE
JRST GTHNUM ;(02)CONVERT NUMBER TO STRING
JRST GTHSTR ;(03)CONVERT STRING TO NUMBER
JRST GTHHNN ;(04)STATUS BY NUMBER
JRST GTHHNI ;(05)STATUS BY INDEX
JRST GTHNHN ;(06)Get local number on a network
JRST GTHNST ;(07)Get status table of a network
JRST GTHNLA ;(10)Get local addresses on networks
GTHMAX==.-GTHDSP ;NUMBER OF FUNCTIONS
GTHSXX: MOVX T4,HS%NCK ;SET THE NICKNAME FLAG
SKIPL P1 ;NO NAME
SKIPL HOSTN(P1) ;DID WE HAVE ONE?
SKIPA T4,HSTSTS(P2) ;NO
IOR T4,HSTSTS(P2) ;RETURN STATUS
UMOVEM T4,4
MOVE T3,HOSTNN(P2) ;RETURN HOST NUMBER
UMOVEM T3,3
JRST SKMRTN ;SKIP RETURN
SUBTTL GTHST% JSYS - Individual Functions
GTHSIZ: HRLZ T2,MHOSTS ;-LENGTH,,1ST INDEX
UMOVEM T2,2 ;RETURN TO USER
MOVSI T3,-NHOSTS ;NUMBER OF HOST SLOTS
UMOVEM T3,3 ;RETURN TO USER
MOVE T4,PRFADR ;GET PREFERRED ADDRESS
UMOVEM T4,4 ;RETURN TO USER
JRST SKMRTN ;DONE
GTHIDX: MOVN T1,MHOSTS ;GET NUMBER OF HOST NAMES IN USE
HRRZ P1,T3 ;CHECK RANGE OF HOST NAME INDEX
CAML P1,T1
RETERR (GTJIX1) ;BAD INDEX TO HOSTN
SETSEC P1,INTSEC ;IN THE RIGHT SECTION
LOAD P2,HSTIDX,(P1) ;GET INDEX INTO HOSTNN
SETSEC P2,INTSEC ;AND IN THE PROPER SECTION
JRST GTHTUS ;WRITE THE STRING
GTHNUM: MOVE T1,T3 ;GET HOST NUMBER
CALL GTHNTS ;CONVERT NUMBER TO STRING
JUMPL P1,[RETERR(GTHSX3)] ;NO STRING FOR THAT NUMBER
; Write host string to user space
GTHTUS: LOAD P4,HSTNMP,(P1) ;GET THE NAME POINTER
SETSEC P4,INTSEC ;INTO PROPER SECTION
ADDI P4,HSTNAM ;POINT TO NAME
MOVE P3,[<POINT 7,0>!1B12] ;EXTENDED POINTER WORD
UMOVE T1,2 ;GET DEST
CALL GTHSOU ;WRITE STRING
UMOVEM T1,2 ;UPDATE USER'S POINTER
JRST GTHSXX ;EXIT
GTHNTS: CALL CVNHST ;MAKE IT NEW FORMAT
CALL HSTHSH ;GET ITS INDEX
RET ;NOT THERE
MOVE P2,T2 ;SAVE INDEX
SKIPG P1,HOSTPN(T2) ;HAS IT A NAME?
SETO P1, ;NO
RET
GTHSTR: CALL GTHSTN ;CONVERT STRING TO NUMBER
SKIPL T2 ;VAILD STRING FOUND?
RETERR(GTHSX5) ; no, return error
MOVE P1,T2 ; Save
SETSEC P1,INTSEC ; in the right section
SKIPN T1,T4 ;COPY HOST NUMBER
RETERR(GTHSX2) ;NO HOST FOUND....ERROR
CALL CVNHST ; Convert number to 32 bits if necessary
CALL HSTHSH ; Look it up in tables
RETERR(GTHSX2) ; Not there
MOVE P2,T2 ; Save that index
JRST GTHSXX ;EXIT
; Convert host string to a number
GTHSTN: STKVAR <<GTHSBF,10>>
MOVEI P3,GTHSBF ; Point to buffer
HRLI P3,(<POINT 7,0>) ; ....
CALL GTHSIN ;GET STRING FROM USER
MOVEI T1,GTHSBF ;MAKE BYTE POINTER
HRLI T1,(<POINT 7,0>)
CALLRET HSTLUK ;LOOKUP NAME
GTHHNI: HRRZ T1,T3 ;GET INDEX
CAIL T1,NHOSTS ; Compare to table size
RETERR (GTJIX1) ; Bad index
SETSEC T1,INTSEC ; Put in proper section
LOAD T1,HSTIDX,(T1) ; get index to tables
SETSEC T1,INTSEC ; Again in right section
SKIPA T1,HOSTNN(T1) ; Get number
GTHHNN: MOVE T1,T3 ;GET HOST NUMBER
CALL GTHNTS ;CONVERT NUMBER TO INDEX
JUMPL P1,[RETERR (GTHSX1)] ;UNKNOWN HOST
JRST GTHSXX ;EXIT
; Move string from user space
GTHSIN: UMOVE T1,2 ; GET POINTER
MOVE T4,[XCTBU [ILDB T2,T1]]
TLNN T1,777777 ; IF JFN DO THE JSYS
MOVE T4,[BIN]
TLC T1,777777 ; CHECK FOR LH -1
TLCN T1,777777
HRLI T1,(<POINT 7,0>) ; USE STANDARD POINTER
MOVEI P5,MAXLC ; UP TO 39 CHARS
GTHSIL: XCT T4 ; DO RIGHT OPERATION
SOSG P5 ; Decrement counter
MOVEI T2,0 ; AFTER MAXLC CHARS FORCE NULL
CAIL T2,140 ; LOWER CASE?
TRZ T2,40 ; YES, RAISE
CAIG T2,40 ; END ON SPACE OR LESS
MOVEI T2,0 ; terminating with null
IDPB T2,P3 ; Stick it in destination string
JUMPG T2,GTHSIL ; loop if more to it
CAME T4,[BIN] ; DON'T BACKUP A TTY
BKJFN ; backup to before termination
NOP ; (shouldn't fail)
UMOVEM T1,2 ; restore updated pointer
RET ; and return
; Write string to user space
; Called with T1 - Dest in user space
; Returns +1 T1 updated pointer
GTHSOU: MOVE T4,[XCTBU [IDPB T2,T1]]
TLNN T1,777777 ; IF JFN DO THE JSYS
MOVE T4,[BOUT]
TLC T1,777777 ; CHECK FOR LH -1
TLCN T1,777777
HRLI T1,(<POINT 7,0>) ; USE STANDARD POINTER
GTHSOL: ILDB T2,P3 ; Get next byte
JUMPE T2,GTHSOX ; If a null
XCT T4 ; DO RIGHT OPERATION
JRST GTHSOL ; Loop
GTHSOX: CAMN T4,[BOUT] ; Don't backup a JFN
RET ; Retrun now if a JFN
XCT T4 ; Stick on NULL
BKJFN ; Backup destination
NOP ; ...
RET ; and return
; Get hostnumber on a network
; Accepts T2 - Network number, or host number on the net
; Returns +1 if no interface on that network
; +2 if we have one, T2 - Hostnumber
GTHNHN: MOVE T1,T2 ; Get number
CALL NETNCT ; Look for an NCT for that net
RETERR (GTHSX5) ; Return error if none
MOVE T1,NTLADR(P1) ; Get our number there
UMOVEM T1,T2 ; Restore it to user
JRST SKMRTN ; And do a skip return
; Get status of a network
; Accepts T2 - Network number or host number on the net
; T3 - Pointer to where to store data
; T4 - -Number of words,,offset of first
; Returns +1 if no such network or invalid offset
; +2 if good arguments with data in table
GTHNST: MOVE T1,T2 ; Get number
CALL NETNCT ; Look it up
RETERR(GTHSX5) ; Bad number
HLRE T1,T4 ; Get number wanted
MOVMS T1 ; Magnitude
ADDI T1,(T4) ; Add in first
CAILE T1,NTXUPP-NTRDY+1 ; Size of area
RETERR(GTJIX1) ; Bad
XMOVEI P1,NTRDY(P1) ; Point to start of area
ADDI P1,(T4) ; Add in offset of fist word
XCTU [HRR T4,T3] ; Setup an AOBJN destination pointer
GTHNS0: MOVE T1,0(P1) ; get a word
UMOVEM T1,0(T4) ; Store it
AOS P1 ; Increment source pointer
AOBJN T4,GTHNS0 ; And loop through all desired
JRST SKMRTN ; And do a skip return
; Get Local Network Addresses
; Accepts T3/ Address of where to store data
; T4/ Number of words
; Returns +1 if invalid offset
; +2 if good arguments with data in table
; Updates callers T4 count of items returned.
GTHNLA: ; Get local addresses
SKIPG T4 ; Legit count?
RETERR(ARGX24) ; No
MOVE P1,NCTVT ; Get address of the first NCT
JRST GTHLA3 ; Report on this NCT
GTHLA1: ; Get the next NCT
LOAD P1,NTLNK,(P1) ; Get address of the next NCT
JUMPN P1,GTHLA3 ; Go report on this NCT
GTHLA2: ; Here when all NCTs examined
XCTU [SUB T4,4] ; Fix up the count
XCTU [MOVNM T4,4] ; Save the count for the caller
JRST SKMRTN ; And do a skip return
GTHLA3: ; NCT Chasing loop
SKIPG T1,NTLADR(P1) ; Get address on this NCT
JRST GTHLA1 ; No address defined. get next NCT.
UMOVEM T1,(T3) ; Save interface address for user
SOJLE T4,GTHLA2 ; Count exhausted?
AOJA T3,GTHLA1 ; No so do the next NCT
>;IFE STANSW
IFN STANSW,<
RS GTHLCK,1 ;LOCK ON HOST TABLE
XNENT (.GTHST,G)
MCENT ;ENTER MONITOR CONTEXT
SKIPL T1 ;CHECK RANGE OF FUNCTION CODE
CAIL T1,GTHMAX
RETERR (ARGX02) ;BAD FUNCTION CODE
SETOB P1,P2 ;NO NUMBER NOR NAME
CALL LCKGTH ;WAIT UNTIL EXCLUSIVE LOCK ON HOST TABLE
CALL @GTHDSP(T1) ;DO THE FUNCTION
RETERR (,<CALL ULKGTH>) ;PASS BACK ERROR, UNLOCK TABLE
CALL ULKGTH ;UNLOCK TABLE
SMRETN ;WE SUCCEEDED, SO SKIP RETURN
;LCKGTH - LOCK HOST TABLE
;RETURNS +1 ALWAYS, TABLE LOCKED AND PROCESS NOINT
LCKGTH: SAVET ;DON'T CLOBBER ANY TEMPORARIES
LCKGT0: NOINT ;TURN OFF PSI
AOSN GTHLCK ;TRY FOR EXCLUSIVE LOCK
RET ;GOT IT. RETURN NOINT
OKINT ;FAILED, TURN PSI BACK ON
MOVEI T1,GTHLCK ;ADDRESS OF LOCK WORD
CALL DISL ;DISMISS UNTIL IT IS -1 (FREE)
JRST LCKGT0 ;TRY AGAIN
;ULKGTH - UNLOCK HOST TABLE
;RETURNS +1 ALWAYS, TABLE UNLOCKED, INTDF DECREMENTED
ULKGTH: SETOM GTHLCK ;CLEAR LOCK
OKINT ;REALLOW INTERRUPTS
RET ;RETURN
GTHDSP: NCTDSP GTHSIZ ;(00)GET NAME TABLE SIZE
NCTDSP GTHIDX ;(01)INDEX INTO NAME SPACE
NCTDSP GTHNUM ;(02)CONVERT NUMBER TO STRING
NCTDSP GTHSTR ;(03)CONVERT STRING TO NUMBER
NCTDSP GTHHNN ;(04)STATUS BY NUMBER
NCTDSP GTHHNI ;(05)STATUS BY INDEX
NCTDSP GTHNHN ;(06)Get local number on a network
NCTDSP GTHNST ;(07)Get status table of a network
NCTDSP GTHNLA ;(10)Get local addresses on networks
GTHMAX==.-GTHDSP ;NUMBER OF FUNCTIONS
GTHSXX: MOVX T4,HS%NCK ;SET THE NICKNAME FLAG
SKIPL P1 ;NO NAME
SKIPL HOSTN(P1) ;DID WE HAVE ONE?
SKIPA T4,HSTSTS(P2) ;NO
IOR T4,HSTSTS(P2) ;RETURN STATUS
UMOVEM T4,4
MOVE T3,HOSTNN(P2) ;RETURN HOST NUMBER
UMOVEM T3,3
RETSKP ;SKIP RETURN TO JACKET ROUTINE
SUBTTL GTHST% JSYS - Individual Functions
GTHSIZ: HRLZ T2,MHOSTS ;-LENGTH,,1ST INDEX
UMOVEM T2,2 ;RETURN TO USER
MOVSI T3,-NHOSTS ;NUMBER OF HOST SLOTS
UMOVEM T3,3 ;RETURN TO USER
MOVE T4,PRFADR ;GET PREFERRED ADDRESS
UMOVEM T4,4 ;RETURN TO USER
RETSKP ;DONE, RETURN TO JACKET ROUTINE
GTHIDX: MOVN T1,MHOSTS ;GET NUMBER OF HOST NAMES IN USE
HRRZ P1,T3 ;CHECK RANGE OF HOST NAME INDEX
CAML P1,T1
RETBAD (GTJIX1) ;BAD INDEX TO HOSTN
SETSEC P1,INTSEC ;IN THE RIGHT SECTION
LOAD P2,HSTIDX,(P1) ;GET INDEX INTO HOSTNN
SETSEC P2,INTSEC ;AND IN THE PROPER SECTION
JRST GTHTUS ;WRITE THE STRING
GTHNUM: MOVE T1,T3 ;GET HOST NUMBER
CALL GTHNTS ;CONVERT NUMBER TO STRING
JUMPL P1,[RETBAD(GTHSX3)] ;NO STRING FOR THAT NUMBER
; JRST GTHTUS
; fall through
; Write host string to user space
GTHTUS: LOAD P4,HSTNMP,(P1) ;GET THE NAME POINTER
SETSEC P4,INTSEC ;INTO PROPER SECTION
ADDI P4,HSTNAM ;POINT TO NAME
MOVE P3,[<POINT 7,0>!1B12] ;EXTENDED POINTER WORD
UMOVE T1,2 ;GET DEST
CALL GTHSOU ;WRITE STRING
UMOVEM T1,2 ;UPDATE USER'S POINTER
JRST GTHSXX ;EXIT
GTHNTS: CALL CVNHST ;MAKE IT NEW FORMAT
CALL HSTHSH ;GET ITS INDEX
RET ;NOT THERE
MOVE P2,T2 ;SAVE INDEX
SKIPG P1,HOSTPN(T2) ;HAS IT A NAME?
SETO P1, ;NO
RET
GTHSTR: CALL GTHSTN ;CONVERT STRING TO NUMBER
SKIPL T2 ;VAILD STRING FOUND?
RETBAD(GTHSX5) ; no, return error
MOVE P1,T2 ; Save
SETSEC P1,INTSEC ; in the right section
SKIPN T1,T4 ;COPY HOST NUMBER
RETBAD(GTHSX2) ;NO HOST FOUND....ERROR
CALL CVNHST ; Convert number to 32 bits if necessary
CALL HSTHSH ; Look it up in tables
RETBAD(GTHSX2) ; Not there
MOVE P2,T2 ; Save that index
JRST GTHSXX ;EXIT
; Convert host string to a number
GTHSTN: STKVAR <<GTHSBF,10>>
MOVEI P3,GTHSBF ; Point to buffer
HRLI P3,(<POINT 7,0>) ; ....
CALL GTHSIN ;GET STRING FROM USER
MOVEI T1,GTHSBF ;MAKE BYTE POINTER
HRLI T1,(<POINT 7,0>)
CALLRET HSTLUK ;LOOKUP NAME
GTHHNI: HRRZ T1,T3 ;GET INDEX
CAIL T1,NHOSTS ; Compare to table size
RETBAD (GTJIX1) ; Bad index
SETSEC T1,INTSEC ; Put in proper section
LOAD T1,HSTIDX,(T1) ; get index to tables
SETSEC T1,INTSEC ; Again in right section
SKIPA T1,HOSTNN(T1) ; Get number
GTHHNN: MOVE T1,T3 ;GET HOST NUMBER
CALL GTHNTS ;CONVERT NUMBER TO INDEX
JUMPL P2,[RETBAD (GTHSX1)] ;UNKNOWN HOST
JRST GTHSXX ;EXIT
; Move string from user space
GTHSIN: UMOVE T1,2 ; GET POINTER
MOVE T4,[XCTBU [ILDB T2,T1]]
TLNN T1,777777 ; IF JFN DO THE JSYS
MOVE T4,[BIN]
TLC T1,777777 ; CHECK FOR LH -1
TLCN T1,777777
HRLI T1,(<POINT 7,0>) ; USE STANDARD POINTER
MOVEI P5,MAXLC ; UP TO 39 CHARS
GTHSIL: XCT T4 ; DO RIGHT OPERATION
SOSG P5 ; Decrement counter
MOVEI T2,0 ; AFTER MAXLC CHARS FORCE NULL
CAIL T2,140 ; LOWER CASE?
TRZ T2,40 ; YES, RAISE
CAIG T2,40 ; END ON SPACE OR LESS
MOVEI T2,0 ; terminating with null
IDPB T2,P3 ; Stick it in destination string
JUMPG T2,GTHSIL ; loop if more to it
CAME T4,[BIN] ; DON'T BACKUP A TTY
BKJFN ; backup to before termination
NOP ; (shouldn't fail)
UMOVEM T1,2 ; restore updated pointer
RET ; and return
; Write string to user space
; Called with T1 - Dest in user space
; Returns +1 T1 updated pointer
GTHSOU: MOVE T4,[XCTBU [IDPB T2,T1]]
TLNN T1,777777 ; IF JFN DO THE JSYS
MOVE T4,[BOUT]
TLC T1,777777 ; CHECK FOR LH -1
TLCN T1,777777
HRLI T1,(<POINT 7,0>) ; USE STANDARD POINTER
GTHSOL: ILDB T2,P3 ; Get next byte
JUMPE T2,GTHSOX ; If a null
XCT T4 ; DO RIGHT OPERATION
JRST GTHSOL ; Loop
GTHSOX: CAMN T4,[BOUT] ; Don't backup a JFN
RET ; Retrun now if a JFN
XCT T4 ; Stick on NULL
BKJFN ; Backup destination
NOP ; ...
RET ; and return
; Get hostnumber on a network
; Accepts T2 - Network number, or host number on the net
; Returns +1 if no interface on that network
; +2 if we have one, T2 - Hostnumber
GTHNHN: MOVE T1,T2 ; Get number
CALL NETNCT ; Look for an NCT for that net
RETBAD (GTHSX5) ; Return error if none
MOVE T1,NTLADR(P1) ; Get our number there
UMOVEM T1,T2 ; Restore it to user
RETSKP ; And do a skip return
; Get status of a network
; Accepts T2 - Network number or host number on the net
; T3 - Pointer to where to store data
; T4 - -Number of words,,offset of first
; Returns +1 if no such network or invalid offset
; +2 if good arguments with data in table
GTHNST: MOVE T1,T2 ; Get number
CALL NETNCT ; Look it up
RETBAD(GTHSX5) ; Bad number
HLRE T1,T4 ; Get number wanted
MOVMS T1 ; Magnitude
ADDI T1,(T4) ; Add in first
CAILE T1,NTXUPP-NTRDY+1 ; Size of area
RETBAD(GTJIX1) ; Bad
XMOVEI P1,NTRDY(P1) ; Point to start of area
ADDI P1,(T4) ; Add in offset of fist word
XCTU [HRR T4,T3] ; Setup an AOBJN destination pointer
GTHNS0: MOVE T1,0(P1) ; get a word
UMOVEM T1,0(T4) ; Store it
AOS P1 ; Increment source pointer
AOBJN T4,GTHNS0 ; And loop through all desired
RETSKP ; And do a skip return
; Get Local Network Addresses
; Accepts T3/ Address of where to store data
; T4/ Number of words
; Returns +1 if invalid offset
; +2 if good arguments with data in table
; Updates callers T4 count of items returned.
GTHNLA: ; Get local addresses
SKIPG T4 ; Legit count?
RETBAD(ARGX24) ; No
MOVE P1,NCTVT ; Get address of the first NCT
JRST GTHLA3 ; Report on this NCT
GTHLA1: ; Get the next NCT
LOAD P1,NTLNK,(P1) ; Get address of the next NCT
JUMPN P1,GTHLA3 ; Go report on this NCT
GTHLA2: ; Here when all NCTs examined
XCTU [SUB T4,4] ; Fix up the count
XCTU [MOVNM T4,4] ; Save the count for the caller
RETSKP ; And do a skip return
GTHLA3: ; NCT Chasing loop
SKIPG T1,NTLADR(P1) ; Get address on this NCT
JRST GTHLA1 ; No address defined. get next NCT.
UMOVEM T1,(T3) ; Save interface address for user
SOJLE T4,GTHLA2 ; Count exhausted?
AOJA T3,GTHLA1 ; No so do the next NCT
>;IFN STANSW
SUBTTL ATNVT% JSYS and NETRDY GETAB Table
; ATtach connection to NVT
; Call: 1 ; [Receive] jfn of opened network connection (JCN for TCP)
; 2 ; Send jfn of open network connection (NCP only)
; ATNVT
; Returns
; +1 ; Cannot attach
; +2 ; Ok. the jfn is released, ac 1 has line number of
; ; Attached pty.
XNENT (.ATNVT,G)
MCENT
TXNE T1,AN%TCP ; Attach TCP Virtual Terminal?
JRST TATNVT ; Yes, go to TCP code
IFE STANSW&PUPSW,<
XJRST [MSEC1,,TVTJFN] ; we were given a JFN
>;IFE STANSW&PUPSW
IFN STANSW&PUPSW,<
JFN==11
XCTU [HRRZ JFN,1] ; Get user's JFN
CALLX (MSEC1,CHKJFN) ; Check it
RETERR(ATNX1) ; Bogus JFN. "Invalid receive JFN"
RETERR(ATNX1) ; TTY:, "Invalid receive JFN"
RETERR(ATNX1) ; Byte pointer or NUL:, "Invalid receive JFN"
CALLX (MSEC1,UNLCKF) ; Unlock JFN
HRRZ T1,FILDEV(JFN) ; Get DTB
CAIN T1,TCPDTB ; TCP: device?
XJRST [MSEC1,,TVTJFN] ; Yes, go to TCP code
CAIN T1,PUPDTB ; PUP: device?
JRST PATNVT ; Yes, go to PUP code
RETERR(ATNX4) ; Neither, return error
>;IFN STANSW&PUPSW
; GNTRDY
; Get the NETRDY table. Attempts to find the data from the NCT for
; the primary network
XNENT (GNTRDY,G)
MOVE T1,DEFADR ; get primary address
CALL NETNCT ; Find an NCT for it
RETERR() ; Error
MOVE T1,@GNTAB(T2) ; get an entry
RET ; And return
; Indirect table for deriving the data
GNTAB: IFIW!<P1>B17+NTRDY ; NETRDY From the NCT
IFIW!<P1>B17+NETON ; As NETON
IFIW+NETENT ; NETENT has its own cell
IFIW!<P1>B17+NTIUPT ; NCPUPT
IFIW+IGDMSG ; Last Imp going down message
IFIW!<P1>B17+NTXDNT ; Last ready line drop
IFIW!<P1>B17+NTXUPP ; last ready line up time
IFIW+IGDTIM ; Last Imp going down message time
SUBTTL HSTLUK - Lookup Host Names
HSTLUK: SAVEPQ ;GET SOME ROOM
MOVE Q1,T1 ;SAVE POINTER
MOVEI T3,10
NIN ;TRY TO GET A NUMBER
JRST HSTLKI ;TRY A NAME
MOVE Q1,T1 ;SAVE UPDATED POINTER
MOVE T1,T2
CALL CVNHST
MOVE T4,T1 ;RETURN HOST NUMBER
MOVE T1,Q1 ;AND UPDATED POINTER
SETZ T2, ;HOST NUMBER FOUND
RET
HSTLKI: HRLZ T2,MHOSTS ;SCAN THE TABLE
PUTSEC P1,INTSEC ;IN THIS SECTION
HSTLK0: MOVE T1,Q1 ;DO NAME POINTER
LOAD T4,HSTNMP,(P1)
ADD T4,[XWD INTSEC,HSTNAM] ;POINT TO THE TABLE
MOVE T3,[<POINT 7,0>!1B12] ;MAKE EXTENDED POINTER
HSTCMP: ILDB Q2,T1 ;COMPARE A STRING
ILDB Q3,T3
SKIPN Q2 ;NULL BYTE?
JUMPE Q3,HSTCM2 ;YES. IS THE OTHER BYTE BYTE ALSO?
CAIN Q2,(Q3) ;NOT NULL. ARE THEY THE SAME?
JRST HSTCMP ;YES SO KEEP COMPARING
HSTLK2:
AOS P1 ;POINT TO NEXT SLOT IN TABLE
AOBJN T2,HSTLK0 ;STEP TO NEXT HOST
SETZ T4, ;NO HOST FOUND
RET
HSTCM2: LOAD T4,HSTIDX,(P1) ;WE HAVE A MATCH. GET THE INDEX
SETSEC T4,INTSEC ;IN THE CORRECT SECTION
MOVE Q3,HSTSTS(T4) ;GET ENTRY STATUS BITS
TXNN Q3,HS%SRV ;HOST NAME?
JRST HSTLK2 ;NO, A GW OR NET. SKIP OVER IT.
MOVE T4,HOSTNN(T4) ;GET THE HOST NUMBER
HRR T2,P1 ;GET THE NAME STRING ADDRESS
RET ;AND RETURN TO CALLER
CVNHST:: ;CONVERT HOST NUMBER IN AC1 TO NEW FORMAT
CAMN T1,[-1] ;IF -1 USE LOCAL HOST NUMBER
MOVE T1,PRFADR ;DEFAULT LOCAL HOST
AND T1,[HSTMSK] ;CUT DOWN TO SIZE
TLNE T1,37700 ;ANY NETWORK NUMBER STUFF?
RET ;YES SO RETURN
ANDI T1,377 ;TURN OFF ALL OTHER BITS
TRZE T1,100 ;SET THE HOST BITS
TRO T1,200000 ;UNITS HOST BIT
TRZE T1,200
TRO T1,400000 ;TWOS HOST BIT
JUMPE T1,R ;IF ZERO LEAVE IT ZERO
IOR T1,NETFLD ;ADD DEFAULT NETWORK NUMBER
RET
TNXEND
END