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.