Trailing-Edge
-
PDP-10 Archives
-
BB-H311D-RM
-
arpanet-sources/mnetdv.mac
There are 10 other files named mnetdv.mac in the archive. Click here to see a list.
; UPD ID= 4961, SNARK:<6.MONITOR>MNETDV.MAC.15, 18-Oct-84 16:14:21 by PAETZOLD
;TCO 6.1.1024 - Add .GTHLA function to GTHST%.
; UPD ID= 4851, SNARK:<6.MONITOR>MNETDV.MAC.14, 17-Sep-84 11:50:34 by PURRETTA
;Update copyright notice
; 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
;GIDNEY::<PAETZOLD.TCP>MNETDV.MAC.3, 16-Mar-84 18:03:06, Edit 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
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1982, 1984.
;ALL RIGHTS RESERVED.
SEARCH ANAUNV,PROLOG
TTITLE MNETDV
IFNDEF REL6,<REL6==:1>
SUBTTL MNTINI - Initialization
SWAPCD
;Called at system startup, initializes tables and storage needed by
;Multinet.
MNTINI::
IFE REL6,<EA.ENT> ; enter section one
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
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>)
CALL HSTINI ;GET THE SYSTEM TO KNOW NAMES OF SITES
BUG.(INF,NOHSTN,MNETDV,SOFT,<HSTINI failed to find host name file>)
CALL NETHSI ; Initialize the network hash table
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?
SKIPN DEFADR ; Did addresses initialize properly?
JRST MNTINX ; No, return now
JRST MNETON ; 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
CALL MLKMA ; Lock down that page
POP P,T2 ; Rstore
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
MNETON::
SKIPA P1,NCTVT ; Point to vector table
MNTIN2: 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 MNTIN2 ; 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.
MNTCHK::
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>>)
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
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 Number /]
PSOUT
MOVX T1,.PRIOU ; Primary output
MOVE T2,NTNET(P1) ; Get Net number
MOVX T3,^D10 ; output in decimal
NOUT ; ...
NOP ; Shouldn't fail
HRROI T1,[ASCIZ / on/]
SKIPN NETON(P1)
HRROI T1,[ASCIZ / off/]
PSOUT
HRROI T1,[ASCIZ /, Output /]
PSOUT
HRROI T1,[ASCIZ /on/]
SKIPN NTORDY(P1)
HRROI T1,[ASCIZ /off/]
PSOUT
MOVEI T1," "
PBOUT
SETZM NTSTCH(P1)
CALL LGTAD ; Report time of this change
SKIPGE T2,T1 ; If time known
JRST MNTC5X ; Not known.
MOVEI T1,.PRIOU ; Still on CTY
MOVEI T3,0
ODTIM
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
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
RESCD
NTSNDX: BUG.(CHK,BADADR,MNETDV,SOFT,<No NCT for address>,<<T1,ADR>>)
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>)
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
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
RETSKP ; And skip return
;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
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
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
SWAPCD
;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
;MNTHLT - Tell all networks we are going away.
;T1/ Reason, a la 1822
;T2/ GTAD when back up
MNTHLT::
SAVEAC <P1>
PUSH P,T1 ; Save reason and
PUSH P,T2 ; When back up
MOVX T1,<377777777777> ; Stop pings
MOVEM T1,PINGTM ; Save new ping time
; Pass info to each interface
SKIPA P1,NCTVT ; Get pointer to tables
MNTHL2: LOAD P1,NTLNK,(P1) ; Get link
JUMPE P1,MNTHL6 ; If done
DMOVE T1,-1(P) ; Get why/when
MNTCALL NTKILL ; Do halt instruction
JRST MNTHL2 ; Loop through all
MNTHL6: ADJSP P,-2 ; CLEAR STACK
RET
;MNTKIL - Turn hardware off on a specific network.
; T1/ network number, or host address
; T2/ Why, or -1
; T3/ When back up or garbage
; Returns+1 Always, network off instruction executed if network exists
MNTKIL::SAVEAC <P1>
CALL NETNCT ; Get the NCT
RET ; No such net, already off
MOVE T1,T2 ; Why or -1
MOVE T2,T3 ; When back up
MNTCALL NTKILL ; Turn the hardware off
RET ; And return
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
SKIPE T2 ; or 0
HRRZI T2,-1 ; or 0,,-1
MOVEM T2,NETON(P1) ; Set function
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 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
\
HSTINI::
SAVEAC <P1>
TRVAR <HTBJFN,<TMPBUF,10>,NAMPTR,NAMIDX,NAMSPC,NAMCNT,SAVEP,BOL,TERM,HSTS,HBEST,HGOOD,NAMLST,NUMLST,NETMSK,ENTTYP>
MOVEM P,SAVEP ;SAVE A STACK FENCE IN CASE OF ERRORS
MOVX T1,GJ%SHT!GJ%OLD ;GTJFN FLAGS. FILE MUST EXIST.
HRROI T2,[ASCIZ/SYSTEM:HOSTS.TXT/] ;FILENAME
GTJFN% ;LOOK FOR THE FILE
ERJMP R ;FILE NOT FOUND
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,NHOSTS ;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
PUTSEC T4,INTSEC ;MAKE POINTER TO SECTION
MOVEI T2,NHOSTS ;COUNT OF TABLE SIZE
HSTIN4: ;LOOP FOR CLEARING ENTRIES
SETZM HOSTN(T4) ;CLEAR OLD NUMBER
SETZM HOSTNN(T4) ;CLEAR NUMBER
SETZM HSTSTS(T4) ;AND STATUS
SETZM HOSTPN(T4) ;AND PRIMARY NAME
ADDI T4,1 ;INCREMENT POINTER
SOJG T2,HSTIN4 ;AND LOOP THROUGH ALL
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 MESSED UP>)
ENDIF.
MOVEM T2,NETMSK ;SAVE HOST MASK FOR LATER
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/MTIP/],.HSMTP
XWD [ASCIZ/MULTICS/],.HSMLT
XWD [ASCIZ/TAC/],.HSTIP
XWD [ASCIZ/TENEX/],.HS10X
XWD [ASCIZ/TIP/],.HSTIP
XWD [ASCIZ/TOPS10/],.HSDEC
XWD [ASCIZ/TOPS20/],.HST20
XWD [ASCIZ/TOPS20AN/],.HST20
XWD [ASCIZ/UNIX/],.HSUNX
XWD [ASCIZ/WAITS/],.HSDEC
NUMOPS=.-OPSTAB-1
;GBOLX - Move to start of next line
;returns BOL - file pointer of start of this line
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
;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
RDFLD1: BIN% ;READ A BYTE
ERJMP PEOF
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
AOS COUNT ;COUNT IT
BIN% ;READ THE NEXT
ERJMP PEOF ;PREMATURE END OF FILE
JRST RDFLD2 ;CONTINUE
RDFLDD: CAIE T2,"," ;FIELD TERMINATOR SEEN?
CAIN T2,":" ;?
JRST RDFLDX ;YES
CAIN T2,.CHCRT ;EOL?
JRST PEOLX ;ERROR
BIN% ;SKIP TWS
ERJMP PEOF
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
SKPFL1: BIN% ;READ A BYTE
ERJMP PEOF
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
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
;HFILER - Error printout routine.
HFILER: MOVE T1,HTBJFN ;Get JFN
RFPTR% ;Read current file position
ERJMP .+1
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
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::SE1CAL ; Call section 1
SAVEPQ ; Save registers clobbered
STKVAR <NONUM,<BUFFER,10>>
HRROI T2,[ASCIZ /SYSTEM:SITE-ADDRESS.TXT/]
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
; 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
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>)
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
TABEND(INTNAM)
; Take of modifiers
TABLE(TYPNAM)
KEY DEFAULT,ADDFLT ; This is the 'primary' address for host
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
.CVHST::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
.GTHST::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 P2,[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
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.
.ATNVT::MCENT
TXNE T1,AN%TCP ; Attach TCP Virtual Terminal?
JRST TATNVT ; Yes, go to TCP code
JRST TVTJFN ; we were given a JFN
; GNTRDY
; Get the NETRDY table. Attempts to find the data from the NCT for
; the primary network
GNTRDY::
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