<> <> <> <> DIRECTORY Basics USING [LongNumber], Process USING [InitializeCondition], ProcessorFace USING [GetClockPulses], CommFlags USING [doDebug], CommUtilDefs USING [MaybeShorten], PupRouterDefs USING [routerLock, BeSurePupIsOn, GetRoutingTableEntry, RoutingTableEntry, routingTable, RoutingTable, firstSocket, PupRouterSocket], DriverDefs USING [Network, GetDeviceChain], PupDefs USING [], BufferDefs USING [QueueInitialize, QueueCleanup], PupTypes USING [fillInNetID, fillInHostID, fillInSocketID, PupAddress, PupNetID, PupSocketID, Pair]; PupRouterCool: MONITOR LOCKS PupRouterDefs.routerLock IMPORTS Process, ProcessorFace, CommUtilDefs, DriverDefs, PupRouterDefs, BufferDefs EXPORTS PupDefs, PupRouterDefs = PUBLIC BEGIN OPEN PupTypes, PupRouterDefs; spareSocket: CARDINAL _ 1000B; nextConnectionID: CARDINAL _ 1000; UniqueLocalPupSocketID: ENTRY SAFE PROCEDURE RETURNS [socket: PupSocketID] = TRUSTED BEGIN mumble: LONG CARDINAL _ ProcessorFace.GetClockPulses[]; -- Alto Pulses are short IF (spareSocket _ spareSocket + 1) = 0 THEN spareSocket _ 1000B; socket _ [LOOPHOLE[mumble, Basics.LongNumber].lowbits, spareSocket]; END; UniqueLocalPupAddress: SAFE PROCEDURE [him: PupAddress] RETURNS [me: PupAddress] = TRUSTED BEGIN RETURN[GetLocalPupAddress[PupTypes.fillInSocketID, him]]; END; AnyLocalPupAddress: SAFE PROCEDURE[soc: PupSocketID] RETURNS [me: PupAddress] = TRUSTED BEGIN RETURN[GetLocalPupAddress[soc, [net:fillInNetID,host:,socket:]]] END; NextPupConnectionID: ENTRY PROCEDURE RETURNS [p: PupTypes.Pair] = BEGIN mumble: LONG CARDINAL _ ProcessorFace.GetClockPulses[]; -- Alto Pulses are short p.a _ LOOPHOLE[mumble, Basics.LongNumber].lowbits; p.b _ nextConnectionID _ nextConnectionID + 1; END; GetLocalPupAddress: SAFE PROCEDURE [ local: PupSocketID, remote: PupAddress] RETURNS [me: PupAddress] = TRUSTED BEGIN destNet: PupNetID _ [0]; rte: RoutingTableEntry; network: DriverDefs.Network _ NIL; IF remote.net # PupTypes.fillInNetID AND remote.host # PupTypes.fillInHostID THEN destNet _ remote.net; rte _ GetRoutingTableEntry[destNet]; IF rte # NIL THEN network _ rte.network; IF network = NIL OR network.netNumber.b > 377B THEN network _ DriverDefs.GetDeviceChain[]; me.net _ [network.netNumber.b]; me.host _ [network.hostNumber]; me.socket _ IF local # PupTypes.fillInSocketID THEN local ELSE UniqueLocalPupSocketID[]; END; PupRouterKnowAboutSocket: ENTRY PROCEDURE [so: PupRouterSocket] = BEGIN IF CommFlags.doDebug THEN BeSurePupIsOn[]; Process.InitializeCondition[CommUtilDefs.MaybeShorten[@so.ready], 0]; BufferDefs.QueueInitialize[so.input]; so.next _ firstSocket; firstSocket _ so; END; PupRouterForgetAboutSocket: ENTRY PROCEDURE [so: PupRouterSocket] = BEGIN previous: PupRouterSocket; IF CommFlags.doDebug THEN BeSurePupIsOn[]; IF firstSocket = so THEN firstSocket _ so.next ELSE FOR previous _ firstSocket, previous.next UNTIL previous = NIL DO IF previous.next = so THEN BEGIN previous.next _ so.next; EXIT; END; ENDLOOP; BufferDefs.QueueCleanup[so.input]; END; GetRoutingTable: PROCEDURE RETURNS [RoutingTable] = BEGIN BeSurePupIsOn[]; RETURN[routingTable]; END; GetFirstPupSocket: PROCEDURE RETURNS [PupRouterSocket] = BEGIN BeSurePupIsOn[]; RETURN[firstSocket]; END; GetHopsToNetwork: SAFE PROCEDURE [net: PupTypes.PupNetID] RETURNS [CARDINAL] = TRUSTED BEGIN rte: RoutingTableEntry _ GetRoutingTableEntry[net]; IF rte = NIL OR rte.network = NIL THEN RETURN[LAST[CARDINAL]]; RETURN[rte.hop]; END; FastPath: SAFE PROCEDURE [where: PupTypes.PupAddress] RETURNS [BOOLEAN] = TRUSTED BEGIN rte: RoutingTableEntry _ GetRoutingTableEntry[where.net]; IF rte = NIL OR rte.hop # 0 THEN RETURN[FALSE]; SELECT rte.network.device FROM local, ethernet, ethernetOne => RETURN[TRUE]; ENDCASE => RETURN[FALSE]; END; END.