// GateConRoute.bcpl -- talks to the Gateway forwarder process // Last modified July 2, 1983 10:06 PM by Boggs get "Pup0.decl" get "Pup1.decl" get "GateForward.decl" external [ // outgoing procedures CreateRouteCtx; RestartRoute; Route RouteSummary; TransitMatrix; GetNetTable // incoming procedures OpenLevel1Socket; CloseLevel1Socket; GetBuf; ReleasePBI InitializeContext; Block; SetTimer; TimerHasExpired Zero; MoveBlock; Allocate; Free; Enqueue; Dequeue; ReturnFrom TopLevel; ResetCmdMenu; CreateCmdBox; BoxProc Ws; Wss; Puts; PutTemplate SendCommand; HEnumerate // incoming statics dsp; ctxQ; sysZone; pupRT; gcHost; oldStatsQ ] static @ru structure RU: // ru -> this 'global frame' for this module [ soc word // -> PupSoc stats word // -> Router Stats block timer word // update stats when this expires ] manifest lenRU = size RU/16 //---------------------------------------------------------------------------- let CreateRouteCtx() be //---------------------------------------------------------------------------- [ Enqueue(ctxQ, InitializeContext(Allocate(sysZone, 150), 150, RouteCtx)) ru = Allocate(sysZone, lenRU); Zero(ru, lenRU) ru>>RU.soc = Allocate(sysZone, lenPupSoc); OpenLevel1Socket(ru>>RU.soc) ] //---------------------------------------------------------------------------- and RestartRoute() be //---------------------------------------------------------------------------- [ SetTimer(lv ru>>RU.timer, 0) if ru>>RU.stats ne 0 then [ Enqueue(oldStatsQ, ru>>RU.stats); ru>>RU.stats = 0 ] ] //---------------------------------------------------------------------------- and Route() be //---------------------------------------------------------------------------- [ ResetCmdMenu() CreateCmdBox(TopLevel, "TopLevel") if gcHost ne 0 then CreateCmdBox(FrnRoutingTable, "FrnRoutingTable") CreateCmdBox(LclRoutingTable, "LclRoutingTable") // ResetCmdMenu destroyed the BoxQ which BoxProc is following. // If we just return now, BoxProc will get horribly confused. // So don't let it continue: force a return from BoxProc. ReturnFrom(BoxProc) ] //---------------------------------------------------------------------------- and RouteCtx(ctx) be //a context //---------------------------------------------------------------------------- [ Block() repeatuntil TimerHasExpired(lv ru>>RU.timer) & gcHost ne 0 SetTimer(lv ru>>RU.timer, 500) let pbi = GetBuf(ru>>RU.soc) pbi>>PBI.pup.dPort.socket^2 = psRouteInfo pbi = SendCommand(pbi, ptStatsRequest, pupOvBytes, (ru>>RU.stats? 1, 3)) if pbi ne 0 then [ let stats = lv pbi>>PBI.pup.words if pbi>>PBI.pup.type eq ptStatsReply & stats>>Stats.version eq gfStatsVersion then [ if ru>>RU.stats then Enqueue(oldStatsQ, ru>>RU.stats) let lenStatBlock = (pbi>>PBI.pup.length-pupOvBytes)/2 ru>>RU.stats = Allocate(sysZone, lenStatBlock) MoveBlock(ru>>RU.stats, stats, lenStatBlock) ] ReleasePBI(pbi) ] ] repeat //---------------------------------------------------------------------------- and RouteSummary(stream) be //---------------------------------------------------------------------------- [ if ru>>RU.stats ne 0 then PutTemplate(stream, "Route: $EUD ", lv ru>>RU.stats>>Stats.routeReqs) ] //---------------------------------------------------------------------------- and GetNetTable(v) = valof //---------------------------------------------------------------------------- // called from Level0Stats to get info to build its menu. [ if ru>>RU.stats eq 0 resultis false v!0 = ru>>RU.stats>>Stats.numNets v!1 = ru>>RU.stats + lenStats ] //---------------------------------------------------------------------------- and TransitMatrix(stream) be //---------------------------------------------------------------------------- [ let stats = ru>>RU.stats; if stats eq 0 return let netTable = stats + lenStats let numNets = stats>>Stats.numNets Wss(stream, " Discard") for i = 0 to numNets-1 if netTable!i ne 0 then PutTemplate(stream, "$10UO", netTable!i) for sNet = 0 to numNets-1 do [ if netTable!sNet eq 0 loop PutTemplate(stream, "*N$3O", netTable!sNet) PrintCount(stream, stats, (netTable!sNet)&377b, 0) //discard column for dNet = 0 to numNets-1 if netTable!dNet ne 0 then PrintCount(stream, stats, (netTable!sNet)&377b, (netTable!dNet)&377b) ] ] //---------------------------------------------------------------------------- and PrintCount(stream, stats, sNet, dNet) be //---------------------------------------------------------------------------- [ for i = 0 to stats>>Stats.numTMEs-1 do [ let tme = stats + lenStats + stats>>Stats.numNets + i*lenTME if tme>>TME.sNet eq sNet & tme>>TME.dNet eq dNet then [ PutTemplate(stream, "$10UED", lv tme>>TME.count) return ] ] Wss(stream, " - ") ] //---------------------------------------------------------------------------- and FrnRoutingTable() be //---------------------------------------------------------------------------- [ let soc = vec lenPupSoc; OpenLevel1Socket(soc) let pbi = GetBuf(soc) pbi>>PBI.pup.dPort.socket^2 = psRouteInfo pbi = SendCommand(pbi, ptRouteRequest, pupOvBytes, 1) if pbi then [ Enqueue(lv soc>>PupSoc.iQ, pbi) RTTitle("*NForeign routing table:") ] let count = 0 let timer = nil; SetTimer(lv timer, 1000) // 5 seconds [ Block() repeatuntil soc>>PupSoc.iQ.head ne 0 % TimerHasExpired(lv timer) let pbi = Dequeue(lv soc>>PupSoc.iQ.head); if pbi eq 0 break if pbi>>PBI.pup.type eq ptRouteReply then for i = 1 to pbi>>PBI.pup.length-pupOvBytes by 4 do RTEntry(pbi>>PBI.pup.bytes^i, pbi>>PBI.pup.bytes^(i+1), pbi>>PBI.pup.bytes^(i+2), pbi>>PBI.pup.bytes^(i+3), lv count) ReleasePBI(pbi) ] repeat CloseLevel1Socket(soc) ] //---------------------------------------------------------------------------- and LclRoutingTable() be //---------------------------------------------------------------------------- [ let PerNet(rte, lvCount) be RTEntry(rte>>RTE.net, rte>>RTE.ndb>>NDB.localNet, rte>>RTE.host, rte>>RTE.hops, lvCount) let count = 0 RTTitle("*NLocal routing table:") HEnumerate(pupRT, PerNet, lv count) ] //---------------------------------------------------------------------------- and RTTitle(string) be //---------------------------------------------------------------------------- [ Ws(string) Ws("*N Net Via Hops | Net Via Hops | Net Via Hops | Net Via Hops") Ws("*N -----------------|------------------|------------------|-----------------") ] //---------------------------------------------------------------------------- and RTEntry(dNet, viaNet, viaHost, hops, lvCount) be //---------------------------------------------------------------------------- [ if @lvCount rem 4 eq 0 then Ws("*N ") PutTemplate(dsp, "$U3O $U3O#$U3F0O# $U2O ", dNet, viaNet, viaHost, hops) unless @lvCount rem 4 eq 3 do Ws(" | ") @lvCount = @lvCount +1 ]