perm filename PUPGAT.MAC[S,NET]1 blob
sn#634033 filedate 1981-12-11 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 <PUP>PUPGAT.MAC14 2-SEP-79 16:00:23 EDIT BY TAFT
C00004 00003 GATSRV SNDINF RECINF
C00007 00004 RECIN1 RECIN2 RECIN3 RECIN4 RECIN5
C00011 00005 GATCHK GATCH1 GATCH2 GATCH4 GATCH6 GATCH9
C00015 00006 BLDGIP BLDGI1 BLDGI2 STNXRT STNXR1 STNXR2 GATENT
C00018 00007 GATINI GATIN1 GATIN2 GATIN3 GATIN4 GATIN6
C00023 ENDMK
C⊗;
;<PUP>PUPGAT.MAC;14 2-SEP-79 16:00:23 EDIT BY TAFT
;<PUP>PUPGAT.MAC;13 27-APR-77 12:34:35 EDIT BY TAFT
;<PUP>PUPGAT.MAC;12 18-MAR-77 17:08:43 EDIT BY TAFT
; SEARCH PSVDEF
;<PUP>PUPGAT.MAC;11 30-JAN-77 16:24:34 EDIT BY TAFT
; Do not advertise as being a gateway if ENTFLG is off
;<PUP>PUPGAT.MAC;10 29-OCT-76 14:36:16 EDIT BY TAFT
; Unconditionally update Tenex's RT upon first call to GATCHK
;<PUP>PUPGAT.MAC;9 25-OCT-76 21:30:46 EDIT BY TAFT
; Randomize broadcast interval to avoid getting in sync with
; other gateways.
;<PUP>PUPGAT.MAC;8 20-OCT-76 13:27:31 EDIT BY TAFT
; Remove directly connected net restriction for gateway info
;GATSRV SNDINF RECINF
; Copyright 1979 by Xerox Corporation
TITLE PUPGAT -- GATEWAY INFORMATION SERVER FOR PUPSRV
SUBTTL E. A. Taft / October, 1976
SEARCH PUPDEF,PSVDEF,STENEX
USEVAR TOPVAR,TOPPVR ; This is part of the top fork
; Gateway Information server (socket 2)
GATSRV::CAIN A,200 ; Type = "Are you a gateway"?
JRST SNDINF ; Yes, send info response
CAIN A,201 ; Type = "I am a gateway"?
JRST RECINF ; Yes, absorb info into our RT
TLNE F,(DEBUGF)
ELOG <Illegal Pup Type %1O from %2P>
POPJ P,
; Send response to "Are you a gateway" packet
SNDINF: TLNE F,(GATEWF) ; Is this host a gateway?
TLNN F,(GATINF) ; Has initialization finished?
POPJ P, ; No, just ignore request
PUSHJ P,GATENT ; Yes, is ENTFLG set?
POPJ P, ; No, ignore
PUSHJ P,SWPPRT## ; Yes, swap source and destination
PUSHJ P,BLDGIP ; Build gateway info packet
MOVEI A,201 ; Reply Pup Type
PUSHJ P,SNDPUP## ; Send it off
POPJ P, ; Failed
TLNE F,(DEBUGF) ; Log reply only if debugging
LOG <Gateway info for %1P>
POPJ P,
; Process "I am a gateway" packet and update local routing table
RECINF: LDB A,PPUPSS ; Get source socket
LDB B,PPUPSN ; Ignore info from non-directly-
CAMLE B,MAXNET ; connected nets
TDZA B,B
HRRZ B,RTADR-1(B)
SKIPE B
CAIE A,2 ; Make sure from right guy
JRST [ ELOG <Gateway Info Pup from suspect source %2P>
POPJ P,]
LDB A,PPUPSN ; Ignore packets from myself
HRRZ A,RTADR-1(A)
LDB B,PPUPSH
CAIN B,(A)
POPJ P,
PUSHJ P,SAVE2## ; Get some more ac's
MOVEI D,PBCONT(PB) ; Init byte ptr into packet
HRLI D,(POINT 8)
LDB C,PUPLEN ; Get pup length
SUBI C,MNPLEN ; Compute number of content bytes
ASH C,-2 ; Compute number of info blocks
JUMPLE C,CPOPJ## ; Forget it if none
HRRZS 0(P) ; Note no RT changes made yet
;RECIN1 RECIN2 RECIN3 RECIN4 RECIN5
; GATSRV (CONT'D)
; Loop here for each info block.
; Update my RT entry for the net given in the block if:
; (1) my RT entry says the net is inaccessible, or
; (2) the info block's hop count +1 is less than my hop count, or
; (3) the Pup source is the gateway thru which we already route, or
; (4) my entry has timed out (not updated in RTTINT seconds).
RECIN1: ILDB P1,D ; Get net number
IBP D ; Flush gateway net number
IBP D ; Flush gateway host number
ILDB P2,D ; Hop count
ADDI P2,1 ; My hops = his hops +1
CAIL P1,1 ; Make sure net number in range
CAMLE P1,MAXNET
JRST RECIN5 ; Not in range, ignore
HRRZ A,RTADR-1(P1) ; Check local host adr on net
JUMPN A,RECIN5 ; Ignore if directly connected
SKIPL RTADR-1(P1) ; Net previously inaccessible?
CAMGE P2,RTHOPS-1(P1) ; Fewer hops on new route?
JRST RECIN3 ; One of those, set new entry
LDB A,[POINT 8,RTADR-1(P1),9] ; Get gateway net in my RT
LDB B,PPUPSN ; Source net of gateway info Pup
CAIE A,(B) ; Same?
JRST RECIN2 ; No, continue
LDB A,[POINT 8,RTADR-1(P1),17] ; Get gateway host in my RT
LDB B,PPUPSH ; Source host of gateway info Pup
CAIN A,(B) ; Same?
JRST [ CAME P2,RTHOPS-1(P1) ; Yes, same hop count too?
JRST RECIN3 ; No, do the update
TIME ; Yes, just reset the timer and
ADDI A,RTTINT*↑D1000 ; avoid the update expense
MOVEM A,RTTIME-1(P1)
JRST RECIN5]
RECIN2: TIME ; Get now
CAMGE A,RTTIME-1(P1) ; Has entry timed out?
JRST RECIN5 ; No, ignore gateway info block
; Replace existing entry with new info block
RECIN3: CAILE P2,MAXHOP ; Hop count too large?
JRST [ MOVSI A,(1B0) ; Yes, declare net inaccessible
MOVEM A,RTADR-1(P1)
HRLOI A,377777 ; Set timer to infinity
JRST RECIN4]
LDB A,PPUPSN ; Gateway net ← Pup source net
LDB B,PPUPSH ; Gateway host ← Pup source host
LSH A,8
IORI A,(B)
HRLZM A,RTADR-1(P1) ; Zero out rest of entry
TIME ; Reset timer
ADDI A,RTTINT*↑D1000
RECIN4: MOVEM A,RTTIME-1(P1)
MOVEM P2,RTHOPS-1(P1) ; Set hop count
TLNE F,(GATINF) ; Initialization complete?
HRROS 0(P) ; Yes, remember to update Tenex
RECIN5: SOJG C,RECIN1 ; Repeat for all info blocks
SKIPGE 0(P) ; Did anything change?
PUSHJ P,STNXRT ; Yes, set Tenex RT
POPJ P, ; Done
;GATCHK GATCH1 GATCH2 GATCH4 GATCH6 GATCH9
; Check routing table and broadcast gateway info packet
; Returns +1
; Clobbers A-D, PB, SV
GATCHK::PUSHJ P,RANDOM## ; Compute time of next call randomly in
MULI B,<GATINT*↑D1000>/4 ; range .75*GATINT to 1.25*GATINT
ADDI B,GATINT*↑D1000
MOVEM B,GATTIM
TIME
ADDM A,GATTIM
MOVEI SV,SV.GAT ; Set service table index
TLON F,(GATINF) ; Say initialization is complete
PUSHJ P,STNXRT ; First time, update Tenex's RT
; Flush routing table entries that have not been updated
; in the past (2*RTTINT) seconds
HLLZ C,PUPROU## ; Init AOBJN pointer
HRRZS 0(P) ; No RT changes made yet
SUBI A,RTTINT*↑D1000 ; RT timer cutoff = 2*RTTINT
GATCH1: CAMGE A,RTTIME(C) ; Has entry timed out?
JRST GATCH2 ; No
MOVSI B,(1B0) ; Yes, declare net inaccessible
MOVEM B,RTADR(C)
HRLOI B,377777 ; Reset timer to infinity
MOVEM B,RTTIME(C)
MOVEI B,MAXHOP+1 ; Make route look very poor
MOVEM B,RTHOPS(C)
HRROS 0(P) ; Remember that RT has changed
GATCH2: AOBJN C,GATCH1 ; Repeat for all entries in RT
SKIPGE 0(P) ; Did anything change?
PUSHJ P,STNXRT ; Yes, set Tenex RT
; If this host is a gateway, broadcast gateway info packets
; on all directly connected networks
TLNE F,(GATEWF) ; Are we a gateway?
TLNN F,(ENABLF) ; In control of system sockets?
JRST GATCH9 ; No, done
PUSHJ P,GATENT ; Is ENTFLG set?
JRST GATCH9 ; No, don't send gateway info
PUSHJ P,SAVE1## ; Yes, get another ac
MOVEI PB,SRVPKT## ; Set pointer to PB
PUSHJ P,BLDGIP ; Build gateway info packet
HLLZ P1,PUPROU## ; Init AOBJN pointer
GATCH4: MOVE B,RTADR(P1) ; Get RT entry for net
TRNE B,-1 ; Directly connected?
TLNN B,(1B1) ; Able to be broadcast upon?
JRST GATCH6 ; No, bypass
MOVEI A,1(P1) ; Yes, get net number
SETZB B,C ; Let Tenex default host and socket
PUSHJ P,STSPRT## ; Set source port in Pup
MOVEI C,2 ; Dest socket = gateway info
PUSHJ P,STDPRT## ; Set destination port in Pup
SETZM PBHEAD+1(PB) ; Zero Pup ID just for kicks
MOVEI A,201 ; Pup type = "I'm a gateway"
PUSHJ P,SNDPUP## ; Send the Pup
CAI ; Failed, forget it
GATCH6: AOBJN P1,GATCH4 ; Repeat for all nets
GATCH9: SETO SV, ; No service now in progress
POPJ P,
;BLDGIP BLDGI1 BLDGI2 STNXRT STNXR1 STNXR2 GATENT
; Build gateway info packet
; PB/ Pointer to packet buffer
; Returns +1: Contents and length have been setup
; Clobbers A-C
BLDGIP: HLLZ C,PUPROU## ; Init AOBJN ptr to routing table
MOVEI A,PBCONT(PB) ; Init byte ptr into packet
HRLI A,(POINT 8)
BLDGI1: SKIPGE RTADR(C) ; Check for accessible network
JRST BLDGI2 ; Not accessible, ignore
MOVEI B,1(C) ; Ok, compute network number
IDPB B,A ; Store in packet
HLRZ B,RTADR(C) ; Get net/host for routing
ROT B,-8 ; Right-justify net
IDPB B,A ; Append it
ROT B,8 ; Right-justify host
IDPB B,A ; Append it
MOVE B,RTHOPS(C) ; Get hop count
IDPB B,A ; Append it
BLDGI2: AOBJN C,BLDGI1 ; Repeat for all networks
PUSHJ P,ENDPUP## ; Finish up, set size
POPJ P,
; Set Tenex's routing table to be equal to mine
; Returns +1
; Clobbers A-D
STNXRT: TLNN F,(ENABLF) ; Am I enabled?
POPJ P, ; No, forget it
PUSHJ P,SAVE1## ; Save another ac
IFN TENEX,<
HLLZ P1,PUPROU## ; Init AOBJN ptr to routing table
STNXR1: MOVE D,RTADR(P1) ; Get my RT entry for net
TRNE D,-1 ; Are we directly connected?
JRST STNXR2 ; Yes, skip it
MOVE A,[SIXBIT /PUPROU/] ; Function name
MOVEI B,1(P1) ; Net number
SETO C, ; Mask of bits to change
OPRFN ; Set the entry in Tenex
PUSHJ P,SCREWUP##
STNXR2: AOBJN P1,STNXR1 ; Repeat for all nets
>;IFN TENEX,<
IFN WAITS,<
PUSHJ P,ROUCLR## ; Clear old our private routing table
HLLZ A,PUPROU##
HRRI A,1
SKIPL B,RTADR-1(A) ; Is this host accessible?
PUSHJ P,ROUADD## ; Yes, hash in routing table
AOBJN A,.-2 ; Repeat for each network
PUSHJ P,ROUSET##
ELOG <Failed to set routing table>
>;IFN WAITS
POPJ P,
; Check whether ENTFLG is on
; Returns +1: Off
; +2: On
; Clobbers A
GATENT: HRRZ A,ENTFLG##
GETAB
PUSHJ P,SCREWUP##
JUMPN A,SKPRET##
POPJ P,
;GATINI GATIN1 GATIN2 GATIN3 GATIN4 GATIN6
; Initialize gateway information server
; Returns +1
; Clobbers A-D, PB, SV
GATINI::MOVEI SV,SV.GAT ; Set service table index
HLRE A,PUPROU## ; Get negative length of Tenex RT
MOVNS A ; Make positive
CAILE A,NNETS ; Make sure in range
JRST [ TYPE <Insufficient routing table space (NNETS)>
HALTF]
MOVEM A,MAXNET ; Store for my use
HRRZ A,PUPPAR## ; Get word 2 of pup parameter table
HRLI A,2
GETAB
PUSHJ P,SCREWUP##
TLNE A,(1B0) ; Is this host a gateway?
TLO F,(GATEWF) ; Yes, set flag
TIME ; Get now
ADDI A,↑D10000 ; Call GATCHK 10 seconds from now
MOVEM A,GATTIM
; Initialize local routing table
MOVE A,PUPROU## ; Get descriptor for Tenex RT
MOVEI B,RTADR ; Where to put it
PUSHJ P,REDGTB## ; Read into my space
TIME ; Get now
ADDI A,RTTINT*↑D1000 ; When to time out RT entry
HLLZ C,PUPROU## ; Init AOBJN pointer
GATIN1: SETZM RTHOPS(C) ; Assume directly connected
HRLOI B,377777 ; Set timeout to infinity
MOVEM B,RTTIME(C)
SKIPGE B,RTADR(C) ; Network accessible?
JRST GATIN2 ; No, go set hops to maximum
TRNE B,-1 ; Yes, directly connected?
JRST GATIN3 ; Yes, done
MOVEM A,RTTIME(C) ; Indirectly connected, set timer
GATIN2: MOVEI B,MAXHOP+1 ; Make routing look very poor
MOVEM B,RTHOPS(C)
GATIN3: AOBJN C,GATIN1 ; Repeat for all nets
; Broadcast gateway info requests on all directly connected nets
PUSHJ P,SAVE1## ; Get another ac
MOVEI PB,SRVPKT## ; Set pointer to PB
MOVEI A,MNPLEN ; Minimum-length Pup
DPB A,PUPLEN
HLLZ P1,PUPROU## ; Init AOBJN pointer
GATIN4: MOVE B,RTADR(P1) ; Get RT entry for net
TRNE B,-1 ; Directly connected?
TLNN B,(1B1) ; Able to be broadcast upon?
JRST GATIN6 ; No, bypass
MOVEI A,1(P1) ; Yes, get net number
SETZB B,C ; Let Tenex default host and socket
PUSHJ P,STSPRT## ; Set source port in Pup
MOVEI C,2 ; Dest socket = gateway info
PUSHJ P,STDPRT## ; Set destination port in Pup
SETZM PBHEAD+1(PB) ; Zero Pup ID just for kicks
MOVEI A,200 ; Pup type = "Are you a gateway"
PUSHJ P,SNDPUP## ; Send the Pup
CAI ; Failed, forget it
GATIN6: AOBJN P1,GATIN4 ; Repeat for all nets
SETO SV, ; No service now in progress
POPJ P,
; Storage for this module
GS MAXNET ; Highest allowable net number
GS GATTIM ; Time for next call to GATCHK
; Routing table stuff, indexed by (net number -1)
GS RTADR,NNETS ; Routing table (same format as Tenex's)
GS RTHOPS,NNETS ; Hop count table
GS RTTIME,NNETS ; When to time out routing table entry
END