// 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
]