-- File: PupRouterCool.Mesa, Last Edit: HGM March 19, 1981 6:33 PM -- This section of code is mostly used when creating/destroying sockets DIRECTORY Inline USING [LowHalf], Process USING [InitializeCondition], System 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 Inline, Process, System, CommUtilDefs, DriverDefs, PupRouterDefs, BufferDefs EXPORTS PupDefs, PupRouterDefs =PUBLIC BEGIN OPEN PupTypes, PupRouterDefs; spareSocket: CARDINAL ← 1000B; nextConnectionID: CARDINAL ← 1000; UniqueLocalPupSocketID: ENTRY PROCEDURE RETURNS [socket: PupSocketID] = BEGIN mumble: LONG CARDINAL ← System.GetClockPulses[]; -- Alto Pulses are short IF (spareSocket ← spareSocket + 1) = 0 THEN spareSocket ← 1000B; socket ← [Inline.LowHalf[mumble], spareSocket]; END; UniqueLocalPupAddress: PROCEDURE [him: POINTER TO PupAddress] RETURNS [me: PupAddress] = BEGIN RETURN[GetLocalPupAddress[PupTypes.fillInSocketID, him]]; END; NextPupConnectionID: ENTRY PROCEDURE RETURNS [p: PupTypes.Pair] = BEGIN mumble: LONG CARDINAL ← System.GetClockPulses[]; -- Alto Pulses are short p.a ← Inline.LowHalf[mumble]; p.b ← nextConnectionID ← nextConnectionID + 1; END; GetLocalPupAddress: PROCEDURE [ local: PupSocketID, remote: POINTER TO PupAddress] RETURNS [me: PupAddress] = BEGIN destNet: PupNetID ← [0]; rte: RoutingTableEntry; network: DriverDefs.Network ← NIL; IF remote # NIL THEN BEGIN OPEN PupTypes; IF remote.net # fillInNetID AND remote.host # fillInHostID THEN destNet ← remote.net; END; 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[]; IF remote # NIL THEN BEGIN OPEN PupTypes; IF remote.net = fillInNetID THEN remote.net ← IF network # NIL THEN [network.netNumber.b] ELSE me.net; IF remote.host = fillInHostID THEN remote.host ← IF network # NIL THEN [network.hostNumber] ELSE me.host; IF remote.socket = fillInSocketID THEN remote.socket ← me.socket; END; 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: PROCEDURE [net: PupTypes.PupNetID] RETURNS [CARDINAL] = BEGIN rte: RoutingTableEntry ← GetRoutingTableEntry[net]; IF rte = NIL OR rte.network = NIL THEN RETURN[LAST[CARDINAL]]; RETURN[rte.hop]; END; FastPath: PROCEDURE [where: PupTypes.PupAddress] RETURNS [BOOLEAN] = 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.