-- File: PupRouterCool.Mesa, Last Edit: HGM March 19, 1981 6:33 PM
-- This section of code is mostly used when creating/destroying sockets
-- Last Edited by: Levin, August 9, 1983 9:48 am
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.