-- File: LoopBackPlug.mesa, Last Edit: -- MAS April 17, 1980 10:55 PM -- HGM October 15, 1979 10:26 PM -- This module is needed/used only in the funny localOnly mode. -- Copyright Xerox Corporation 1979, 1980 DIRECTORY InlineDefs: FROM "InlineDefs" USING [COPY], CommUtilDefs: FROM "CommUtilDefs" USING [GetEthernetHostNumber], StatsDefs: FROM "StatsDefs" USING [StatBump, StatIncr], DriverDefs: FROM "DriverDefs" USING [ doStats, Glitch, useCount, firstNetwork, CreateDefaultEthernetDriver, GetInputBuffer, AddDeviceToChain, Network, NetworkObject, PutOnGlobalDoneQueue, PutOnGlobalInputQueue], PupDefs: FROM "PupDefs" USING [GetDoStats], BufferDefs: FROM "BufferDefs", DriverTypes: FROM "DriverTypes" USING [pupLocalPacket], PupTypes: FROM "PupTypes" USING [PupErrorCode, noErrorPupErrorCode]; LoopBackPlug: MONITOR IMPORTS InlineDefs, CommUtilDefs, StatsDefs, DriverDefs, PupDefs EXPORTS DriverDefs, PupDefs SHARES BufferDefs, DriverTypes = BEGIN OPEN StatsDefs, BufferDefs, DriverDefs; localEncapsulationOffset: CARDINAL = 4; localEncapsulationBytes: CARDINAL = 4; myNetwork: DriverDefs.NetworkObject _ [ decapsulateBuffer: DecapsulateBuffer, encapsulatePup: EncapsulatePup, encapsulateRpp: EncapsulateRpp, sendBuffer: SendBuffer, forwardBuffer: ForwardBuffer, activateDriver: ActivateDriver, deactivateDriver: DeactivateDriver, deleteDriver: DeleteDriver, interrupt: DeactivateDriver, -- No interrupt routine device: local, alive: TRUE, speed: 3000, index: , netNumber: 0, hostNumber: , next: NIL, pupStats: PupStats, stats: NIL ]; CommPackageAlreadyActive: PUBLIC ERROR = CODE; MachineIDTooBigForEthernet: PUBLIC ERROR = CODE; SetLocalOnly: PUBLIC PROCEDURE [localOnly: BOOLEAN] = BEGIN -- NB: This won't work in the multi network case. IF DriverDefs.useCount#0 THEN DriverDefs.Glitch[CommPackageAlreadyActive]; DriverDefs.firstNetwork _ NIL; IF localOnly THEN [] _ CreateLoopBackNetwork[] ELSE [] _ DriverDefs.CreateDefaultEthernetDriver[]; END; DecapsulateBuffer: PROCEDURE [b: Buffer] RETURNS [BufferDefs.BufferType] = BEGIN SELECT b.encapsulation.localType FROM DriverTypes.pupLocalPacket => RETURN[pup]; ENDCASE => RETURN[rejected]; END; EncapsulateRpp: PROCEDURE [RppBuffer, PupHostID] = LOOPHOLE[EncapsulatePup]; EncapsulatePup: PROCEDURE [b: PupBuffer, destination: PupHostID] = BEGIN b.encapsulation _ [ local [ localSpare1:, localSpare2:, localSpare3:, localSpare4:, localHost: b.dest.host, localType: DriverTypes.pupLocalPacket ] ]; b.length _ (b.pupLength+1+localEncapsulationBytes)/2; END; ForwardBuffer: PROCEDURE [b: Buffer] RETURNS [PupTypes.PupErrorCode] = BEGIN SendBuffer[b]; RETURN[PupTypes.noErrorPupErrorCode]; END; SendBuffer: ENTRY PROCEDURE [b: Buffer] = BEGIN copy: Buffer; b.device _ local; IF b.encapsulation.localHost=myNetwork.hostNumber THEN BEGIN -- sending to ourself, copy it over copy _ GetInputBuffer[]; IF copy#NIL THEN BEGIN copy.device _ local; InlineDefs.COPY[ from: @b.encapsulation+localEncapsulationOffset, nwords: b.length, to: @copy.encapsulation+localEncapsulationOffset ]; copy.length _ b.length; copy.network _ @myNetwork; IF doStats THEN StatIncr[statEtherPacketsLocal]; IF doStats THEN StatBump[statEtherWordsLocal,b.length]; END ELSE IF doStats THEN StatIncr[statEtherEmptyFreeQueue]; PutOnGlobalDoneQueue[b]; -- give this one back first IF copy#NIL THEN PutOnGlobalInputQueue[copy]; RETURN END; PutOnGlobalDoneQueue[b]; -- just throw it away END; CreateLoopBackNetwork: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN AddDeviceToChain[@myNetwork,0]; RETURN[TRUE]; END; DeleteDriver: PROCEDURE = BEGIN END; ActivateDriver: PROCEDURE = BEGIN myNetwork.hostNumber _ CommUtilDefs.GetEthernetHostNumber[]; END; DeactivateDriver: PROCEDURE = BEGIN END; PupStats: PROCEDURE [PupBuffer, Network] RETURNS [BOOLEAN] = BEGIN RETURN[FALSE]; END; -- initialization [] _ PupDefs.GetDoStats[]; -- Get main PupPackage started END. -- LoopBackPlug module(2048)\1682b12B323b17B194b14B63b14B290b13B131b10B871b21B105b12B30b14B93b16B30b8B