<> <> <> <> DIRECTORY Process USING [SetTimeout, MsecToTicks], BufferDefs USING [AdjustBufferSize, DataWordsPerPupBuffer, PupBuffer, BufferAccessHandle, MakeBufferPool, FreeBufferPool], CommFlags USING [doDebug], CommUtilDefs USING [GetEthernetHostNumber], DriverDefs USING [GetGiantVector, Glitch, Network, RouterObject, SetPupRouter, MaybeGetFreePupBuffer, GetDeviceChain, CommPackageGo, CommPackageOff], GermSwap USING [switches], PupDefs USING [ --defaultNumberOfNetworks,-- SetPupContentsWords, PupRouterBroadcastThis], PupRouterDefs USING [BeSurePupIsOn, checksum, dataWordsPerPup, firstSocket, GetRoutingTableEntry, inThings, maxHop, outThings, PupBroadcaster, PupChecksums, PupErrors, PupInputer, PupRouterIn, PupRouterOut, routerIsActive, routingTable, RoutingTable, RoutingTableEntry, RoutingTableObject, RoutingTableSeq, Timeout], PupStream USING [], PupTypes USING [PupNetID, gatewaySoc]; PupRouterCold: MONITOR LOCKS routerLock IMPORTS GermSwap, BufferDefs, CommUtilDefs, DriverDefs, Process, PupDefs, PupRouterDefs EXPORTS PupStream, PupDefs, PupRouterDefs SHARES BufferDefs = PUBLIC BEGIN OPEN PupRouterDefs; Network: TYPE = DriverDefs.Network; routerLock: PUBLIC MONITORLOCK; routingTableUpdateTimeout: PUBLIC CONDITION; probeResponse: PUBLIC CONDITION; numberOfNetworks: PUBLIC CARDINAL _ 255--PupDefs.defaultNumberOfNetworks--; pupUseCount: CARDINAL _ 0; routerTimeoutFork: PROCESS; pupBuffersToAllocate: CARDINAL _ 50; pupBuffers: BufferDefs.BufferAccessHandle _ NIL; doDebug: BOOLEAN = CommFlags.doDebug; router: DriverDefs.RouterObject _ [input: LOOPHOLE[PupInputer], broadcast: LOOPHOLE[PupBroadcaster], addNetwork: AddNetwork, removeNetwork: RemoveNetwork, stateChanged: StateChanged]; CantChangeBuffersWhenActive: PUBLIC ERROR = CODE; AdjustBufferParms: PUBLIC SAFE PROCEDURE [bufferPoolSize, bufferSize: CARDINAL] = TRUSTED BEGIN IF doDebug AND pupUseCount # 0 THEN DriverDefs.Glitch[CantChangeBuffersWhenActive]; IF bufferPoolSize # 0 THEN pupBuffersToAllocate _ bufferPoolSize; IF bufferSize # 0 THEN BufferDefs.AdjustBufferSize[bufferSize]; END; PupPackageMake: PUBLIC ENTRY SAFE PROCEDURE = TRUSTED BEGIN routing: RoutingTable; firstNetwork: Network; IF (pupUseCount _ pupUseCount + 1) > 1 THEN RETURN; DriverDefs.CommPackageGo[]; pupBuffers _ BufferDefs.MakeBufferPool[ total: pupBuffersToAllocate, reserve: 0]; dataWordsPerPup _ BufferDefs.DataWordsPerPupBuffer[]; firstNetwork _ DriverDefs.GetDeviceChain[]; routing _ NEW[RoutingTableSeq[numberOfNetworks + 1]]; -- allocates network zero too routingTable _ routing; routerIsActive _ TRUE; <> FOR i: CARDINAL IN [0..routing.length) DO routing[i] _ [net: [i], hop: maxHop + 1, time: 210, route:, network: NIL]; ENDLOOP; <> FOR network: Network _ firstNetwork, network.next UNTIL network = NIL DO IF network.hostNumber=0 THEN BEGIN -- Probably a DLion (or something else without an EthernetOne) network.hostNumber _ CommUtilDefs.GetEthernetHostNumber[]; END; AddNetwork[network]; ENDLOOP; DriverDefs.SetPupRouter[@router]; routerTimeoutFork _ FORK Timeout[]; IF firstNetwork = NIL THEN RETURN; IF firstNetwork.device = local THEN RETURN; -- avoid hanging <> <> <> FOR i: CARDINAL IN [0..10) DO gotRoutingPup: BOOLEAN _ FALSE; ProbeForRoutingInfo[]; WAIT probeResponse; FOR i: CARDINAL IN [0..routing.length) DO IF routing[i].network # NIL AND routing[i].hop # 0 THEN gotRoutingPup _ TRUE; ENDLOOP; IF gotRoutingPup THEN EXIT; ENDLOOP; END; ProbeForRoutingInfo: PROCEDURE = BEGIN b: BufferDefs.PupBuffer; b _ DriverDefs.MaybeGetFreePupBuffer[]; IF b = NIL THEN RETURN; b.bypassZeroNet _ FALSE; b.pupType _ gatewayRequest; b.pupID _ [0, 0]; b.dest.socket _ b.source.socket _ PupTypes.gatewaySoc; PupDefs.SetPupContentsWords[b, 0]; PupDefs.PupRouterBroadcastThis[b]; END; PupPackageDestroy: PUBLIC SAFE PROCEDURE = TRUSTED BEGIN IF doDebug THEN BeSurePupIsOn[]; IF PupPackageDestroyLocked[] THEN RETURN; JOIN routerTimeoutFork; IF doDebug THEN DriverDefs.GetGiantVector[].pupRoutingTable _ DESCRIPTOR[NIL, 0]; BufferDefs.FreeBufferPool[pupBuffers]; DriverDefs.CommPackageOff[]; END; PupPackageDestroyLocked: ENTRY PROCEDURE RETURNS [BOOLEAN] = INLINE BEGIN IF (pupUseCount _ pupUseCount - 1) # 0 THEN RETURN[TRUE]; DriverDefs.SetPupRouter[NIL]; routerIsActive _ FALSE; NOTIFY routingTableUpdateTimeout; RETURN[FALSE]; END; GetPupPackageUseCount: PUBLIC SAFE PROCEDURE RETURNS [CARDINAL] = CHECKED BEGIN RETURN[pupUseCount]; END; AddNetwork: PROCEDURE [network: Network] = BEGIN net: PupTypes.PupNetID _ [network.netNumber.b]; rte: RoutingTableEntry; IF ~network.alive THEN RETURN; IF routingTable[0].network = NIL THEN routingTable[0] _ [net: [0], hop: 0, time: 0, route: [0], network: network]; rte _ GetRoutingTableEntry[net]; IF rte # NIL THEN rte^ _ [net: net, hop: 0, time: 0, route: [0], network: network]; END; RemoveNetwork: PROCEDURE [network: Network] = BEGIN probe: BOOLEAN _ FALSE; FOR i: CARDINAL IN [0..routingTable.length) DO IF routingTable[i].network # network THEN LOOP; routingTable[i] _ [net: [i], hop: maxHop + 1, time: 210, route:, network: NIL]; probe _ TRUE; ENDLOOP; IF probe THEN ProbeForRoutingInfo[]; END; StateChanged: PROCEDURE [network: Network] = BEGIN RemoveNetwork[network]; AddNetwork[network]; END; <> SetPupStormy: PUBLIC PROCEDURE [new: BOOLEAN] = BEGIN outThings.outStormy _ inThings.inStormy _ new; END; SetBadPupProc: PUBLIC PROCEDURE [proc: PROCEDURE [BufferDefs.PupBuffer]] = BEGIN inThings.badChecksumProc _ proc; END; InspectIncomingPups: PUBLIC PROCEDURE [ new: BOOLEAN, proc: PROCEDURE [CARDINAL, BufferDefs.PupBuffer]] = BEGIN inThings.showIn _ new; inThings.inShower _ proc; END; InspectOutgoingPups: PUBLIC PROCEDURE [ new: BOOLEAN, proc: PROCEDURE [CARDINAL, BufferDefs.PupBuffer]] = BEGIN outThings.showOut _ new; outThings.outShower _ proc; END; InspectStrayPups: PUBLIC SAFE PROCEDURE [ on, seeBroadcast: BOOLEAN, proc: PROCEDURE [BufferDefs.PupBuffer] RETURNS [error: BOOLEAN]] = TRUSTED BEGIN inThings.watcherIsWatching _ on; inThings.watcherSeesBroadcast _ seeBroadcast; inThings.watcherCallsThis _ proc; END; UseNullChecksumMicrocode: PUBLIC PROCEDURE = BEGIN PupRouterDefs.checksum _ none; END; UseSoftwareChecksumMicrocode: PUBLIC PROCEDURE = BEGIN PupRouterDefs.checksum _ software; END; UseAltoChecksumMicrocode: PUBLIC PROCEDURE = BEGIN PupRouterDefs.checksum _ alto; END; UsePrincOpsChecksumMicrocode: PUBLIC PROCEDURE = BEGIN PupRouterDefs.checksum _ princOps; END; <> START PupRouterDefs.PupRouterIn; START PupRouterDefs.PupRouterOut; START PupRouterDefs.PupChecksums; START PupRouterDefs.PupErrors; Process.SetTimeout[@routingTableUpdateTimeout, Process.MsecToTicks[30000]]; Process.SetTimeout[@probeResponse, Process.MsecToTicks[500]]; IF doDebug THEN BEGIN DriverDefs.GetGiantVector[].firstPupSocket _ @firstSocket; END; IF NOT GermSwap.switches[c] THEN PupPackageMake[]; END.