-- File: RoutingInfoTool.mesa, Last Edit: HGM March 19, 1981 4:45 PM -- Please don't forget to update the herald.... DIRECTORY Storage USING [String, FreeStringNil], String USING [AppendString, AppendNumber], Time USING [AppendCurrent], FormSW USING [ ClientItemsProcType, ProcType, AllocateItemDescriptor, newLine, CommandItem, StringItem], MsgSW USING [Post], Put USING [Char, CR, Text, Line], Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFormSW, MakeFileSW], ToolWindow USING [TransitionProcType], Window USING [Handle], AddressTranslation USING [ AppendMyHostNumber, AppendNetworkAddress, AppendNetworkNumber, AppendSystemElement, StringToNetworkAddress], BufferDefs USING [BufferAccessHandle, OisBuffer], OISCPTypes USING [RoutingInfoTuple], OISCPConstants USING [unknownSocketID, routingInformationSocket], OISCP USING [ OiscpPackageDestroy, OiscpPackageMake, GetFreeSendOisBufferFromPool, ReturnFreeOisBuffer, GetOisPacketTextLength, SetOisPacketTextLength], Router USING [EnumerateRoutingTable, RoutingTableEntry], Socket USING [ Abort, AssignNetworkAddress, Create, Delete, GetPacket, PutPacket, SetWaitTime, TimeOut, TransferStatus], SocketInternal USING [GetBufferPool, SocketHandle], SpecialSystem USING [ HostNumber, GetProcessorID, NetworkAddress, NetworkNumber, ProcessorID], System USING [], DriverDefs USING [Network, GetDeviceChain], PupRouterDefs USING [RoutingTableEntry, EnumerateRoutingTable, PupGateInfo], PupDefs USING [ PupPackageMake, PupPackageDestroy, GetFreePupBuffer, ReturnFreePupBuffer, PupBuffer, PupSocket, PupSocketDestroy, PupSocketMake, SecondsToTocks, SetPupContentsBytes, GetPupContentsBytes, AppendPupAddress, AppendErrorPup, GetPupAddress, PupNameTrouble], PupTypes USING [PupAddress, fillInSocketID, gatewaySoc, allHosts]; RoutingInfoTool: PROGRAM IMPORTS Storage, String, Time, FormSW, MsgSW, Put, Tool, AddressTranslation, OISCP, Router, Socket, SocketInternal, SpecialSystem, DriverDefs, PupRouterDefs, PupDefs EXPORTS Socket, System SHARES BufferDefs = BEGIN OPEN PupDefs, PupTypes; msg, form, log: Window.Handle ← NIL; me, pupTarget, oisTarget: STRING ← NIL; Init: PROCEDURE = BEGIN [] ← Tool.Create[ name: "Routing Info of March 19, 1981"L, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; DeviceChain: FormSW.ProcType = BEGIN network: DriverDefs.Network; WriteCR[]; WriteCurrentDateAndTime[]; WriteLine[" Device Chain:"L]; WriteLine[" ix net hst speed bfr dn type"L]; FOR network ← DriverDefs.GetDeviceChain[], network.next UNTIL network = NIL DO O4[network.index]; O4[network.netNumber.b]; O4[network.hostNumber]; D6[network.speed]; D4[network.buffers]; WriteString[IF network.alive THEN " "L ELSE " *"L]; WriteString[" "L]; SELECT network.device FROM ethernetOne => WriteLine["Ethernet - 3mb"L]; ethernet => WriteLine["Ethernet - 10mb"L]; sla => WriteLine["SLA"L]; packetradio => WriteLine["Packet Radio"L]; phonenet => WriteLine["Phone Net"L]; ENDCASE => WriteLine["???"L]; ENDLOOP; END; LocalPup: FormSW.ProcType = BEGIN PrintOne: PROCEDURE [rte: PupRouterDefs.RoutingTableEntry] = BEGIN network: DriverDefs.Network ← rte.network; IF network = NIL THEN RETURN; nets ← nets + 1; IF k = 0 THEN WriteChar['|]; O4[rte.net]; O4[network.netNumber.b]; WriteChar['#]; IF rte.hop # 0 THEN O3Z[rte.route] ELSE O3Z[network.hostNumber]; WriteChar['#]; O4[rte.hop]; WriteString[" |"L]; IF (k ← k + 1) = 3 THEN BEGIN WriteCR[]; k ← 0; END; END; k, nets: CARDINAL ← 0; WriteCR[]; WriteCurrentDateAndTime[]; WriteLine[" Local Pup Routing Table."L]; WriteLine["| Net Via Hops | Net Via Hops | Net Via Hops |"L]; WriteLine["|-------------------|-------------------|-------------------|"L]; PupRouterDefs.EnumerateRoutingTable[PrintOne]; IF k # 0 THEN WriteCR[]; IF nets > 1 THEN BEGIN WriteString["There are "L]; WriteDecimal[nets - 1]; WriteLine[" active networks."L]; END; END; RemotePup: FormSW.ProcType = BEGIN where: PupAddress; FindPath: PROCEDURE RETURNS [BOOLEAN] = BEGIN WriteString[pupTarget]; WriteChar['=]; where ← [[0], [0], PupTypes.gatewaySoc]; GetPupAddress[ @where, pupTarget ! PupNameTrouble => BEGIN MsgSW.Post[msg, e]; WriteLine[e]; GOTO Trouble; END]; PrintPupAddress[where]; WriteLine["."L]; RETURN[TRUE]; EXITS Trouble => RETURN[FALSE]; END; soc: PupSocket; b: PupBuffer; nets: CARDINAL ← 0; WriteCR[]; WriteCurrentDateAndTime[]; WriteString[" Routing Table from "L]; IF ~FindPath[] THEN RETURN; soc ← PupSocketMake[PupTypes.fillInSocketID, where, SecondsToTocks[2]]; THROUGH [0..10) UNTIL nets # 0 DO b ← GetFreePupBuffer[]; b.pupType ← gatewayRequest; SetPupContentsBytes[b, 0]; b.pupID ← [0, 0]; soc.put[b]; UNTIL (b ← soc.get[]) = NIL DO -- 2 sec wait IF where # b.source THEN BEGIN WriteString["Reply from: "L]; PrintPupAddress[b.source]; WriteLine["."L]; END; SELECT b.pupType FROM gatewayInfo => BEGIN length: CARDINAL = GetPupContentsBytes[b]; info: LONG POINTER TO PupRouterDefs.PupGateInfo ← LOOPHOLE[@b.pupWords]; k, n: CARDINAL; n ← length/(2*SIZE[PupRouterDefs.PupGateInfo]); IF (length MOD (2*SIZE[PupRouterDefs.PupGateInfo])) # 0 THEN WriteLine["***** Funny Length *****"L]; WriteLine[ "| Net Via Hops | Net Via Hops | Net Via Hops |"L]; WriteLine[ "|-------------------|-------------------|-------------------|"L]; k ← 0; FOR i: CARDINAL IN [0..n) DO nets ← nets + 1; IF k = 0 THEN WriteChar['|]; O4[info.net]; O4[info.viaNet]; WriteChar['#]; O3Z[info.viaHost]; WriteChar['#]; O4[info.hop]; WriteString[" |"L]; IF (k ← k + 1) = 3 THEN BEGIN WriteCR[]; k ← 0; END; info ← info + SIZE[PupRouterDefs.PupGateInfo]; ENDLOOP; IF k # 0 THEN WriteCR[]; END; ENDCASE => PrintErrorPup[b]; ReturnFreePupBuffer[b]; ENDLOOP; IF nets = 0 THEN MsgSW.Post[msg, "No Response that try."L]; ENDLOOP; IF where.host # PupTypes.allHosts THEN BEGIN WriteString["There are "L]; WriteDecimal[nets]; WriteLine[" active networks."L]; END; PupSocketDestroy[soc]; END; LocalOis: FormSW.ProcType = BEGIN PrintOne: PROCEDURE [rte: Router.RoutingTableEntry] = BEGIN network: DriverDefs.Network ← rte.network; IF network = NIL THEN duds ← duds + 1 ELSE nets ← nets + 1; WriteNetNumber[rte.destNetwork]; WriteChar[' ]; IF rte.delay # 1 THEN WriteNetAndHost[network.netNumber, rte.route] ELSE WriteNetAndHost[network.netNumber, me]; O4[rte.delay]; O4[rte.timeUnits]; IF rte.network=NIL THEN WriteChar['~] ELSE WriteChar[' ]; WriteCR[]; END; nets, duds: CARDINAL ← 0; me: SpecialSystem.ProcessorID = SpecialSystem.GetProcessorID[]; WriteCR[]; WriteCurrentDateAndTime[]; WriteLine[" Local OISCP Routing Table."L]; WriteLine[" Net Via Dly Tim"L]; Router.EnumerateRoutingTable[PrintOne]; IF nets > 1 THEN BEGIN WriteString["There are "L]; WriteDecimal[nets - 1]; WriteLine[" active networks."L]; END; IF duds > 0 THEN BEGIN WriteString["There are "L]; WriteDecimal[duds]; WriteLine[" dead slots."L]; END; END; -- EXPORTED TYPE(S) NetworkAddress: PUBLIC TYPE = SpecialSystem.NetworkAddress; ChannelHandle: PUBLIC TYPE = SocketInternal.SocketHandle; RemoteOis: FormSW.ProcType = BEGIN nets: CARDINAL ← 0; PrintOne: PROCEDURE [rte: LONG POINTER TO OISCPTypes.RoutingInfoTuple] = BEGIN nets ← nets + 1; WriteNetNumber[rte.objectNetID]; O4[rte.interrouterDelay]; WriteCR[]; END; remoteAddr, localAddr: SpecialSystem.NetworkAddress; cH: ChannelHandle; myBufferAccessHandle: BufferDefs.BufferAccessHandle; b: BufferDefs.OisBuffer; status: Socket.TransferStatus; errFlag, hit: BOOLEAN ← FALSE; WriteCR[]; WriteCurrentDateAndTime[]; WriteLine[" Remote OIS Routing Table."L]; MsgSW.Post[msg, ""L]; remoteAddr ← AddressTranslation.StringToNetworkAddress[oisTarget ! ANY => BEGIN MsgSW.Post[msg, "RemoteAddress is incorrectly specified; try again."L]; errFlag ← TRUE; CONTINUE; END]; IF errFlag THEN RETURN; IF remoteAddr.socket=OISCPConstants.unknownSocketID THEN remoteAddr.socket ← OISCPConstants.routingInformationSocket; localAddr ← Socket.AssignNetworkAddress[]; cH ← Socket.Create[localAddr]; myBufferAccessHandle ← SocketInternal.GetBufferPool[cH]; Socket.SetWaitTime[cH, 1500]; -- milli-seconds FOR i: CARDINAL IN [0..10) UNTIL hit DO b ← OISCP.GetFreeSendOisBufferFromPool[myBufferAccessHandle]; OISCP.SetOisPacketTextLength[b, 2*1]; b.ois.transCntlAndPktTp.packetType ← routingInformation; b.ois.destination ← remoteAddr; b.ois.routingType ← routingInfoRequest; Socket.PutPacket[cH, b]; DO b ← Socket.GetPacket[ cH ! Socket.TimeOut => EXIT]; status ← LOOPHOLE[b.status]; SELECT TRUE FROM (status # goodCompletion) => BEGIN -- some kind of error occurred --PrintSocketEchoError[b, status]; Put.Char[log, 'e]; END; (b.ois.routingType # routingInfoResponse) => BEGIN Put.Char[log, '#]; END; ENDCASE => BEGIN -- the response we were looking for length, entrys: CARDINAL; length ← OISCP.GetOisPacketTextLength[b]; entrys ← length/(2*SIZE[OISCPTypes.RoutingInfoTuple]); IF remoteAddr#b.ois.source THEN BEGIN temp: STRING = [50]; Put.Text[log, "Response from: "L]; AddressTranslation.AppendNetworkAddress[temp, b.ois.source]; Put.Line[log, temp]; END; IF ~hit THEN Put.Line[log," Net Dly"L]; hit ← TRUE; FOR n: CARDINAL IN [0..entrys) DO PrintOne[@b.ois.routingTuple[n]]; ENDLOOP; END; OISCP.ReturnFreeOisBuffer[b]; ENDLOOP; IF nets = 0 THEN MsgSW.Post[msg, "No Response that try."L]; ENDLOOP; Put.CR[log]; Socket.Abort[cH]; Socket.Delete[cH]; MsgSW.Post[msg, ""L]; END; -- IO things WriteNetNumber: PROCEDURE [net: SpecialSystem.NetworkNumber] = BEGIN temp: STRING = [50]; AddressTranslation.AppendNetworkNumber[temp, net]; temp.length ← temp.length - 1; -- flush # THROUGH [temp.length..5) DO WriteChar[' ]; ENDLOOP; WriteString[temp]; END; WriteNetAndHost: PROCEDURE [ net: SpecialSystem.NetworkNumber, host: SpecialSystem.HostNumber] = BEGIN temp: STRING = [50]; AddressTranslation.AppendSystemElement[ temp, SpecialSystem.NetworkAddress[net,host,[0]]]; THROUGH [temp.length..25) DO WriteChar[' ]; ENDLOOP; WriteString[temp]; END; WriteChar: PROCEDURE [c: CHARACTER] = BEGIN Put.Char[log, c]; END; WriteCR: PROCEDURE = BEGIN Put.CR[log]; END; WriteString: PROCEDURE [s: STRING] = BEGIN Put.Text[log, s]; END; WriteLine: PROCEDURE [s: STRING] = BEGIN Put.Line[log, s]; END; WriteDecimal: PROCEDURE [n: CARDINAL] = INLINE BEGIN WriteNumber[n, 10, 0]; END; O, WriteOctal: PROCEDURE [n: CARDINAL] = INLINE BEGIN WriteNumber[n, 8, 0]; END; WriteNumber: PROCEDURE [n, radix, width: CARDINAL] = INLINE BEGIN temp: STRING = [25]; String.AppendNumber[temp, n, radix]; THROUGH [temp.length..width) DO WriteChar[' ]; ENDLOOP; WriteString[temp]; END; O3Z: PROCEDURE [n: CARDINAL] = BEGIN temp: STRING = [25]; String.AppendNumber[temp, n, 8]; THROUGH [temp.length..3) DO WriteChar['0]; ENDLOOP; WriteString[temp]; END; O4: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 8, 4]; END; D4: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 10, 4]; END; D6: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 10, 6]; END; WriteCurrentDateAndTime: PROCEDURE = BEGIN time: STRING = [20]; Time.AppendCurrent[time]; WriteString[time]; END; PrintPupAddress: PROCEDURE [a: PupAddress] = BEGIN temp: STRING = [40]; AppendPupAddress[temp, a]; WriteString[temp]; END; PrintErrorPup: PUBLIC PROCEDURE [b: PupDefs.PupBuffer] = BEGIN text: STRING = [100]; AppendErrorPup[text, b]; MsgSW.Post[msg, text]; END; MakeSWs: Tool.MakeSWsProc = BEGIN msg ← Tool.MakeMsgSW[window: window, lines: 5]; form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; log ← Tool.MakeFileSW[window: window, name: "RoutingInfo.log$"L]; END; MakeForm: FormSW.ClientItemsProcType = BEGIN nParams: CARDINAL = 8; items ← FormSW.AllocateItemDescriptor[nParams]; items[0] ← FormSW.CommandItem[ tag: "LocalPup"L, proc: LocalPup, place: FormSW.newLine]; items[1] ← FormSW.CommandItem[tag: "RemotePup"L, proc: RemotePup]; items[2] ← FormSW.StringItem[tag: "PupTarget"L, string: @pupTarget]; items[3] ← FormSW.CommandItem[ tag: "LocalOis"L, proc: LocalOis, place: FormSW.newLine]; items[4] ← FormSW.CommandItem[tag: "RemoteOis"L, proc: RemoteOis]; items[5] ← FormSW.StringItem[tag: "OisTarget"L, string: @oisTarget]; items[6] ← FormSW.CommandItem[ tag: "DeviceChain"L, proc: DeviceChain, place: FormSW.newLine]; items[7] ← FormSW.StringItem[tag: "MyProcessorID"L, string: @me]; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => BEGIN pupTarget ← Storage.String[40]; String.AppendString[pupTarget, "ME"L]; oisTarget ← Storage.String[40]; String.AppendString[oisTarget, "0#*#1"L]; me ← Storage.String[40]; AddressTranslation.AppendMyHostNumber[me]; me.length ← me.length - 1; -- flush stupid # PupDefs.PupPackageMake[]; OISCP.OiscpPackageMake[]; END; new = inactive => BEGIN OISCP.OiscpPackageDestroy[]; PupDefs.PupPackageDestroy[]; pupTarget ← Storage.FreeStringNil[pupTarget]; oisTarget ← Storage.FreeStringNil[oisTarget]; me ← Storage.FreeStringNil[me]; END; ENDCASE; END; Init[]; END.