PupRouterOut.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Levin, August 9, 1983 9:47 am
Russ Atkinson (RRA) February 4, 1985 1:09:28 pm PST
DIRECTORY
Basics USING [LongNumber],
BufferDefs,
CommFlags USING [doDebug, doShow, doStats, doStorms],
DriverDefs USING [GetDeviceChain, Glitch, Network, PutOnGlobalDoneQueue],
DriverTypes USING [bufferSeal],
ProcessorFace USING [GetClockPulses],
PupDefs USING [outgoingPup, zappedOutgoingPup, PupBuffer],
PupRouterDefs USING [routerLock, maxHop, OutThings, RoutingTableEntry, GetRoutingTableEntry, BeSurePupIsOn, SetPupChecksum],
PupTypes USING [allNets, allHosts, PupType, PupAddress, PupHostID, PupNetID],
StatsDefs USING [StatIncr];
PupRouterOut: MONITOR LOCKS PupRouterDefs.routerLock
IMPORTS BufferDefs, ProcessorFace, StatsDefs, PupRouterDefs, DriverDefs
EXPORTS BufferDefs, PupRouterDefs, PupDefs
SHARES BufferDefs, DriverTypes =
BEGIN OPEN StatsDefs, PupRouterDefs, DriverDefs, PupDefs, PupTypes;
EXPORTed TYPEs
Network: PUBLIC TYPE = DriverDefs.Network;
dataWordsPerPup: PUBLIC CARDINAL;
outThings: PUBLIC OutThings ← [outStormy: FALSE, showOut: FALSE, outShower:];
parameters for killing packets
lightning: INTEGER ← 30;
bolt: INTEGER ← 10;
BufferSealBroken: PUBLIC ERROR = CODE;
IllegalPupLength: PUBLIC ERROR = CODE;
PupRouterSendThis: PUBLIC ENTRY PROCEDURE [b: PupBuffer] =
BEGIN
IF b.dest.net = allNets AND b.dest.host = allHosts THEN
BEGIN PupRouterBroadcastThis[b]; RETURN; END;
SendUnlocked[b];
END;
SneakySendUnlocked: PUBLIC PROCEDURE [b: PupBuffer] = JustSendUnlocked;
JustSendUnlocked: INTERNAL PROCEDURE [b: PupBuffer] =
BEGIN SendUnlocked[b]; END;
SendUnlocked: INTERNAL PROCEDURE [b: PupBuffer] =
BEGIN
d: PupAddress ← b.dest;
n: PupNetID ← d.net;
rte: RoutingTableEntry;
network: Network;
h: PupHostID;
IF CommFlags.doStats THEN StatIncr[statPupSent];
IF CommFlags.doDebug THEN BeSurePupIsOn[];
IF CommFlags.doDebug AND b.seal # DriverTypes.bufferSeal THEN Glitch[BufferSealBroken];
IF CommFlags.doStorms AND outThings.outStormy -- for debugging only
AND (lightning ← lightning + 1) > bolt OR lightning < 0 THEN
BEGIN
IF lightning > bolt THEN
BEGIN
IF bolt > 100 THEN
BEGIN
mumble: LONG CARDINAL ← ProcessorFace.GetClockPulses[];
Alto Pulses are short
lightning ← -INTEGER[LOOPHOLE[mumble, Basics.LongNumber].lowbits MOD 20B];
bolt ← 10;
END
ELSE BEGIN lightning ← 0; bolt ← bolt + 1; END;
END;
IF CommFlags.doShow AND outThings.showOut THEN
outThings.outShower[zappedOutgoingPup, b];
PutOnGlobalDoneQueue[b];
IF CommFlags.doStats THEN StatIncr[statZappedP];
RETURN;
END;
Maybe we should do something for the local case?
b.pupTransportControl ← 0;
rte ← GetRoutingTableEntry[n];
IF rte = NIL OR rte.hop > maxHop OR (network ← rte.network) = NIL THEN
BEGIN -- don't know where to send it
IF CommFlags.doStats THEN StatIncr[statPupsSentNowhere];
BEGIN -- Send him an error Pup, but beware of RequeueProc-- END;
PutOnGlobalDoneQueue[b];
RETURN; -- wait to see if there is an alternate path
END;
IF CommFlags.doShow AND outThings.showOut THEN outThings.outShower[outgoingPup, b];
h ← rte.route;
IF h = 0 THEN h ← b.dest.host; -- we are on the same net
IF CommFlags.doDebug AND ((b.pupLength + 1)/2) > dataWordsPerPup + wordsPerPupHeader
THEN DriverDefs.Glitch[IllegalPupLength];
SetPupChecksum[b];
network.encapsulatePup[b, h];
network.sendBuffer[b];
END;
PupRouterBroadcastThis: PUBLIC PROCEDURE [b: PupBuffer] =
BEGIN
network: Network;
IF CommFlags.doStats THEN StatIncr[statPupBroadcast];
IF CommFlags.doDebug THEN BeSurePupIsOn[];
IF CommFlags.doDebug AND b.seal # DriverTypes.bufferSeal THEN Glitch[BufferSealBroken];
b.network ← network ← DriverDefs.GetDeviceChain[];
IF network = NIL THEN {PutOnGlobalDoneQueue[b]; RETURN; };
b.allNets ← TRUE; -- this is where it gets turned on
b.dest.host ← allHosts;
PupBroadcaster[b];
END;
b.network is already set up to the desired network
PupBroadcaster: PUBLIC PROCEDURE [b: PupBuffer] =
BEGIN
network: Network ← b.network;
IF ~network.alive OR (b.bypassZeroNet AND network.netNumber = [0, 0]) THEN
BEGIN PutOnGlobalDoneQueue[b]; RETURN; END;
goes (slowly) around in circles
b.pupTransportControl ← 0;
IF network.netNumber.b > 377B THEN b.dest.net ← b.source.net ← [0]
ELSE b.dest.net ← b.source.net ← [network.netNumber.b];
b.source.host ← [network.hostNumber];
network.encapsulatePup[b, PupTypes.allHosts];
SetPupChecksum[b];
network.sendBuffer[b];
END;
Pup is assumed to have arrived from somewhere else. We fixup defaults here.
SwapPupSourceAndDest: PUBLIC PROCEDURE [b: PupBuffer] =
BEGIN
network: Network ← b.network;
temp: PupAddress;
IF CommFlags.doDebug AND b.seal # DriverTypes.bufferSeal THEN Glitch[BufferSealBroken];
temp ← b.source;
b.source ← b.dest;
b.dest ← temp;
in case we are returning a broadcast packet
IF b.dest.net = 0 AND network.netNumber.b < 400B THEN
b.dest.net ← [network.netNumber.b];
IF b.source.net = 0 AND network.netNumber.b < 400B THEN
b.source.net ← [network.netNumber.b];
IF b.source.host = PupTypes.allHosts THEN
b.source.host ← [network.hostNumber];
END;
ReturnPup: PUBLIC PROCEDURE [
b: PupBuffer, type: PupTypes.PupType, bytes: CARDINAL] =
BEGIN SwapPupSourceAndDest[b]; SendPup[b, type, bytes]; END;
wordsPerPupHeader: CARDINAL = 11;
bytesPerPupHeader: CARDINAL = wordsPerPupHeader*2;
GetPupContentsBytes: PUBLIC PROCEDURE [b: PupBuffer] RETURNS [bytes: CARDINAL] =
BEGIN RETURN[b.pupLength - bytesPerPupHeader]; END;
SetPupContentsBytes: PUBLIC PROCEDURE [b: PupBuffer, bytes: CARDINAL] =
BEGIN
IF bytes > dataWordsPerPup*2 THEN Glitch[IllegalPupLength];
b.pupLength ← bytes + bytesPerPupHeader;
END;
SetPupContentsWords: PUBLIC PROCEDURE [b: PupBuffer, words: CARDINAL] =
BEGIN
IF words > dataWordsPerPup THEN Glitch[IllegalPupLength];
b.pupLength ← words*2 + bytesPerPupHeader;
END;
SendPup: PUBLIC PROCEDURE [b: PupBuffer, type: PupType, bytes: CARDINAL] =
BEGIN
b.pupType ← type;
SetPupContentsBytes[b, bytes];
PupRouterSendThis[b];
END;
Formerly in DummyForwarder, but more properly here...
DontForwardPupBuffer: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] = BEGIN
BufferDefs.ReturnFreeBuffer[b];
IF CommFlags.doStats THEN StatsDefs.StatIncr[statPupNotForwarded];
END;
END.