DIRECTORY CommDriver USING [Buffer, Network], Endian USING [HWORD], Process USING [Detach, Pause, priorityNormal, SecondsToTicks, SetPriority, Ticks], Pup USING [allHosts, allNets, Host], PupBuffer USING [Buffer, noChecksum, RoundUpForChecksum, WordsWithoutChecksum], PupHop USING [maxHop], PupInternal USING [CaptureForwarding, ProcessGatewayInfo, ProcessGatewayRequest, Route], PupSocket USING [CreateServer, FreeBuffer, Get, SetRemoteAddress, Socket, waitForever], PupSocketBackdoor USING [ReturnErrorNoFree], PupWKS USING [gatewayInfo]; PupForwarderImpl: CEDAR MONITOR IMPORTS Process, PupBuffer, PupInternal, PupSocket, PupSocketBackdoor = { BYTE: TYPE = [0..100H); Buffer: TYPE = PupBuffer.Buffer; Network: TYPE = CommDriver.Network; TempDriverBuffer: PROC [b: Buffer] RETURNS [CommDriver.Buffer] = TRUSTED INLINE { RETURN[LOOPHOLE[b]]; }; socket: PupSocket.Socket; -- Overlays the one in PupRouterImpl RoutingSlurper: PROC = { socket _ PupSocket.CreateServer[ local: PupWKS.gatewayInfo, getTimeout: PupSocket.waitForever ]; PupSocket.SetRemoteAddress[socket, [Pup.allNets, Pup.allHosts, PupWKS.gatewayInfo]]; Process.SetPriority[Process.priorityNormal]; DO b: Buffer _ PupSocket.Get[socket]; SELECT b.type FROM gatewayRequest => PupInternal.ProcessGatewayRequest[b, FALSE]; gatewayInfo => IF PupInternal.ProcessGatewayInfo[b] THEN kick _ TRUE; ENDCASE => NULL; PupSocket.FreeBuffer[b]; ENDLOOP; }; kick: BOOL _ FALSE; RoutingDemon: PROC = { second: Process.Ticks = Process.SecondsToTicks[1]; Process.SetPriority[Process.priorityNormal]; DO FOR i: CARDINAL IN [0..15) UNTIL kick DO Process.Pause[2*second]; ENDLOOP; kick _ FALSE; PupInternal.ProcessGatewayRequest[NIL, FALSE]; ENDLOOP; }; RealForwarder: PROC [b: Buffer] RETURNS [Buffer] = { source: Network _ NARROW[b.ovh.network]; dest: Network; immediate: Pup.Host; old: Endian.HWORD; IF b.hopCount = PupHop.maxHop THEN { PupSocketBackdoor.ReturnErrorNoFree[b, tooManyHops, "Too many hops"]; BumpStats[source.index, 0, 0]; RETURN[b]; }; [dest, immediate] _ PupInternal.Route[b.dest]; IF dest = NIL THEN { PupSocketBackdoor.ReturnErrorNoFree[b, cantGetThere, "No route to that net"]; BumpStats[source.index, 0, 0]; RETURN[b]; }; TRUSTED { old _ (@b.hWord[0]+magicOne)^; }; b.hopCount _ b.hopCount.SUCC; UpdatePupChecksum[b, magicTwo, old]; b.ovh.encap _ dest.pup.getEncapsulation[dest, immediate]; dest.pup.send[dest, TempDriverBuffer[b], PupBuffer.RoundUpForChecksum[b.byteLength]]; BumpStats[source.index, dest.index, b.byteLength]; RETURN[b]; }; packetsForwarded: LONG CARDINAL _ 0; bytesForwarded: LONG CARDINAL _ 0; BumpStats: ENTRY PROC [source, dest: CARDINAL, bytes: CARDINAL] = { IF dest # 0 THEN { packetsForwarded _ packetsForwarded.SUCC; bytesForwarded _ bytesForwarded + bytes; }; }; magicOne: INTEGER = -9; -- offset for pupTransportControl magicTwo: CARDINAL = 1; UpdatePupChecksum: PROC [b: Buffer, offset: INTEGER, oldValue: WORD] = TRUSTED { words: NAT _ PupBuffer.WordsWithoutChecksum[b.byteLength]; checksumLoc: LONG POINTER TO Endian.HWORD _ @b.byteLength + words; diff: WORD; IF checksumLoc^ = PupBuffer.noChecksum THEN RETURN; diff _ OnesSub[(@b.hWord[0] + (offset + (magicOne - magicTwo)))^, oldValue]; checksumLoc^ _ OnesAdd[checksumLoc^, LeftCycle[diff, words - offset]]; }; OnesAdd: PROC [a, b: CARDINAL] RETURNS [c: CARDINAL] = INLINE { c _ a + b; IF c < a THEN c _ c + 1; IF c = 177777B THEN c _ 0; }; OnesSub: PROC [a, b: CARDINAL] RETURNS [c: CARDINAL] = INLINE { c _ a + (-b - 1); IF c < a THEN c _ c + 1; IF c = 177777B THEN c _ 0; }; LeftCycle: PROC [a, b: CARDINAL] RETURNS [c: CARDINAL] = INLINE { c _ a; THROUGH [0..(b MOD 16)) DO IF c < 100000B THEN c _ c*2 ELSE c _ c*2 + 1; ENDLOOP; }; PupInternal.CaptureForwarding[RealForwarder]; TRUSTED { Process.Detach[FORK RoutingSlurper[]]; }; TRUSTED { Process.Detach[FORK RoutingDemon[]]; }; }. ώPupForwarderImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Hal Murray, June 6, 1986 4:04:34 am PDT Russ Atkinson (RRA) April 25, 1986 5:07:14 pm PST Routing Table Updates Negative indexing to address word holding hopCount Κς˜codešœ™Kšœ Οmœ1™šŸœžœ˜˜ Kšœ˜Kšœ$˜$—KšœT˜TKšœ,˜,šž˜Kšœ"˜"šžœž˜Kšœ7žœ˜>Kšœžœ#žœžœ˜EKšžœžœ˜—Kšœ˜Kšžœ˜—K˜K˜—Kšœžœžœ˜šŸ œžœ˜K˜2Kšœ,˜,šž˜Kš žœžœžœ žœžœžœ˜JKšœžœ˜ Kšœ"žœžœ˜.Kšžœ˜—K˜—K˜šŸ œžœ žœ ˜4Kšœžœ˜(K˜K˜Kšœ žœ˜šžœžœ˜$KšœE˜EK˜Kšžœ˜ —K˜.šžœžœžœ˜KšœM˜MK˜Kšžœ˜ —šžœ$˜+Kšœ2™2—Kšœžœ˜Kšœ$˜$Kšœ9˜9KšœU˜UKšœ2˜2Kšžœ˜ K˜K˜—Kšœžœžœ˜$Kšœžœžœ˜"š Ÿ œžœžœžœ žœ˜Cšžœ žœ˜Kšœ$žœ˜)Kšœ+˜+—Kšœ˜—K˜Kšœ žœ !˜:šœ žœ˜K˜—š Ÿœžœžœ žœžœ˜PKšœžœ0˜:Kš œ žœžœžœžœ˜BKšœžœ˜ Kšžœ%žœžœ˜3KšœL˜LKšœF˜FKšœ˜—š œŸœžœžœžœžœžœ˜@Kšœ žœžœ ˜#Kšžœ žœ˜Kšœ˜—š Ÿœžœžœžœžœžœ˜?Kšœ˜Kšžœžœ ˜Kšžœ žœ˜Kšœ˜—š Ÿ œžœžœžœžœžœ˜AKšœ˜šžœžœž˜Kšžœ žœ žœ ˜-Kšžœ˜—Kšœ˜——˜Kšœ-˜-Kšžœžœ˜3šžœžœ˜1K˜——šœ˜K˜——…—ώ