-- Copyright (C) 1981, 1984, 1985 by Xerox Corporation. All rights reserved. -- OthelloPup.mesa, HGM, 10-Mar-85 5:51:08 -- File: OthelloPup.mesa, Last Edit: HGM May 22, 1979 10:35 PM -- File: OthelloPup.mesa, Last Edit: Fay/BLyon August 21, 1980 3:42 PM -- File: OthelloPup.mesa, Last Edit: BLyon August 29, 1980 9:21 AM -- File: OthelloPup.mesa, Last Edit: ?? 25-Nov-81 13:22:47 -- File: OthelloPup.mesa, Last Edit: Fay 17-Dec-81 14:22:18 DIRECTORY Process USING [Detach, Pause, Yield], Buffer USING [GetBuffer, ReturnBuffer], Driver USING [Network], OthelloDefs, PupDefs USING [ AppendPupAddress, DataWordsPerPupBuffer, GetPupAddress, GetPupContentsBytes, PupBuffer, PupNameTrouble, PupPackageDestroy, PupPackageMake, PupSocket, PupSocketDestroy, PupSocketMake, SecondsToTocks, SetPupContentsBytes, veryShortWait], PupRouterDefs USING [GetRoutingTable, RoutingTableEntry, RoutingTableObject], PupPktOps USING [pupBuffers], PupTypes USING [echoSoc, fillInSocketID, maxDataWordsPerGatewayPup, PupAddress]; OthelloPup: PROGRAM IMPORTS Process,Buffer, PupDefs, PupRouterDefs, PupPktOps, OthelloDefs = BEGIN OPEN OthelloDefs; PrintErrorPup: PROCEDURE [b: PupDefs.PupBuffer] = BEGIN source: PupTypes.PupAddress ¬ b.pup.source; NewLine[]; IF b.pup.pupType = error THEN BEGIN len: CARDINAL = PupDefs.GetPupContentsBytes[b]; WriteString["[Error Pup, code="L]; WriteOctal[LOOPHOLE[b.pup.errorCode]]; WriteString[", from: "L]; PrintPupAddress[@source]; WriteString["] "L]; FOR i: CARDINAL IN [0..len - 2*(10 + 1 + 1)) DO WriteChar[b.pup.errorText[i]] ENDLOOP; END ELSE BEGIN WriteString[" ***** "L]; WriteString["Funny PupType = "L]; WriteOctal[LOOPHOLE[b.pup.pupType]]; WriteString[" ***** "L]; END; NewLine[]; END; EchoUser: PROCEDURE = BEGIN OPEN PupDefs, PupTypes; bytesPerBuffer: CARDINAL; funny, late: LONG CARDINAL ¬ 0; recv, sent: LONG CARDINAL ¬ 0; wrong: LONG CARDINAL ¬ 0; me, where: PupAddress ¬ [, , echoSoc]; mySoc: PupSocket; packetNumber: CARDINAL ¬ 0; routing: PupRouterDefs.RoutingTableEntry; pleaseStop: BOOLEAN ¬ FALSE; Watch: PROCEDURE = BEGIN [] ¬ ReadChar[ ! ABORTED => CONTINUE]; pleaseStop ¬ TRUE; END; GetName["Echo to: "L, @echoName]; GetPupAddress[ @where, echoName ! PupNameTrouble => AbortingCommand[e]]; routing ¬ @PupRouterDefs.GetRoutingTable[][where.net]; IF routing=NIL OR routing.network = NIL THEN AbortingCommand["Can't reach that network"L]; mySoc ¬ PupSocketMake[fillInSocketID, where, SecondsToTocks[5]]; me ¬ mySoc.getLocalAddress[]; PrintPupAddress[@me]; WriteString[" => "L]; IF routing.hop # 0 THEN { WriteOctal[routing.network.pupNetNumber]; WriteChar['#]; WriteOctal[routing.route]; WriteChar['#]; WriteString[" => "L]}; PrintPupAddress[@where]; NewLine[]; Process.Detach[FORK Watch[]]; bytesPerBuffer ¬ 2*MIN[DataWordsPerPupBuffer[], maxDataWordsPerGatewayPup]; UNTIL pleaseStop DO FOR len: CARDINAL IN [0..bytesPerBuffer] UNTIL pleaseStop DO b: PupBuffer; b ¬ Buffer.GetBuffer[pup, PupPktOps.pupBuffers, send, fullBuffer]; b.pup.pupID.a ¬ b.pup.pupID.b ¬ (packetNumber ¬ packetNumber + 1); b.pup.pupType ¬ echoMe; SetPupContentsBytes[b, len]; FOR i: CARDINAL IN [0..len) DO b.pup.pupBytes[i] ¬ i ENDLOOP; mySoc.put[b]; sent ¬ sent + 1; Process.Yield[]; -- be sure we don't hog machine UNTIL (b ¬ mySoc.get[]) = NIL DO SELECT TRUE FROM (b.pup.pupType # iAmEcho) => {funny ¬ funny + 1; PrintErrorPup[b]}; ((b.pup.pupID.a # packetNumber) OR (b.pup.pupID.b # packetNumber) OR (len # GetPupContentsBytes[b])) => { WriteChar['#]; late ¬ late + 1}; ENDCASE => { FOR i: CARDINAL IN [0..len) DO IF b.pup.pupBytes[i] # (i MOD 400B) THEN { wrong ¬ wrong + 1; WriteChar['~]; GOTO Wrong}; ENDLOOP; WriteChar['!]; recv ¬ recv + 1; EXIT}; Buffer.ReturnBuffer[b]; REPEAT Wrong => NULL; ENDLOOP; IF b # NIL THEN Buffer.ReturnBuffer[b] ELSE WriteChar['?]; ENDLOOP; NewLine[]; ENDLOOP; PupSocketDestroy[mySoc]; WriteLine["."L]; WriteString["Out: "L]; WriteLongNumber[sent]; WriteString[", In: "L]; WriteLongNumber[recv]; WriteString[" ("L]; WriteLongNumber[(recv*100)/sent]; WriteLine["%)"L]; IF late # 0 THEN BEGIN WriteString["Late: "L]; WriteLongNumber[late]; WriteString[" ("L]; WriteLongNumber[(late*100)/sent]; WriteLine["%)"L]; END; IF funny # 0 THEN BEGIN WriteLongNumber[funny]; WriteLine[" funny"L]; END; IF wrong # 0 THEN BEGIN WriteLongNumber[wrong]; WriteLine[" wrong data"L]; END; END; PupSender: PROCEDURE = BEGIN OPEN PupDefs, PupTypes; bytesPerBuffer: CARDINAL; me, where: PupAddress ¬ [, , echoSoc]; mySoc: PupSocket; sent, echo, full, other: LONG CARDINAL ¬ 0; routing: PupRouterDefs.RoutingTableEntry; pleaseStop: BOOLEAN ¬ FALSE; Watch: PROCEDURE = BEGIN [] ¬ ReadChar[ ! ABORTED => CONTINUE]; pleaseStop ¬ TRUE; END; GetName["Send to: "L, @echoName]; GetPupAddress[ @where, echoName ! PupNameTrouble => AbortingCommand[e]]; routing ¬ @PupRouterDefs.GetRoutingTable[][where.net]; IF routing=NIL OR routing.network = NIL THEN AbortingCommand["Can't reach that network"L]; mySoc ¬ PupSocketMake[fillInSocketID, where, PupDefs.veryShortWait]; me ¬ mySoc.getLocalAddress[]; PrintPupAddress[@me]; WriteString[" => "L]; IF routing.hop # 0 THEN BEGIN WriteOctal[routing.network.pupNetNumber]; WriteChar['#]; WriteOctal[routing.route]; WriteChar['#]; WriteString[" => "L]; END; PrintPupAddress[@where]; NewLine[]; Process.Detach[FORK Watch[]]; bytesPerBuffer ¬ 100; UNTIL pleaseStop DO b: PupBuffer; FOR i: CARDINAL IN [0..3) DO b ¬ Buffer.GetBuffer[pup, PupPktOps.pupBuffers, send, fullBuffer]; b.pup.pupID.a ¬ b.pup.pupID.b ¬ i; b.pup.pupType ¬ echoMe; FOR i: CARDINAL IN [0..bytesPerBuffer) DO b.pup.pupBytes[i] ¬ i; ENDLOOP; SetPupContentsBytes[b, bytesPerBuffer]; mySoc.put[b]; sent ¬ sent + 1; IF (sent MOD 100) = 0 THEN BEGIN WriteChar['s]; Process.Pause[1]; END; ENDLOOP; UNTIL (b ¬ mySoc.get[]) = NIL DO IF b.pup.pupType = iAmEcho THEN BEGIN echo ¬ echo + 1; IF (echo MOD 100) = 0 THEN WriteChar['r]; END ELSE BEGIN IF b.pup.pupType = error AND b.pup.errorCode # resourceLimitsPupErrorCode THEN BEGIN other ¬ other + 1; PrintErrorPup[b]; END ELSE full ¬ full + 1; END; Buffer.ReturnBuffer[b]; b ¬ NIL; ENDLOOP; Process.Yield[]; -- be sure we don't hog machine ENDLOOP; NewLine[]; WriteString["Sent: "L]; WriteLongNumber[sent]; WriteString[", Echoed: "L]; WriteLongNumber[echo]; IF full # 0 THEN BEGIN WriteString[", BufferFull: "L]; WriteLongNumber[full]; END; IF other # 0 THEN BEGIN WriteString[", Other: "L]; WriteLongNumber[other]; END; WriteLine["."L]; PupSocketDestroy[mySoc]; END; PrintLocalPupRoutingTable: PROCEDURE = BEGIN pupRt: LONG DESCRIPTOR FOR ARRAY OF PupRouterDefs.RoutingTableObject; k: CARDINAL ¬ 0; WriteLine["| Net Via Hops | Net Via Hops | Net Via Hops | Net Via Hops |"L]; WriteLine["|-----------------|-----------------|-----------------|-----------------|"L]; pupRt ¬ PupRouterDefs.GetRoutingTable[]; FOR i: CARDINAL IN [0..LENGTH[pupRt]) DO D3: PROC [n: CARDINAL] = INLINE {WriteFixedWidthNumber[n, 3, 10]}; O4: PROC [n: CARDINAL] = INLINE {WriteFixedWidthNumber[n, 4, 8]}; O3Z: PROC [n: CARDINAL] = { n ¬ n MOD 1000B; THROUGH [0..3) DO WriteChar['0 + (n/100B) MOD 10B]; n ¬ n*10B ENDLOOP}; r: PupRouterDefs.RoutingTableEntry = @pupRt[i]; network: Driver.Network = r.network; OthelloDefs.CheckUserAbort[! ABORTED => EXIT]; IF network = NIL THEN LOOP; IF k = 0 THEN WriteChar['|]; O4[i]; O4[network.pupNetNumber]; WriteChar['#]; O3Z[IF r.hop # 0 THEN r.route ELSE network.pupHostNumber]; WriteChar['#]; D3[r.hop]; WriteString[" |"L]; IF (k ¬ k + 1) = 4 THEN BEGIN NewLine[]; k ¬ 0; Process.Yield[]; END; ENDLOOP; IF k # 0 THEN NewLine[]; END; PrintPupAddress: PROC [a: POINTER TO PupTypes.PupAddress] = { buffer: STRING ¬ [50]; PupDefs.AppendPupAddress[buffer, a­]; WriteString[buffer]}; echoName: LONG STRING ¬ NIL; Commands: PROC [index: CARDINAL] = BEGIN SELECT index FROM 0 => { MyNameIs[myNameIs: "Pup Echo User"L, myHelpIs: "Pup echo user"L]; PupDefs.PupPackageMake[]; EchoUser[! UNWIND => PupDefs.PupPackageDestroy[]]}; 1 => { MyNameIs[myNameIs: "Pup Sender"L, myHelpIs: "Send Pups rapidly"L]; PupDefs.PupPackageMake[]; PupSender[! UNWIND => PupDefs.PupPackageDestroy[]]}; 2 => { MyNameIs[ myNameIs: "Pup Routing Tables"L, myHelpIs: "Show pup network routing tables"L]; PupDefs.PupPackageMake[]; PrintLocalPupRoutingTable[! UNWIND => PupDefs.PupPackageDestroy[]]}; ENDCASE => IndexTooLarge; PupDefs.PupPackageDestroy[]; END; commandProcessor: CommandProcessor ¬ [Commands]; RegisterCommandProc[@commandProcessor]; END.....