-- File: PupRouterOut.mesa, Last Edit: HGM October 16, 1979 11:08 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY StatsDefs: FROM "StatsDefs" USING [StatIncr], CommUtilDefs: FROM "CommUtilDefs" USING [GetTicks], PupRouterDefs: FROM "PupRouterDefs" USING [ routerLock, maxHop, OutThings, PupRoutingTableEntry, BeSurePupIsOn, SetPupChecksum], DriverDefs: FROM "DriverDefs" USING [ firstNetwork, doDebug, doShow, doStats, doStorms, Glitch, Network, PutOnGlobalDoneQueue], PupDefs: FROM "PupDefs" USING [ outgoingPup, zappedOutgoingPup, PupBuffer], BufferDefs: FROM "BufferDefs", PupTypes: FROM "PupTypes" USING [ allNets, allHosts, PupType, PupAddress, PupHostID, PupNetID], DriverTypes: FROM "DriverTypes" USING [bufferSeal]; PupRouterOut: MONITOR LOCKS PupRouterDefs.routerLock IMPORTS StatsDefs, CommUtilDefs, PupRouterDefs, DriverDefs EXPORTS PupRouterDefs, PupDefs SHARES BufferDefs, DriverTypes = BEGIN OPEN StatsDefs, PupRouterDefs, DriverDefs, PupDefs, PupTypes; pupRoutingTableOut: PUBLIC DESCRIPTOR FOR ARRAY OF PupRoutingTableEntry; 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; routing: POINTER TO PupRoutingTableEntry; network: Network; h: PupHostID; IF doStats THEN StatIncr[statPupSent]; IF doDebug THEN BeSurePupIsOn[]; IF doDebug AND b.seal#DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; IF 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 lightning_-INTEGER[CommUtilDefs.GetTicks[] MOD 20B]; bolt_10; END ELSE BEGIN lightning_0; bolt_bolt+1; END; END; IF doShow AND outThings.showOut THEN outThings.outShower[zappedOutgoingPup,b]; PutOnGlobalDoneQueue[b]; IF doStats THEN StatIncr[statZappedP]; RETURN; END; -- Maybe we should do something for the local case? b.pupTransportControl _ 0; routing _ @pupRoutingTableOut[n]; network _ routing.network; IF n ~IN [0..LENGTH[pupRoutingTableOut]) OR routing.hop>maxHop OR network=NIL THEN BEGIN -- don't know where to send it IF doStats THEN StatIncr[statPupsSentNowhere]; IF n ~IN [0..LENGTH[pupRoutingTableOut]) OR network=NIL THEN BEGIN -- Send him an error Pup, but beware of RequeueProc-- END; PutOnGlobalDoneQueue[b]; RETURN; -- wait to see if there is an alternate path END; b.source.host _ [network.hostNumber]; -- tell the truth b.source.net _ [network.netNumber]; IF doShow AND outThings.showOut THEN outThings.outShower[outgoingPup,b]; h _ routing.route; IF h=0 THEN h _ b.dest.host; -- we are on the same net IF 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 IF doStats THEN StatIncr[statPupBroadcast]; IF doDebug THEN BeSurePupIsOn[]; IF doDebug AND b.seal#DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; IF DriverDefs.firstNetwork=NIL THEN BEGIN PutOnGlobalDoneQueue[b]; RETURN; END; b.allNets _ TRUE; -- this is where it gets turned on b.network _ DriverDefs.firstNetwork; 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 b.bypassZeroNet AND network.netNumber=0 THEN BEGIN PutOnGlobalDoneQueue[b]; RETURN; END; -- goes (slowly) around in circles b.pupTransportControl _ 0; b.dest.net _ b.source.net _ [network.netNumber]; 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: DriverDefs.Network _ b.network; temp: PupAddress; IF 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 THEN b.dest.net _ [network.netNumber]; IF b.source.net=0 THEN b.source.net _ [network.netNumber]; 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; END. -- PupRouterOut(2048)\738b12B593b17B193b18B54b16B73b12B235t10 13t0 1015b54B554b22B108t10 13t0 368b14B511b21B242i49I36t10 19t0 42t10 19t0 60t10 9t0 4t10 7t0 10b9B232b19B119b19B170b19B170b7B