;<PUP>PUPGAT.MAC;15 14-DEC-81 19:00:08 EDIT BY TAFT ; Keep routing table in external file PUPSRV.RT for benefit of ; other programs that need routing information. ;<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 ; 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 ; 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 ; 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, ; 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 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 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, ; 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 ; Init routing table mapped onto PUPSRV.RT MOVSI A,(1B8+1B17) ; Ignore deleted, short form HRROI B,[ASCIZ /<SYSTEM>PUPSRV.RT;1/] TLNE F,(DEBUGF) ; Debugging? HRROI B,[ASCIZ /PUPSRV.RT;1/] ; Yes, make private file GTJFN JRST GATINE MOVE C,A MOVE B,[↑D36B5+1B19+1B20+1B25] ; R+W, thawed OPENF JRST [ EXCH C,A RLJFN CAI MOVE C,A JRST GATINE] HRLI A,12 ; Make file appear 1 page long SETO B, MOVEI C,1000 CHFDB MOVSI A,0(A) ; Source is file, page 0 MOVEI B,RTPAGE ; Destination is this fork, RTPAGE LSH B,-9 HRLI B,400000 MOVSI C,(1B2+1B3) ; R+W PMAP ; Initialize local routing table GATIN0: MOVSI A,(1B0) ; Init unused entries to "inaccessible" MOVEM A,RTPAGE MOVE A,[RTPAGE,,RTPAGE+1] BLT A,RTPAGE+377 MOVEI A,MAXHOP+1 MOVEM A,RTPAGE+400 MOVE A,[RTPAGE+400,,RTPAGE+401] BLT A,RTPAGE+777 MOVE A,PUPROU## ; Get descriptor for Tenex RT MOVEI B,RTADR ; Where to put it PUSHJ P,REDGTB## ; Read into my space ; Initialization (cont'd) 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, ; Here if couldn't access PUPSRV.RT GATINE: ELOG <Failed to open PUPSRV.RT%/ - %1J> JRST GATIN0 ; Press on ; 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 RTTIME,NNETS ; When to time out routing table entry GSP RTPAGE,1 ; Routing information mapped to file PUPSRV.RT RTADR==:RTPAGE+1 ; Routing table (same format as Tenex's) RTHOPS==:RTPAGE+401 ; Hop count table END