.TITLE EGP EGP internet gateway .NLIST BEX .ENABL LC ; ; Pdp11/dcn - EGP internet gateway ; ; This module supports the Exterior Gateway Protocol (EGP) ; ; External symbols ; .GLOBL RDOCT,RDDEC,HASH,GETARG,PRIDNT .GLOBL CHAIN,ERRLVL .GLOBL FLAGS,OPNBLK,CTRL,HELP,NETAST .GLOBL NGBTAB,SYSN ; ; Entry symbols ; .GLOBL NETDAT,NETSIG,INIT,KWKTBL,COM00 ; ; System definitions ; .ASECT .MCALL .COM,.CHN,.PSA,.SUP,.SMF ;dcnlib definitions .MCALL .KWTAB,.MSG,.PSEM,.VSEM,.WIND ;dcnlib macros .MCALL $DFIH,$DFTIM,$DFSIG,$DFTBL ;moslib definitions .MCALL DFCON,OPNBLK,ADDR,CALL,GETARG,DFSRV,FORMAT ;netlib macros .MCALL .GTJB,.DSTAT,.SETTO,.EXIT,.MRKT,.CMKT,.SPND,.RSUM ;rt-11 macros .COM ;define common data .CHN ;define argument .PSA ;define process storage area .SUP ;define host parameter area .SMF ;define semaphore ids $DFIH ;define internet header $DFTIM ;define timer values $DFSIG ;define interprocess signals $DFTBL ;define host/gateway table formats DFCON ;define connection block DFSRV ;define service bits ; ; Module definitions ; .MACRO FSA ARG ;tickle finite-state automaton MOVB ARG,R0 JSR PC,FSA .ENDM FSA ; ; Assembly parameters ; RTPSIZ = 256. ;rtp control block size DIAMTR = 3 ;maximum internet diameter (hops) ; ; Options word bits ; X.DFLT = 000004 ;disable default X.ROUT = 000010 ;disable nonzero nets ; ; Interrupt codes ; IPPID = 2+EXTBAS ;get internet process pid NTPID = 3+EXTBAS ;get net process pid ; ; Fixed parameters ; PAR.P1 = 45. ;minimum interval between hello commands PAR.P2 = 120. ;minimum interval between poll commands PAR.P3 = 45. ;request/cease retransmission timeout PAR.P4 = 3600. ;long abort timeout PAR.P5 = 180. ;short abort timeout PAR.J = 3 ;up threshold (active mode) PAR.K = 1 ;down threshold (all modes) ; ; Event codes ; EV.UP = 0 ;Up reachability indication EV.DWN = 1 ;Down reachability indication EV.REQ = 2 ;Request command EV.CFM = 3 ;Confirm response EV.REF = 4 ;Refuse response EV.CEA = 5 ;Cease command EV.CAK = 6 ;Cease-ack response EV.HLO = 7 ;Hello command EV.IHU = 8. ;I-H-U response EV.POL = 9. ;Poll command EV.UPD = 10. ;Update response EV.STR = 11. ;Start request EV.STP = 12. ;Stop request or timer t3 underflow EV.T1 = 13. ;timer t1 underflow EV.T2 = 14. ;timer t2 underflow ; ; Exterior gateway protocol (egp) header ; . = 0 EH.VER: .BLKB 1 ;version number VRSN = 2 ;egp version number EH.TYP: .BLKB 1 ;message type EC.UPD = 1 ;update EC.POL = 2 ;poll EC.ACQ = 3 ;neighbor acquisition EC.HLO = 5 ;neighbor reachability EC.ERR = 10 ;error EH.COD: .BLKB 1 ;message code EH.STA: .BLKB 1 ;status EH.CHK: .BLKW 1 ;checksum EH.SYS: .BLKW 1 ;system number EH.SEQ: .BLKW 1 ;sequence number EH.LEN = . ;end of egp header ; ; Neighbor acquisition messages ; ; Stat Reason Scenarios ; --------------------------------------------------------- ; 0 unspecified when nothing else fits ; ; 1 active mode request/confirm only ; ; 2 passive mode request/confirm only ; ; 3 insufficient resources 1. out of table space ; 2. out of system resources ; ; 4 administratively 1. unknown autonomous system # ; prohibited 2. use another gateway ; ; 5 going down 1. operator initiated ; 2. abort timeout ; ; 6 parameter problem 1. nonsense polling parameters ; 2. unable to assume compatible mode ; ; Header extension ; . = EH.LEN EH.POL: .BLKW 2 ;min poll intervals (request/confirm only) ; ; Code field ; CD.REQ = 0 ;request CD.CFM = 1 ;confirm CD.REF = 2 ;refuse CD.CEA = 3 ;cease CD.CAK = 4 ;cease-ack ; ; Status field ; SF.USP = 0 ;unspecified SF.ACT = 1 ;active mode SF.PAS = 2 ;passive mode SF.FUL = 3 ;insufficient resources SF.ADP = 4 ;administratively prohibited SF.STP = 5 ;going down SF.PAR = 6 ;parameter problem SF.PRO = 7 ;protocol violation ; ; Neighbor reachability messages ; ; Code field ; CD.HLO = 0 ;hello CD.IHU = 1 ;i heard you ; ; Status field ; SF.IND = 0 ;indeterminate SF.UP = 1 ;up state SF.DWN = 2 ;down state SF.UNS = 200 ;unsolicited (update only) ; ; Update/poll messages ; Code field (not used) ; Status field (see neighbor reachability messages) ; ; Header extension ; . = EH.LEN EH.IGW: .BLKB 1 ;number of interior gateways EH.EGW: .BLKB 1 ;number of exterior gateways EH.NET: .BLKW 2 ;ip source net EH.DAT = . ;beginning of data area (update only) ; ; Error message ; Code field (not used) ; Status field (see neighbor reachability messages) ; ; Code Reason Scenarios ; ----------------------------------------------------------------------- ; 0 unspecified when nothing else fits ; ; 1 bad EGP header format 1. bad message length ; 2. invalid Type, Code or Status fields ; ; 2 bad EGP data field 1. nonsense polling rates (Request/Confirm) ; format 2. invalid Update message format ; 3. response IP Net Address field does not ; match command (Update) ; ; 3 reachability info 1. no info available on net specified in ; unavailable IP Net Address field (Poll) ; ; 4 excessive polling rate 1. two or more Hello commands received within ; min specified polling interval ; 2. two or more Poll commands received within ; min specified polling interval ; 3. two or more Request commands received ; within some (reasonably short) interval ; ; 5 no response 1. no Update received for Poll within some ; (reasonably long) interval ; ; Header extension ; . = EH.LEN EH.ERR: .BLKW 1 ;reason for error ER.UNS = 0 ;unspecified ER.HDR = 1 ;bad EGP header field format ER.DAT = 2 ;bad EGP data field format ER.NET = 3 ;net-reachability information not available ER.POL = 4 ;excessive polling rate ER.RSP = 5 ;no response EH.HDR = . ;header of bad message ; ; Neighbor table entry format ; . = 0 NG.ADR: .BLKW 2 ;neighbor ip address NG.GAT: .BLKW 2 ;gateway ip address NG.SYS: .BLKW 1 ;egp system number NG.FLG: .BLKW 1 ;status flags ST.DMP = 100000 ;formatted packet dump (debug) ST.ORG = 040000 ;active acquisition mode ST.ONL = 020000 ;online ST.ACT = 010000 ;active reachability mode ST.RCH = 004000 ;reachability indication ST.HLO = 002000 ;hello request ST.UNS = 001000 ;unsolicited update ST.ZER = 000400 ;force zero receive distance ST.DFT = 000200 ;default gateway NG.CMD: .BLKB 1 ;egp command NG.STA: .BLKB 1 ;protocol state NG.RCH: .BLKB 1 ;reachability state .EVEN NG.SND: .BLKW 1 ;send sequence number NG.RCV: .BLKW 1 ;receive sequence number ; NG.P1: .BLKW 1 ;minimum interval between hello commands NG.P2: .BLKW 1 ;minimum interval between poll commands NG.T1P: .BLKW 1 ;timer t1 preset NG.T2P: .BLKW 1 ;timer t2 preset NG.T1: .BLKW 1 ;timer t1 NG.T2: .BLKW 1 ;timer t2 NG.T3: .BLKW 1 ;timer t3 ; NG.TIM: .BLKW 2 ;last timestamp NG.RXS: .BLKB 1 ;receive status NG.TXS: .BLKB 1 ;send status .EVEN ; NG.BAD: .BLKW 1 ;bad format NG.CHK: .BLKW 1 ;bad checksum NG.DRP: .BLKW 1 ;dropped NG.UNR: .BLKW 1 ;unreachable NG.RES: .BLKW 1 ;no buffer ; ; Event log ; NG.EVN: .BLKW 1 ;0 Up reachability indication .BLKW 1 ;1 Down reachability indication .BLKW 1 ;2 Request command .BLKW 1 ;3 Confirm response .BLKW 1 ;4 Refuse response .BLKW 1 ;5 Cease command .BLKW 1 ;6 Cease-ack response .BLKW 1 ;7 Hello command .BLKW 1 ;8 I-H-U response .BLKW 1 ;9 Poll command .BLKW 1 ;10 Update response .BLKW 1 ;11 Start request .BLKW 1 ;12 Stop request or timer t3 underflow .BLKW 1 ;13 timer t1 underflow .BLKW 1 ;14 timer t2 underflow ; ; Action log ; NG.ACT: .BLKW 1 ;0 Up reachability indication .BLKW 1 ;1 Down reachability indication .BLKW 1 ;2 Request command .BLKW 1 ;3 Confirm response .BLKW 1 ;4 Refuse response .BLKW 1 ;5 Cease command .BLKW 1 ;6 Cease-ack response .BLKW 1 ;7 Hello command .BLKW 1 ;8 I-H-U response .BLKW 1 ;9 Poll command .BLKW 1 ;10 Update response .BLKW 1 ;11 Start request .BLKW 1 ;12 Stop request or timer t3 underflow .BLKW 1 ;13 timer t1 underflow .BLKW 1 ;14 timer t2 underflow NG.LEN = . ;length of table entry .PAGE .SBTTL Process net packets ; .PSECT $BOSI,RO,I ; ; Net completion routine ; NETSUB: JSR PC,NETAST RTS PC ; ; Process net signals ; r0 = code, r1 = open block pointer ; NETSIG: CMPB #SG.CC,R0 ;is this close complete BNE 1$ ;branch if no .RSUM ;proceed with main routine 1$: RTS PC ; ; Process net packets ; r0 = packet pointer ; NETDAT: MOV R0,R1 ;align packet pointers ADD PH.OFS(R1),R0 MOV R0,R2 ;(start) ADD PH.LNG(R1),R0 ;(end) MOV RSMPTR,R3 ;(buffer) BIT #IH.OFF,IH.FRG(R1) ;is this first fragment BNE 1$ ;branch if no MOV R1,R2 ;yes. reset pointers MOV #EGPRSM,R3 1$: CMP R3,@#50 ;(upper storage limit) BHIS 2$ MOVB (R2)+,(R3)+ ;copy fragment CMP R2,R0 BLO 1$ 2$: MOV R3,RSMPTR ;save for next fragment MOV IH.FRG(R1),-(SP) CALL CTRL,#CM.FRE,R1,OPNBLK+CONPTR ;discard packet BIT #IH.MF,(SP)+ ;is this last fragment BNE 5$ ;branch if no MOV #EGPRSM,R1 ;yes. process reassembled packet SUB R1,R3 ;recompute length SUB PH.OFS(R1),R3 MOV R3,PH.LNG(R1) MOV R1,R2 ;set pointers ADD PH.OFS(R1),R2 MOV #NGBTAB,R4 ;initialize table scan MOVB NGBTAB-2,NGBID 3$: DECB NGBID ;is table full BEQ 5$ ;branch if yes TST NG.ADR(R4) ;yes. is this end of table BNE 4$ ;branch if no JSR PC,NGBINI ;yes. initialize new neighbor MOV IH.SRC(R1),NG.ADR(R4) MOV IH.SRC+2(R1),NG.ADR+2(R4) MOV IH.DST(R1),NG.GAT(R4) MOV IH.DST+2(R1),NG.GAT+2(R4) MOV #ST.ONL,NG.FLG(R4) CLRB NG.CMD(R4) MOV #PAR.P1,NG.P1(R4) MOV #PAR.P2,NG.P2(R4) FORMAT #COM40,R4 ;new neighbor 4$: CMP NG.ADR(R4),IH.SRC(R1) ;does packet match entry BNE 6$ ;branch if no CMP NG.ADR+2(R4),IH.SRC+2(R1) BNE 6$ ;branch if no JSR PC,EGPPKT ;yes. process packet 5$: RTS PC ; 6$: ADD #NG.LEN,R4 ;advance to next entry BR 3$ ; ; Process timer calls once per second ; GATICK: MOV #NGBTAB,R4 ;initialize table scan 1$: TST NG.ADR(R4) ;is this end of table BEQ 5$ ;branch if yes TST NG.T1(R4) ;no. update timer t1 BEQ 2$ DEC NG.T1(R4) BNE 2$ ;branch if no overflow FSA #EV.T1 ;signal overflow 2$: TST NG.T2(R4) ;update timer t2 BEQ 3$ DEC NG.T2(R4) BNE 3$ ;branch if no overflow FSA #EV.T2 ;signal overflow 3$: TST NG.T3(R4) ;update timer t3 BEQ 4$ DEC NG.T3(R4) BNE 4$ ;branch if no overflow MOVB #SF.STP,NG.TXS(R4) FSA #EV.STP ;signal overflow 4$: JSR PC,EGPOUT ;complete business ADD #NG.LEN,R4 ;advance to next entry BR 1$ ; 5$: .MRKT #ARGBLK,#TIME,#GATICK,#1 ;restart the bubble machine RTS PC .PAGE .SBTTL Egp processing ; ; Process egp packet ; R1 = packet pointer, r2 = egp header pointer ; EGPPKT: MOV R1,-(SP) ;save packet pointer MOV PH.TIM(R1),NG.TIM(R4) ;update timestamp MOV PH.TIM+2(R1),NG.TIM+2(R4) JSR PC,DUMP ;optional dump CMP PH.LNG(R1),#EH.LEN ;is format valid BLO 3$ ;branch if no JSR PC,CHKSUM ;yes. compute egp checksum TST R0 BEQ 1$ ;branch if ok INC NG.CHK(R4) ;bad checksum BR 7$ ; 1$: SWAB EH.SYS(R2) ;onward pdp11 SWAB EH.SEQ(R2) CMPB EH.VER(R2),#VRSN ;is header valid BNE 3$ ;branch if no MOV #DECODE,R0 ;decode type field MOVB EH.TYP(R2),R1 CMP R1,(R0)+ BHIS 3$ ;branch if invalid ASL R1 ADD R1,R0 MOV @R0,R0 BEQ 3$ ;branch if invalid CMP R0,#400 BLO 2$ ;branch if complete MOVB EH.COD(R2),R1 ;decode code field CMP R1,(R0)+ BHIS 3$ ;branch if invalid ASL R1 ADD R1,R0 MOV @R0,R0 BNE 2$ ;branch if valid 3$: INC NG.BAD(R4) ;bad version, type or code BR 7$ ; 2$: TSTB R0 ;is this response BMI 4$ ;branch if no CMP EH.SEQ(R2),NG.SND(R4) ;yes. is sequence number correct BEQ 6$ ;branch if yes INC NG.DRP(R4) ;bad sequence number BR 7$ ; 4$: MOV EH.SEQ(R2),NG.RCV(R4) ;command. save sequence number 6$: MOVB EH.STA(R2),NG.RXS(R4) ;save status info FSA R0 ;evoke event 7$: MOV (SP)+,R1 ;restore packet pointer RTS PC ; ; Fsa (fsa) finite-state automaton ; R0 = event code, r2 = header pointer, r4 = neighbor pointer ; FSA: BIC #^C17,R0 ;safety first ASL R0 ;update event tallies MOV R0,-(SP) ;save event code ADD R4,R0 INC NG.EVN(R0) ASL @SP ;compute table address MOVB NG.STA(R4),R0 ASL R0 MOV STATE(R0),R0 ADD (SP)+,R0 MOVB (R0)+,NG.STA(R4) TSTB (R0)+ JSR PC,@(R0)+ RTS PC ; ; Summary of state transitions ; ; Next Message ; Event State Sent Actions ; -------------------------------------------------------------------------- ; ; Idle State (0) ; ; Request 2 Confirm Initialize state variables and ; Hello reset timer t1 to T1 seconds and ; reset timer t3 to P5 seconds. ; or *** 0 Refuse Return resources. ; Cease 0 Cease-ack Return resources. ; Start 1 Request Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; Stop *** 1 Request Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; ; Acquisition State (1) ; ; Request 2 Confirm Initialize state variables and ; Hello reset timer t1 to T1 seconds and ; reset timer t3 to P5 seconds. ; Confirm 2 Hello Initialize state variables and ; reset timer t1 to T1 seconds and ; reset timer t3 to P5 seconds. ; Refuse 0 Stop timers and return resources. ; Cease 0 Cease-ack Stop timers and return resources. ; Start 1 Request Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; Stop/t3 0 Stop timers and return resources. ; t1 1 Request Reset timer t1 to P3 seconds. ; ; Down State (2) ; Note: Reset timer t3 to P4 seconds on receipt of reachability indication ; ; Up 3 Poll Reset timer t2 to T2 seconds. ; Request 2 Confirm Reinitialize state variables and ; reset timer t1 to T1 seconds and ; reset timer t3 to P5 seconds. ; Cease 0 Cease-ack Stop timers and return resources. ; Hello 2 I-H-U ; I-H-U 2 Process neighbor-reachability info. ; Start 1 Request Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; Stop/t3 4 Cease Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; t1 2 Hello Reset timer t1 to T1 seconds. ; ; Up State (3) ; Note: Reset timer t3 to P4 seconds on receipt of reachability indication ; ; Down 2 Stop timer t2. ; Request 2 Confirm Reinitialize state variables and ; Hello reset timer t1 to T1 seconds and ; reset timer t3 to P5 seconds. ; Cease 0 Cease-ack Stop timers and return resources. ; Hello 3 I-H-U ; I-H-U 3 Process neighbor-reachability info. ; Poll 3 Update ; Update 3 Process net-reachability info. ; Start 1 Request Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; Stop/t3 4 Cease Reset timer t1 to P3 seconds and ; reset timer t3 to P5 seconds. ; t1 3 Hello Reset timer t1 to T1 seconds. ; t2 3 Poll Reset timer t2 to T2 seconds. ; ; Cease State (4) ; ; Request 4 Cease ; Cease 0 Cease-ack Stop timers and return resources. ; Cease-ack 0 Stop timers and return resources. ; Stop/t3 0 Stop timers and return resources. ; t1 4 Cease Reset timer t1 to P3 seconds. ; ; System control messages ; START: FORMAT #COM42J,R4 ;start request JSR PC,NGBRST ;reset neighbor RSTRT: MOVB #EV.REQ,NG.CMD(R4) ;send request MOV #PAR.P3,NG.T1(R4) ;restart timer t1 RTS PC ; STOP: FORMAT #COM42G,R4 ;stop request JSR PC,NGBRST ;reset neighbor RSTOP: MOVB #EV.CEA,NG.CMD(R4) ;send cease MOV #PAR.P3,NG.T1(R4) ;restart timer t1 RTS PC ; TIMOT: FORMAT #COM42G,R4 ;stop request JSR PC,NGBINI ;reinitialize neighbor RTS PC ; ; Neighbor acquisition messages ; ; Status Receiver capabilites ; field 0 1 2 ; ------------------------------------- ; 0 * active passive ; 1 passive active passive ; 2 active active ** ; REQST1: FORMAT #COM43,R4 ;neighbor request REQST: JSR PC,NGBRST ;reset neighbor MOVB #EV.CFM,NG.CMD(R4) ;presume send confirm BIT #ST.ONL,NG.FLG(R4) ;is gateway online BNE REQ1 ;branch if yes JSR PC,NGBINI ;no. reinitialize neighbor MOVB #EV.REF,NG.CMD(R4) MOVB #SF.STP,NG.TXS(R4) RTS PC ; CNFRM: FORMAT #COM42C,R4 ;neighbor confirm JSR PC,NGBRST ;reset neighbor REQ1: MOV EH.SYS(R2),NG.SYS(R4) ;record egp system number BIC #ST.ACT,NG.FLG(R4) ;determine polling bit CMPB EH.STA(R2),#SF.ACT BEQ 2$ ;branch if neighbor active CMPB EH.STA(R2),#SF.PAS BEQ 1$ ;branch if neighbor passive CMP NG.SYS(R4),#SYSN ;neighbor default. compare system numbers BLO 2$ ;branch if default active BHI 1$ ;branch if default passive BIT #ST.ORG,NG.FLG(R4) ;same system. did this neighbor start BEQ 2$ ;branch if no (passive) 1$: BIS #ST.ACT,NG.FLG(R4) ;active BR 3$ ; 2$: ADD NG.T2P(R4),NG.T3(R4) ;passive. increase timer r3 3$: MOV EH.POL(R2),R0 ;compute hello interval SWAB R0 CMP R0,NG.P1(R4) BHIS 4$ MOV NG.P1(R4),R0 4$: MOV R0,NG.T1P(R4) MOV EH.POL+2(R2),R0 ;compute poll interval SWAB R0 CMP R0,NG.P2(R4) BHIS 5$ MOV NG.P2(R4),R0 5$: MOV R0,NG.T2P(R4) CMP R0,#256.*64. ;are intervals reasonable BHIS 6$ ;branch if no CMP R0,NG.T1P(R4) BHIS TIMR3 ;branch if yes 6$: JSR PC,NGBINI ;no. reinitialize neighbor MOVB #EV.REF,NG.CMD(R4) MOVB #SF.PAR,NG.TXS(R4) RTS PC ; TIMR1: BIT #ST.RCH,NG.FLG(R4) ;is reachability indicated BNE 1$ ;branch if yes CLC ;no. update state ROLB NG.RCH(R4) MOVB NG.RCH(R4),R0 ;is neighbor down BIC #^C17,R0 CMPB BITPOP(R0),#PAR.K BHI 1$ ;branch if no FSA #EV.DWN ;yes. signal down 1$: BIC #ST.RCH,NG.FLG(R4) ;reset reachability indication TIMR3: MOV NG.T1P(R4),NG.T1(R4) ;restart timer t1 BIT #ST.ACT,NG.FLG(R4) ;is this active BEQ 2$ ;branch if no BIS #ST.HLO,NG.FLG(R4) ;yes. send hello 2$: RTS PC ; RFUSE: FORMAT #COM42D,R4 ;neighbor refuse JSR PC,NGBINI ;reinitialize neighbor NOOP: RTS PC ; CEASE: FORMAT #COM42E,R4 ;neighbor cease CEASE1: JSR PC,NGBINI ;reinitialize neighbor MOVB #EV.CAK,NG.CMD(R4) ;send cease-ack RTS PC ; CEASE2: FORMAT #COM42F,R4 ;neighbor cease-ack JSR PC,NGBINI ;reinitialize neighbor RTS PC ; CEASE3: MOVB #EV.CEA,NG.CMD(R4) ;send cease MOVB #SF.PRO,NG.TXS(R4) RTS PC ; ; Neighbor reachability messages ; UPITY1: FORMAT #COM41,R4 ;neighbor up BIS #ST.UNS,NG.FLG(R4) ;send unsolicited update TIMR2: MOVB #EV.POL,NG.CMD(R4) ;send poll MOV NG.T2P(R4),NG.T2(R4) ;restart timer t2 RTS PC ; UPITY2: FORMAT #COM42B,R4 ;neighbor down CLR NG.T2(R4) ;stop timer t2 RTS PC ; HELLO: MOVB #EV.IHU,NG.CMD(R4) ;hello. send ihu HLO1: BIT #ST.ACT,NG.FLG(R4) ;is this passive BEQ HLO2 ;branch if yes RTS PC ;active. quietly withdraw ; HEARD: BIT #ST.ACT,NG.FLG(R4) ;is this passive BEQ HLO2 ;branch if yes BIT #ST.RCH,NG.FLG(R4) ;active. has it hit before BNE 1$ ;branch if yes BIS #ST.RCH,NG.FLG(R4) ;no. record a hit MOV #PAR.P4,NG.T3(R4) ;reset timer t3 SEC ;update state ROLB NG.RCH(R4) JSR PC,UPDATE ;update local routing MOVB NG.RCH(R4),R0 ;is neighbor up BIC #^C17,R0 CMPB BITPOP(R0),#PAR.J BLO 1$ ;branch if no FSA #EV.UP ;declare up 1$: RTS PC ; HLO2: MOVB EH.STA(R2),R0 ;passive. is this reachability indication BIC #^C17,R0 CMPB R0,#SF.UP BNE 1$ ;branch if no BIT #ST.RCH,NG.FLG(R4) ;yes. has it hit before BNE 1$ ;branch if yes BIS #ST.RCH,NG.FLG(R4) ;no. record a hit MOV #PAR.P4,NG.T3(R4) ;reset timer t3 SEC ;update state ROLB NG.RCH(R4) JSR PC,UPDATE ;update local routing FSA #EV.UP ;declare up 1$: RTS PC ; ; Net reachability messages ; POLL: MOVB #EV.UPD,NG.CMD(R4) ;send update BR HLO1 ; UPDAT: MOV R2,R3 ;initialize for packet scan ADD #EH.DAT,R2 1$: TSTB EH.IGW(R3) ;are there more internal gateways BLE 2$ ;branch if no DECB EH.IGW(R3) ;yes. process update BR 3$ ; 2$: TSTB EH.EGW(R3) ;are there more external gateways BLE HEARD ;branch if no DECB EH.EGW(R3) ;yes. process update 3$: MOV R3,R0 ;assemble gateway address ADD #EH.NET,R0 JSR PC,NTCLAS BR 4$ ;class a BR 5$ ;class b BR 6$ ;class c ; 4$: MOVB (R2)+,EH.NET+1(R3) ;class a 5$: MOVB (R2)+,EH.NET+2(R3) ;class b 6$: MOVB (R2)+,EH.NET+3(R3) ;class c MOV R3,R1 ;find hid ADD #EH.NET,R1 JSR PC,ADRMAP BCS HEARD ;branch if cant BITB #GT.END,GATFLG(R0) BNE HEARD ;branch if default MOVB GATHID(R0),EGPHIX JSR PC,DECUPD ;decode gateway block BCC 1$ FORMAT #COM42X,R4 ;format error BR 1$ ; ; Send egp packet ; R4 = neighbor pointer ; EGPOUT: TSTB NG.CMD(R4) ;is command pending BNE 2$ ;branch if yes BIT #ST.UNS,NG.FLG(R4) ;no. is unsolicited update pending BEQ 1$ ;branch if no BIC #ST.UNS,NG.FLG(R4) ;yes. send it MOVB #EV.UPD+200,NG.CMD(R4) BR 2$ ; 1$: BIT #ST.HLO,NG.FLG(R4) ;is hello pending BEQ 3$ ;branch if no BIC #ST.HLO,NG.FLG(R4) ;yes. send it MOVB #EV.HLO,NG.CMD(R4) 2$: CALL CTRL,#CM.GET,#PKTPTR,OPNBLK+CONPTR ;yes. allocate packet MOV R0,R2 ASL R2 ;decode return ADD R2,PC BR 5$ ;0 accepted BR 4$ ;1 connection open error BR 4$ ;2 invalid parameters INC NG.RES(R4) ;3 insufficient resources 3$: RTS PC ; 4$: JSR PC,PRIDNT ;fatal error .EXIT ; 5$: MOV PKTPTR,R2 ;initialize ip header MOV #IH.LEN,PH.OFS(R2) ADD #BUFLDR,R2 MOV #,(R2)+ ;(ih.ver,ih.tos) CLR (R2)+ ;(ih.fl) CLR (R2)+ ;(ih.id) CLR (R2)+ ;(ih.frg) MOV #+,(R2)+ ;(ih.ttl,ih.pro) CLR (R2)+ ;(ih.chk) MOV NG.GAT(R4),(R2)+ ;(ih.src) MOV NG.GAT+2(R4),(R2)+ MOV NG.ADR(R4),(R2)+ ;(ih.dst) MOV NG.ADR+2(R4),(R2)+ MOV R2,HEDPTR ;save header pointer MOVB #VRSN,(R2)+ ;(eh.ver) complete egp header CLRB (R2)+ ;(eh.typ) CLRB (R2)+ ;(eh.cod) CLRB (R2)+ ;(eh.sta) CLR (R2)+ ;(eh.cks) MOV #SYSN,(R2)+ ;(eh.sys) MOV NG.RCV(R4),(R2)+ ;(eh.seq) (assume receive) MOV HEDPTR,R1 ;restore header pointer ; ; Construct data portion ; MOVB NG.CMD(R4),R0 ;log events BIC #^C17,R0 ASL R0 MOV R0,-(SP) ADD R4,R0 INC NG.ACT(R0) ADD (SP)+,PC ;branch to process BR . ;0 Up reachability indication BR . ;1 Down reachability indication BR OUTREQ ;2 Request command BR OUTCFM ;3 Confirm response BR OUTREF ;4 Refuse response BR OUTCEA ;5 Cease command BR OUTCAK ;6 Cease-ack response BR OUTHLO ;7 Hello command BR OUTIHU ;8 I-H-U response BR OUTPOL ;9 Poll command BR OUTUPD ;10 Update response ; OUTREQ: MOVB #CD.REQ,EH.COD(R1) ;send request command MOV NG.SND(R4),EH.SEQ(R1) BR OUT11 ; OUTCFM: MOVB #CD.CFM,EH.COD(R1) ;send confirm response BR OUT11 ; OUTREF: MOVB #CD.REF,EH.COD(R1) ;send refuse response BR OUT12 ; OUTCEA: MOVB #CD.CEA,EH.COD(R1) ;send cease command MOV NG.SND(R4),EH.SEQ(R1) BR OUT12 ; OUTCAK: MOVB #CD.CAK,EH.COD(R1) ;send cease-ack response OUT12: BISB NG.TXS(R4),EH.STA(R1) ;complete status field OUT11: MOVB #EC.ACQ,EH.TYP(R1) MOV NG.P1(R4),@R2 ;(eh.pol) insert polling intervals SWAB (R2)+ MOV NG.P2(R4),@R2 SWAB (R2)+ BR EGPSND ; OUTPOL: MOVB #EC.POL,EH.TYP(R1) ;send poll command INC NG.SND(R4) ;increment send sequence MOV NG.SND(R4),EH.SEQ(R1) CLR (R2)+ ;(reserved) MOV R4,R0 ;determine net class ADD #NG.GAT,R0 JSR PC,NTCLAS BR 2$ ;class a BR 1$ ;class b MOV NG.GAT(R4),(R2)+ ;(eh.net) class c MOVB NG.GAT+2(R4),(R2)+ CLRB (R2)+ BR OUT22 ; 1$: MOV NG.GAT(R4),(R2)+ ;(eh.net) class b CLR (R2)+ BR OUT22 ; 2$: MOVB NG.GAT(R4),(R2)+ ;(eh.net) class a CLRB (R2)+ CLR (R2)+ BR OUT22 ; OUTUPD: MOVB #EC.UPD,EH.TYP(R1) ;send update response TSTB NG.CMD(R4) ;is this solicited BPL 1$ ;branch if yes BISB #SF.UNS,EH.STA(R1) ;no. so mark 1$: MOVB #1,(R2)+ ;(eh.igw) CLRB (R2)+ ;(eh.egw) MOV R4,R0 ;determine net class ADD #NG.GAT,R0 JSR PC,NTCLAS BR 4$ ;class a BR 3$ ;class b 2$: MOV NG.GAT(R4),(R2)+ ;(eh.net) class c MOVB NG.GAT+2(R4),(R2)+ CLRB (R2)+ BR 6$ ; 3$: MOV NG.GAT(R4),(R2)+ ;(eh.net) class b CLR (R2)+ BR 5$ ; 4$: MOVB NG.GAT(R4),(R2)+ ;(eh.net) class a CLRB (R2)+ CLR (R2)+ MOVB NG.GAT+1(R4),(R2)+ ;(eh.dat) 5$: MOVB NG.GAT+2(R4),(R2)+ 6$: MOVB NG.GAT+3(R4),(R2)+ JSR PC,ENCUPD ;encode update data BR OUT22 ; OUTHLO: MOVB #CD.HLO,EH.COD(R1) ;send hello command MOV NG.SND(R4),EH.SEQ(R1) BR OUT20 ; OUTIHU: MOVB #CD.IHU,EH.COD(R1) ;send i-h-u response OUT20: MOVB #EC.HLO,EH.TYP(R1) OUT22: CMPB NG.STA(R4),#2 ;complete status field BNE 1$ BISB #SF.DWN,EH.STA(R1) 1$: CMPB NG.STA(R4),#3 BNE EGPSND BISB #SF.UP,EH.STA(R1) ; ; Complete packet and send ; EGPSND: CLRB NG.CMD(R4) ;reset for next time MOV PKTPTR,R1 ;compute length SUB R1,R2 SUB PH.OFS(R1),R2 MOV R2,PH.LNG(R1) MOV HEDPTR,R2 ;complete egp header SWAB EH.SYS(R2) ;onward pdp11 SWAB EH.SEQ(R2) JSR PC,CHKSUM ;compute checksum MOV R0,EH.CHK(R2) JSR PC,DUMP CALL CTRL,#CM.SND,R1,OPNBLK+CONPTR ;send ip packet MOV R0,R2 ASL R2 ;decode return ADD R2,PC BR 3$ ;0 accepted BR 12$ ;1 connection open error BR 12$ ;2 invalid parameters BR 12$ ;3 insufficient resources NOP ;4 local host unreachable INC NG.UNR(R4) ;5 foreign net unreachable 3$: RTS PC ; 12$: JSR PC,PRIDNT ;fatal error .EXIT .PAGE .SBTTL Subroutines ; ; Subroutine to initialize neighbor ; NGBINI: JSR PC,NGBRST ;reset neighbor BIT #ST.ORG,NG.FLG(R4) ;is this operator-initiated BNE 1$ ;branch if yes CLR NG.T3(R4) ;no. stop timer t3 1$: CLRB NG.STA(R4) ;initialize protocol state RTS PC ; ; Subroutine to reset neighbor ; NGBRST: CLR NG.T1(R4) ;reset timers CLR NG.T2(R4) MOV #PAR.P5,NG.T3(R4) BIC #ST.ACT+ST.RCH+ST.HLO+ST.UNS,NG.FLG(R4) CLRB NG.RCH(R4) ;initialize reachability state CLRB NG.CMD(R4) CLRB NG.TXS(R4) RTS PC ; ; Encupd (enc) encode update ; r2 = data area pointer, r4 = gateway pointer, ; Returns r2 = updated data area pointer ; ENCUPD: MOV R1,-(SP) ;save goodies MOV R3,-(SP) MOV R2,R3 CLRB (R2)+ ;insert dist-count CLR R0 ;dist 1$: MOV R3,-(SP) ;save pointer MOV R2,R3 MOVB R0,(R2)+ ;insert dist, net-count CLRB (R2)+ MOV $GATAD,R1 ;scan for this dist 2$: BITB #GT.END,GATFLG(R1) ;is this end of table BNE 7$ ;branch if yes CMPB @R3,GATHOP(R1) ;no. does dist match entry BNE 6$ ;branch if no BITB #GT.HLO,GATFLG(R1) ;*** yes. is net directly reachable BEQ 6$ ;*** branch if no MOV R1,-(SP) ;yes. is it up MOVB GATHID(R1),R1 BIC #^C377,R1 MUL #HOSLEN,R1 ADD $HOSAD,R1 MOV R1,R0 MOV (SP)+,R1 CMP HOSDLY(R0),#TM.TTL BHIS 6$ ;branch if no MOV R1,R0 ;yes. determine net class ADD #GATNET,R0 JSR PC,NTCLAS BR 4$ ;class a BR 3$ ;class b MOVB GATNET(R1),(R2)+ ;class c. send it MOVB GATNET+1(R1),(R2)+ MOVB GATNET+2(R1),(R2)+ BR 5$ ; 3$: MOVB GATNET(R1),(R2)+ ;class b. send it MOVB GATNET+1(R1),(R2)+ BR 5$ ; 4$: MOVB GATNET(R1),(R2)+ ;class a. send it 5$: INCB 1(R3) 6$: ADD #GATLEN,R1 ;advance to next entry BR 2$ ; 7$: MOV R3,R0 ;restore pointer MOV (SP)+,R3 TSTB 1(R0) ;were there any nets BNE 8$ ;branch if yes MOV R0,R2 ;no. back up BR 9$ ; 8$: INCB @R3 ;increment dist-count 9$: MOVB @R0,R0 ;bump dist INC R0 BIT #X.ROUT,@PARPTR ;is dist in bounds BNE 10$ ;branch if no CMPB R0,#DIAMTR BLOS 1$ ;branch if yes 10$: MOV (SP)+,R3 ;restore goodies MOV (SP)+,R1 RTS PC ; ; Decupd (dec) decode gateway block ; r2 = data area pointer, r3 = egp header pointer, r4 = gateway pointer, ; Returns r2 = updated data area pointer ; DECUPD: MOV R2,R1 ;point to dist count TSTB (R2)+ 1$: TSTB @R1 ;is dist count zero BEQ 5$ ;branch if yes MOV R1,-(SP) ;no. save pointer MOV R2,R1 CMPB (R2)+,(R2)+ 2$: TSTB 1(R1) ;is net count zero BEQ 3$ ;branch if yes CMP R2,RSMPTR ;no. is address in bounds BHIS 4$ ;branch if no JSR PC,NTINSR ;yes. update net DECB 1(R1) ;advance to next net BR 2$ ; 3$: MOV (SP)+,R1 ;advance to next dist DECB @R1 BR 1$ ; 4$: MOV (SP)+,R1 ;format error SEC 5$: RTS PC ; ; Ntinsr (nti) insert new entry into net table ; R1 = distance pointer, r2 = data area pointer, r3 = egp header pointer, ; R4 = gateway pointer, returns r2 = updated data area pointer ; NTINSR: MOV R1,-(SP) ;preserve registers CLRB EGPHOP ;fiddle distance for protobum routers BIT #ST.ZER,NG.FLG(R4) BNE 1$ MOVB @R1,EGPHOP 1$: CLR -(SP) ;make some room CLR -(SP) MOV R2,R0 ;copy address and update pointer MOV SP,R1 JSR PC,NTCLAS BR 3$ ;class a BR 2$ ;class b MOVB (R2)+,(R1)+ ;class c 2$: MOVB (R2)+,(R1)+ ;class b 3$: MOVB (R2)+,(R1)+ ;class a CMPB EGPHOP,#DIAMTR ;no. is distance too far BHI 8$ ;branch if yes INCB EGPHOP ;no. update distance CMP NG.GAT(R4),EH.NET(R3) ;is the enemy us BNE 4$ ;branch if no CMP NG.GAT+2(R4),EH.NET+2(R3) BEQ 8$ ;branch if yes 4$: MOV SP,R1 ;find net table entry JSR PC,NTSRCH BCS 8$ ;branch if cant ; CMP EH.NET(R3),GATLDR(R0) ;yes. is this same gateway ; BNE 5$ ;branch if no ; CMP EH.NET+2(R3),GATLDR+2(R0) ; BEQ 6$ ;branch if yes 5$: CMPB EGPHOP,GATHOP(R0) ;no. is this way longer BHI 8$ ;branch if yes 6$: MOVB EGPHOP,GATHOP(R0) ;no. update net table MOVB EGPHIX,GATHID(R0) MOV NG.T2P(R4),R1 ASH #-2,R1 CMPB R1,GATTTL(R0) BLOS 7$ MOVB R1,GATTTL(R0) 7$: MOV EH.NET(R3),GATLDR(R0) MOV EH.NET+2(R3),GATLDR+2(R0) 8$: CMP (SP)+,(SP)+ ;recapture stack MOV (SP)+,R1 RTS PC ; ; Ntsrch (nts) search leader table ; R1 = internet address (word) pointer, returns r0 = net table pointer, ; Cc(c) = 1 if table full ; NTSRCH: MOV R1,-(SP) ;save .PSEM #SF.RUT ;lock routing tables MOV @SP,R1 TSTB @R1 ;find net table entry BEQ 5$ ;branch if bad format JSR PC,ADRMAP BCS 5$ ;branch if cant BITB #GT.END,GATFLG(R0) BNE 2$ ;branch if default BITB #GT.EGP,GATFLG(R0) ;is this egp entry BEQ 5$ ;branch if no BR 4$ ; 2$: JSR PC,GTCAC ;find free cache entry BCS 5$ ;branch if cant MOV @SP,R1 ;found. update entry MOV (R1)+,GATNET(R0) MOV (R1)+,GATNET+2(R0) MOV #377*400,GATMSK(R0) MOV #377*400+377,GATMSK+2(R0) CMPB GATNET(R0),#128. ;edit mask BLO 3$ ;branch if class a CLRB GATMSK+1(R0) CMPB GATNET(R0),#192. BLO 3$ ;branch if class b CLRB GATMSK+2(R0) ;class c 3$: BIC GATMSK(R0),GATNET(R0) BIC GATMSK+2(R0),GATNET+2(R0) MOVB #GT.EGP+GT.CAC,GATFLG(R0) MOVB #255.,GATHOP(R0) 4$: .VSEM #SF.RUT ;unlock routing tables CLC ;normal exit BR 6$ ; 5$: .VSEM #SF.RUT ;unlock routing tables SEC ;error exit 6$: MOV (SP)+,R1 RTS PC ; ; Adrmap (rut) find net entry ; R1 = internet address (word) pointer, returns r0 = gateway table pointer, ; r1 = host table pointer, c(cc) = 1 if not found ; ADRMAP: MOV R2,-(SP) ;save MOV $GATAD,R0 ;initialize pointer 1$: BITB #GT.ERR+GT.HOL,GATFLG(R0) BEQ 2$ ;branch if okay BITB #GT.END,GATFLG(R0) BEQ 4$ ;branch if not last 2$: BITB #GT.CAC,GATFLG(R0) BEQ 3$ ;branch if permanent TSTB GATTTL(R0) BEQ 4$ ;branch if inactive cache 3$: MOV @R1,R2 ;mask address BIC GATMSK(R0),R2 CMP GATNET(R0),R2 ;does entry match BNE 4$ ;branch if no MOV 2(R1),R2 BIC GATMSK+2(R0),R2 CMP GATNET+2(R0),R2 BNE 4$ ;branch if no CLR R1 ;yes. is hid in range BISB GATHID(R0),R1 CMPB R1,$HOSCT BHIS 5$ ;branch if no MUL #HOSLEN,R1 ;yes. get host table pointer ADD $HOSAD,R1 CLC ;normal return BR 6$ ; 4$: BITB #GT.END,GATFLG(R0) ;is there another entry BNE 5$ ;branch if no ADD #GATLEN,R0 ;yes. advance to next entry BR 1$ ; 5$: SEC ;error return 6$: MOV (SP)+,R2 ;evas RTS PC ; ; GTCAC (rut) find an empty cache entry ; Returns r0 = gateway table pointer, c(cc) = 1 if cant ; GTCAC: MOV $GATAD,R0 ;initialize pointer 1$: BITB #GT.END,GATFLG(R0) ;is there another entry BNE 3$ ;branch if no BITB #GT.CAC,GATFLG(R0) ;yes. is this empty cache entry BEQ 2$ ;branch if no TSTB GATTTL(R0) BEQ 4$ ;branch if yes 2$: ADD #GATLEN,R0 ;no. advance to next entry BR 1$ 3$: SEC ;error exit RTS PC ; 4$: CLC ;normal exit RTS PC ; ; Ntclas (ntc) determine entry format ; R0 = net pointer, returns +0 (class a), +2 (class b), +3 (class c) ; NTCLAS: CMPB @R0,#128. ;determine class BLO 3$ ;branch if class a CMPB @R0,#192. BLO 2$ ;branch if class b ADD #2,@SP ;class c. exit +4 2$: ADD #2,@SP ;class b. exit +2 3$: RTS PC ;class a. exit +0 ; ; Subroutine to update host table entry ; r4 = gateway pointer ; UPDATE: BIT #X.DFLT,@PARPTR ;is this default gateway BNE 9$ ;branch if no BIT #ST.DFT,NG.FLG(R4) BEQ 9$ ;branch if no MOV R1,-(SP) ;yes. save MOV R2,-(SP) .PSEM #SF.RUT ;lock routing tables MOV #ZERO,R1 ;find entry JSR PC,ADRMAP BCC 4$ ;branch if found CLR R1 ;not found. find free hid BISB $HOSCT+1,R1 MOVB R1,-(SP) MUL #HOSLEN,R1 ADD $HOSAD,R1 1$: CMPB @SP,$HOSCT ;is hid available BHIS 2$ ;branch if no TSTB HOSPID(R1) ;yes. is it free BEQ 3$ ;branch if yes ADD #HOSLEN,R1 ;no. advance to next one INCB @SP BR 1$ ; 2$: TSTB (SP)+ ;no hid available BR 8$ ; 3$: MOVB (SP)+,GATHID(R0) ;found free hid. initialize net entry 4$: CLR GATNET(R0) CLR GATNET+2(R0) MOV #-1,GATMSK(R0) MOV #-1,GATMSK+2(R0) MOV NG.ADR(R4),GATLDR(R0) ;yes. so specify MOV NG.ADR+2(R4),GATLDR+2(R0) CLRB GATHOP(R0) MOVB #GT.CAC+GT.HLO+GT.END,GATFLG(R0) MOV NG.T1P(R4),R2 ;update ttl ASR R2 CMPB R2,GATTTL(R0) BLOS 5$ MOVB R2,GATTTL(R0) 5$: MOV R1,-(SP) MOV R4,R1 ;find gateway hid ADD #NG.ADR,R1 JSR PC,ADRMAP MOVB HOSPID(R1),R0 MOV (SP)+,R1 BCS 8$ ;branch if cant MOVB R0,HOSPID(R1) ;update entry MOV NG.T1P(R4),R2 ;allow four hello intervals ASH #2,R2 CMP R2,#255. ;clamp to eight bits BLOS 6$ MOV #255.,R2 6$: CMPB R2,HOSTTL(R1) ;is it less than running timeout BLOS 7$ ;branch if yes MOVB R2,HOSTTL(R1) ;no. reset timeout 7$: MOV NG.TIM(R4),HOSTIM(R1) MOV NG.TIM+2(R4),HOSTIM+2(R1) MOV #TM.MIN,HOSDLY(R1) CLR HOSOFS(R1) 8$: .VSEM #SF.RUT ;unlock routing tables MOV (SP)+,R2 ;evas MOV (SP)+,R1 9$: RTS PC ; ; Subroutine to compute egp checksum ; R1 = packet pointer ; CHKSUM: MOV R1,-(SP) ;save few MOV R2,-(SP) CLR R0 MOV PH.LNG(R1),R2 ;get data pointers ADD PH.OFS(R1),R1 CLR -(SP) ;checksum block ASR R2 ROL @SP 1$: ADD (R1)+,R0 ;accumulate checksum ADC R0 DEC R2 BNE 1$ TST @SP BEQ 4$ MOVB (R1)+,@SP 4$: ADD (SP)+,R0 ADC R0 TST R0 ;clean up complement BEQ 2$ 3$: COM R0 2$: MOV (SP)+,R2 ;restore few MOV (SP)+,R1 RTS PC ; ; Subroutine to dump egp datagram ; R1 = packet pointer, r4 = gateway pointer ; DUMP: MOV R1,-(SP) ;save registers MOV R2,-(SP) MOV R3,-(SP) BIT #ST.DMP,NG.FLG(R4) ;is trace bit set BEQ 20$ ;branch if no MOV PH.OFS(R1),R2 ;yes. compute total packet length ADD PH.LNG(R1),R2 SUB #BUFLDR-1,R2 ASR R2 ADD #BUFLDR,R1 ;point to ip header MOV R1,TEMP ;display current address FORMAT #DMP00,#TEMP 4$: MOV #8.,R3 ;set loop count 2$: FORMAT #DMP01 ;display current word TST (R1)+ DEC R2 BLE 3$ ;branch if done SOB R3,2$ ;loop until end line FORMAT #DMP02 ;end line BR 4$ ; 3$: FORMAT #DMP03 ;end line 20$: MOV (SP)+,R3 ;restore registers MOV (SP)+,R2 MOV (SP)+,R1 RTS PC .PAGE .SBTTL COMMAND INTERPRETATION ; ; Initialization ; INIT: MOV #-1,R0 ;find highest usable address .SETTO CMP #STOEND,R0 ;will we fit BLOS 1$ ;branch if yes FORMAT #COM42 ;no. insufficient storage .EXIT ; 1$: MOV R0,@#50 ;reset upper limit MOV #STOBGN,R0 ;clear storage 2$: CLR (R0)+ CMP R0,#STOEND BLO 2$ .GTJB #ARGBLK,#AREA,#-1 ;get process parameters MOV AREA+16,PARPTR ADD #PAROPT,PARPTR .DSTAT #ARGBLK,#HOSPTR ;get table pointers BCC 4$ 3$: FORMAT #COM42A ;broken configuration .EXIT ; 4$: .MSG <#^RLOG> ;switch to log process MOV #2,ERRLVL MOV ARGBLK+4,R3 ;set par pointer MOV R3,R0 ;fetch ip address ADD #PARIDS,R0 ADD @R0,R0 MOV (R0)+,$NETID MOV (R0)+,$NETID+2 MOV AREA+2,R2 ;find free segment ADD #17777,R2 ASH #-5,R2 BIC #^C<7*400>,R2 MOV PARHOS(R3),R0 ;map to host table MOV PARHOS+2(R3),R1 SUB #2,R1 SBC R0 BIS R2,R0 .WIND MOV (R1)+,$HOSCT ;save header info MOV R1,$HOSAD ADD #400,R2 ;next free sedgment MOV PARNET(R3),R0 ;map to net table MOV PARNET+2(R3),R1 BIS R2,R0 .WIND MOV R1,$GATAD CALL CTRL,#CM.OPN,#OPNBLK+CONPAR,OPNBLK+CONPTR ;open egp connection TST R0 BEQ 5$ ;branch if ok JSR PC,PRIDNT ;print reason for failure .EXIT ; 5$: .MRKT #ARGBLK,#TIME,#GATICK,#1 ;start the bubble machine FORMAT #HERALD,CHAIN ;from the top RTS PC ; ; Unrecognized command ; NTFD: FORMAT #COM29 ;unrecognized command RTS PC ; ; Show (sho) display neighbor table ; (segment of command language interpreter) ; Arg = gateway id ; SHOW: CLR -(SP) ;initialize JSR PC,GTID ;get gateway id BNE 2$ ;branch if present FORMAT #COM2 ;invalid or missing. display header MOV #NGBTAB,R4 1$: TST NG.ADR(R4) ;is this end of table BEQ 3$ ;branch if yes MOV SP,R1 ;no. display gateway id FORMAT #COM8A FORMAT #COM8,R4 ;display entry ADD #NG.LEN,R4 ;advance to next entry INC @SP BR 1$ ; 2$: FORMAT #COM20,R4 ;display detail 3$: TST (SP)+ ;recover stack RTS PC ; ; Gateway (gat) create neighbor table entry ; (segment of command language interpreter) ; Arg1 = gateway number, arg2-5 = gateway address ; GATE: JSR PC,GTID ;get gateway id BEQ 3$ ;branch if invalid or missing MOV R4,R2 ;numeric. stash address MOV $NETID,(R2)+ MOV $NETID+2,(R2)+ MOV $NETID,(R2)+ MOV $NETID+2,(R2)+ MOV R4,R2 MOV #8.,R3 1$: JSR PC,RDDEC ;(arg3-arg5) BEQ 2$ MOVB R0,(R2)+ SOB R3,1$ 2$: JSR PC,NGBINI ;initialize neighbor MOV #ST.ORG+ST.ONL,NG.FLG(R4) MOV #PAR.P1,NG.P1(R4) MOV #PAR.P2,NG.P2(R4) 3$: RTS PC ; ; Quit (qui) leave the game ; (segment of command language interpreter) ; (no arguments) ; QUIT: .CMKT #ARGBLK,#1,#0 ;turn off the bubble machine CALL CTRL,#CM.CLS,#0,OPNBLK+CONPTR ;close connection .SPND ;wait for connection to die .EXIT ;return to cli ; ; Verbose (ver) be very noisy ; (segment of command language interpreter) ; arg = error levle ; VERB: JSR PC,RDDEC ;set error level MOV R0,ERRLVL RTS PC ; ; Output (cmd) change console device output ; (segment of command language interpreter) ; Arg = output device name ; OUTP: JSR PC,HASH ;get new name BEQ 1$ ;branch if missing .MSG RTS PC ; 1$: .MSG <#^RTT > ;default to "tt" RTS PC ; ; Start (cmd) start protocol ; (segment of command language interpreter) ; Arg1 = gateway id, arg2 = hello interval, arg3 = poll interval ; STRT: JSR PC,GTID ;get gateway id BEQ 3$ ;branch if invalid or missing JSR PC,RDDEC ;(arg2) get hello interval BNE 1$ ;branch if given MOV #PAR.P1,R0 ;missing. assume default 1$: MOV R0,NG.P1(R4) JSR PC,RDDEC ;(arg3) get poll interval BNE 2$ ;branch if given MOV #PAR.P2,R0 ;missing. assume default 2$: MOV R0,NG.P2(R4) FSA #EV.STR ;start protocol 3$: RTS PC ; ; Stop (cmd) stop protocol ; (segment of command language interpreter) ; Arg1 = gateway id, arg2 = stop code ; STOX: JSR PC,GTID ;get gateway id BEQ 1$ ;branch if invalid or missing JSR PC,RDDEC ;(arg2) get stop code BNE 2$ ;branch if given MOV #SF.STP,R0 ;missing. assume operator initiated 2$: MOVB R0,NG.TXS(R4) FSA #EV.STP ;stop protocol 1$: RTS PC ; ; On (on) set options on ; Arg1 = gateway id, arg2 = "trace", "active" or "line" ; ONSW: JSR PC,GTID ;get gateway id BEQ 5$ ;branch if invalid or missing 1$: JSR PC,HASH ;get argument BEQ 5$ ;branch if end MOV #OPTABL,R1 ;search for match 2$: TST @R1 BEQ 4$ ;branch if not found CMP R0,(R1)+ BEQ 3$ ;branch if found TST (R1)+ BR 2$ ; 3$: BIS @R1,NG.FLG(R4) ;update flags BR 1$ ; 4$: FORMAT #COM28 ;invalid argument 5$: RTS PC ; ; Off (off) set options off ; Arg1 = gateway id, arg2 = "trace", "active" or "line" ; OFSW: JSR PC,GTID ;get gateway id BEQ 5$ ;branch if invalid or missing 1$: JSR PC,HASH ;get argument BEQ 5$ ;branch if end MOV #OPTABL,R1 ;search for match 2$: TST @R1 BEQ 4$ ;branch if not found CMP R0,(R1)+ BEQ 3$ ;branch if found TST (R1)+ BR 2$ ; 3$: BIC @R1,NG.FLG(R4) ;update flags BR 1$ ; 4$: FORMAT #COM28 ;invalid argument 5$: RTS PC ; ; Subroutine to get gateway id ; Returns r4 = neighbor table pointer, cc(z) = 1 if invalid or missing ; GTID: JSR PC,RDDEC ;(arg) get geteway id BEQ 1$ ;branch if missing CMP R0,NGBTAB-2 ;present. is it in range BHIS 2$ ;branch if no MUL #NG.LEN,R0 ;compute entry pointer MOV R1,R4 ADD #NGBTAB,R4 RTS PC ; 2$: FORMAT #COM28 ;invalid argument 1$: SEZ ;invalid or missing RTS PC .PAGE .SBTTL TABLES, TEXT STRINGS AND VARIABLES ; ; Data segment ; .PSECT $BOSD,RO,D ; ; Command table for kwik ; KWKTBL: .KWTAB ,HELP ;send help information .KWTAB ,SHOW ;show gate status .KWTAB ,GATE ;show gateway status .KWTAB ,QUIT ;leave the game .KWTAB ,VERB ;set error level .KWTAB ,OUTP ;select log device .KWTAB ,STRT ;start protocol .KWTAB ,STOX ;stop protocol .KWTAB ,ONSW ;enable options .KWTAB ,OFSW ;disable options .KWTAB < >,NTFD ;end of table ; ; Option table for "on"/"off" ; OPTABL: .WORD <^RTRA>,ST.DMP ;formatted packet dump (debug) .WORD <^RACT>,ST.ORG ;active acquisition mode .WORD <^RLIN>,ST.ONL ;online .WORD <^RZER>,ST.ZER ;zero .WORD 0 ;end of table ; ; Event decoding ; DECODE: .WORD 6 .WORD 0 ;0 invalid .WORD EV.UPD ;1 update .WORD EV.POL+200 ;2 poll .WORD DECACQ ;3 neighbor acquisition .WORD 0 ;4 invalid .WORD DECRCH ;5 neighbor reachability ENDODE = . ;end of table ; DECACQ: .WORD 5 .WORD EV.REQ+200 ;0 request .WORD EV.CFM ;1 confirm .WORD EV.REF ;2 refuse .WORD EV.CEA+200 ;3 cease .WORD EV.CAK ;4 cease-ack ENDACQ = . ;end of table ; DECRCH: .WORD 2 .WORD EV.HLO+200 ;0 hello .WORD EV.IHU ;1 i heard you ENDRCH = . ;end of table ; ; State transition table ; ; 0 Idle 1 Aqsn 2 Down 3 Up 4 Cease ; +-----------+-----------+-----------+-----------+-----------+ ; Up |0 |1 |3/Poll |3 |4 | ; Down |0 |1 |2 |2 |4 | ; Request |2/Confirm |2/Confirm |2/Confirm |2/Confirm |4/Cease | ; Confirm |0/Cease |2 |2 |3 |4 | ; Refuse |0/Cease |0 |2 |3 |4 | ; Cease |0/Cease-ack|0/Cease-ack|0/Cease-ack|0/Cease-ack|0/Cease-ack| ; Cease-ack |0 |1 |2 |3 |0 | ; Hello |0/Cease |1 |2/I-H-U |3/I-H-U |4 | ; I-H-U |0/Cease |1 |2/Process |3/Process |4 | ; Poll |0/Cease |1 |2 |3/Update |4 | ; Update |0/Cease |1 |2 |3/Process |4 | ; Start |1/Request |1/Request |1/Request |1/Request |4 | ; Stop/t3 |1/Request |0 |4/Cease |4/Cease |0 | ; t1 |0 |1/Request |2/Hello |3/Hello |4/Cease | ; t2 |0 |1 |2 |3/Poll |4 | ; +-----------+-----------+-----------+-----------+-----------+ ; STATE: .WORD STAT00,STAT01,STAT02,STAT03,STAT04 ;state index table ; ; Idle State (0) ; STAT00: .WORD 0,NOOP ;0 Up reachability indication .WORD 0,NOOP ;1 Down reachability indication .WORD 2,REQST1 ;2 Request command .WORD 0,CEASE3 ;3 Confirm response .WORD 0,CEASE3 ;4 Refuse response .WORD 0,CEASE1 ;5 Cease command .WORD 0,NOOP ;6 Cease-ack response .WORD 0,CEASE3 ;7 Hello command .WORD 0,CEASE3 ;8 I-H-U response .WORD 0,CEASE3 ;9 Poll command .WORD 0,CEASE3 ;10 Update response .WORD 1,START ;11 Start request .WORD 1,START ;12 * Stop request or timer t3 underflow .WORD 0,NOOP ;13 timer t1 underflow .WORD 0,NOOP ;14 timer t2 underflow ; ; Acquisition State (1) ; STAT01: .WORD 1,NOOP ;0 Up reachability indication .WORD 1,NOOP ;1 Down reachability indication .WORD 2,REQST1 ;2 Request command .WORD 2,CNFRM ;3 Confirm response .WORD 0,RFUSE ;4 Refuse response .WORD 0,CEASE ;5 Cease command .WORD 1,NOOP ;6 Cease-ack response .WORD 1,NOOP ;7 Hello command .WORD 1,NOOP ;8 I-H-U response .WORD 1,NOOP ;9 Poll command .WORD 1,NOOP ;10 Update response .WORD 1,START ;11 Start request .WORD 0,TIMOT ;12 Stop request or timer t3 underflow .WORD 1,RSTRT ;13 timer t1 underflow .WORD 1,NOOP ;14 timer t2 underflow ; ; Down State (2) ; STAT02: .WORD 3,UPITY1 ;0 Up reachability indication .WORD 2,NOOP ;1 Down reachability indication .WORD 2,REQST ;2 Request command .WORD 2,NOOP ;3 Confirm response .WORD 2,NOOP ;4 Refuse response .WORD 0,CEASE ;5 Cease command .WORD 2,NOOP ;6 Cease-ack response .WORD 2,HELLO ;7 Hello command .WORD 2,HEARD ;8 I-H-U response .WORD 2,NOOP ;9 Poll command .WORD 2,NOOP ;10 Update response .WORD 1,START ;11 Start request .WORD 4,STOP ;12 Stop request or timer t3 underflow .WORD 2,TIMR1 ;13 timer t1 underflow .WORD 2,NOOP ;14 timer t2 underflow ; ; Up State (3) ; STAT03: .WORD 3,NOOP ;0 Up reachability indication .WORD 2,UPITY2 ;1 Down reachability indication .WORD 2,REQST1 ;2 Request command .WORD 3,NOOP ;3 Confirm response .WORD 3,NOOP ;4 Refuse response .WORD 0,CEASE ;5 Cease command .WORD 3,NOOP ;6 Cease-ack response .WORD 3,HELLO ;7 Hello command .WORD 3,HEARD ;8 I-H-U response .WORD 3,POLL ;9 Poll command .WORD 3,UPDAT ;10 Update response .WORD 1,START ;11 Start request .WORD 4,STOP ;12 Stop request or timer t3 underflow .WORD 3,TIMR1 ;13 timer t1 underflow .WORD 3,TIMR2 ;14 timer t2 underflow ; ; Cease State (4) ; STAT04: .WORD 4,NOOP ;0 Up reachability indication .WORD 4,NOOP ;1 Down reachability indication .WORD 4,CEASE3 ;2 Request command .WORD 4,NOOP ;3 Confirm response .WORD 4,NOOP ;4 Refuse response .WORD 0,CEASE ;5 Cease command .WORD 0,CEASE2 ;6 Cease-ack response .WORD 4,NOOP ;7 Hello command .WORD 4,NOOP ;8 I-H-U response .WORD 4,NOOP ;9 Poll command .WORD 4,NOOP ;10 Update response .WORD 4,NOOP ;11 Start request .WORD 0,TIMOT ;12 Stop request or timer t3 underflow .WORD 4,RSTOP ;13 timer t1 underflow .WORD 4,NOOP ;14 timer t2 underflow ; ZERO: .WORD 0,0 ;innocent zeros TIME: .WORD 0,60. ;one-second timeout HOSPTR: .RAD50 /HOS/ ;name of host process ; ; Bit population count ; BITPOP: .BYTE 0 ;0000 .BYTE 1 ;0001 .BYTE 1 ;0010 .BYTE 2 ;0011 .BYTE 1 ;0100 .BYTE 2 ;0101 .BYTE 2 ;0110 .BYTE 3 ;0111 .BYTE 1 ;1000 .BYTE 2 ;1001 .BYTE 2 ;1010 .BYTE 3 ;1011 .BYTE 2 ;1100 .BYTE 3 ;1101 .BYTE 3 ;1110 .BYTE 4 ;1111 ; ; Text strings for gate protocol ; HERALD: .ASCIZ '?EGP-I-Gateway Process (25-Mar-86 Version) ^LD' COM00: .ASCIZ '?EGP-^+' COM2: .ASCII 'GateID Gateway State Reach Hello Poll SndSeq RcvSeq Update^/' .ASCIZ '--------------------------------------------------------------------------------' ; COM8: .ASCII '^C'' ^BI'' ^BK' .ASCII ' ^I'' ^I' .ASCIZ ' ^I'' ^I'' ^+T' COM8A: .ASCIZ '^I'<0>' ^+' COM20: .ASCII 'Tally Event Action^/' .ASCII '------------------------------^/' .ASCII 'Request ^I'' ^I'' ' .ASCII ' Neighbor ^C''^/' .ASCII 'Confirm ^I'' ^I'' ' .ASCII ' Gateway ^C''^/' .ASCII 'Refuse ^I'' ^I'' ' .ASCII ' Flags ^K''^/' .ASCII 'Cease ^I'' ^I'' ' .ASCII ' System ^I''^/' .ASCII 'Cease-ack ^I'' ^I'' ' .ASCII ' Hello interval ^I''^/' .ASCII 'Hello ^I'' ^I'' ' .ASCII ' Poll interval ^I''^/' .ASCII 'I-H-U ^I'' ^I'' ' .ASCII ' Status ^BI''^/' .ASCII 'Poll ^I'' ^I'' ' .ASCII ' Bad format ^I''^/' .ASCII 'Update ^I'' ^I'' ' .ASCII ' Bad checksum ^I''^/' .ASCII 'Start ^I'' ^I'' ' .ASCII ' Dropped ^I''^/' .ASCII 'Stop ^I'' ^I'' ' .ASCII ' Unreachable ^I''^/' .ASCII 'Up ^I'' ' .ASCII ' No buffer ^I''^/' .ASCII 'Down ^I''^/' .ASCII 'Timer 1 ^I''^/' .ASCIZ 'Timer 2 ^I' DMP00: .ASCIZ '^K'<0>' ^+' DMP01: .ASCIZ ' ^K'<0>'^+' DMP02: .ASCIZ '^/ ^+' DMP03: .BYTE 0 ; ; Text strings for error conditions ; COM42: .ASCIZ '?EGP-F-Insufficient storage' COM42A: .ASCIZ '?EGP-F-Broken configuration' COM29: .ASCIZ '?EGP-F-Unrecognized command' COM28: .ASCIZ '?EGP-F-Invalid argument' COM40: .ASCIZ '?EGP-I-New neighbor ^C' COM41: .ASCIZ '?EGP-I-Neighbor ^C'' up ^BK' COM42B: .ASCIZ '?EGP-I-Neighbor ^C'' down ^BK' COM43: .ASCIZ '?EGP-I-Neighbor ^C'' request ^BK' COM42C: .ASCIZ '?EGP-I-Neighbor ^C'' confirm ^BK' COM42D: .ASCIZ '?EGP-I-Neighbor ^C'' refuse ^BK' COM42E: .ASCIZ '?EGP-I-Neighbor ^C'' cease ^BK' COM42F: .ASCIZ '?EGP-I-Neighbor ^C'' cease-ack ^BK' COM42X: .ASCIZ '?EGP-I-Neighbor ^C'' format error' COM42J: .ASCIZ '?EGP-I-Start request ^C' COM42G: .ASCIZ '?EGP-I-Stop request ^C' .EVEN ; .PSECT $DATA,RW,I ; ; Gate connection data ; OPNBLK: OPNBLK 0,EGP,EGPBLK,RTPSIZ,NETSUB,P.EGP,300 ;egp block $NETID: .WORD 0,0 ;internet address $HOSCT: .BYTE 0,0 ;host table header $HOSAD: .WORD 0 ;host table pointer $GATAD: .WORD 0 ;net table pointer $NTSEQ: .WORD 1 ;update sequence number ; .PSECT $ERAS,RW,I STOBGN = . ;beginning of erasable storage ; ; Variables ; EGPHIX: .BLKB 1 ;gateway host id EGPHOP: .BLKB 1 ;distance NGBID: .BLKB 1 ;gateway id .EVEN TEMP: .BLKW 1 ;busy little temporary PARPTR: .BLKW 1 ;options-word pointer PKTPTR: .BLKW 1 ;packet pointer HEDPTR: .BLKW 1 ;header pointer RSMPTR: .BLKW 1 ;reassembly pointer ARGBLK: .BLKW 5 ;rt-11 argument block AREA: .BLKW 39. ;scratch area EGPBLK: .BLKW RTPSIZ/2 ;connection block EGPRSM: .BLKB 1000. ;reassembly buffer (min size) STOEND = . .EVEN ; .END