-- Copyright (C) 1984  by Xerox Corporation. All rights reserved. 
-- ForwarderCold.mesa, HGM, 16-Feb-84  0:29:52

DIRECTORY
  Event USING [aboutToSwap],
  EventTypes USING [aboutToBoot, aboutToBootPhysicalVolume],
  Supervisor USING [
    AddDependency, AgentProcedure, CreateSubsystem, SubsystemHandle],

  Buffer USING [PupBuffer, ReturnBuffer],
  Driver USING [Network],
  ForwarderDefs USING [PupForwarderOff],
  PupTypes USING [gatewaySoc],
  Stats USING [StatCounterIndex, StatsStringToIndex],
  Trouble USING [Bug];

ForwarderCold: PROGRAM
  IMPORTS Event, Supervisor, Buffer, ForwarderDefs, Stats, Trouble
  EXPORTS Buffer, ForwarderDefs
  SHARES Buffer =
  BEGIN OPEN Stats;

  -- EXPORTed TYPEs
  Network: PUBLIC TYPE = Driver.Network;

  broom: Supervisor.SubsystemHandle = Supervisor.CreateSubsystem[Broom];

  statPupGatewayPacketMs: PUBLIC StatCounterIndex;
  statGateInfoReplies: PUBLIC StatCounterIndex;
  statGateInfoBC: PUBLIC StatCounterIndex;
  statRoutingTableChanges: PUBLIC StatCounterIndex;
  statGateLowOnBuffers: PUBLIC StatCounterIndex;
  statGarbageSourceOrDest: PUBLIC StatCounterIndex;
  statNoRouteToNet: PUBLIC StatCounterIndex;
  statTooManyHops: PUBLIC StatCounterIndex;

  Broom: Supervisor.AgentProcedure =
    BEGIN
    SELECT event FROM
      EventTypes.aboutToBoot, EventTypes.aboutToBootPhysicalVolume =>
        ForwarderDefs.PupForwarderOff[];
      ENDCASE => NULL;
    END;

  SetupForwarderThings: PUBLIC PROCEDURE =
    BEGIN
    statPupGatewayPacketMs ← StatsStringToIndex["MS spent processing Pup Gateway Info Packets"];
    statGateInfoReplies ← StatsStringToIndex["Pup Gateway Info Replies"];
    statGateInfoBC ← StatsStringToIndex["Pup Gateway Info Broadcasts"];
    statRoutingTableChanges ← StatsStringToIndex["Pup Routing Table Changes"];
    statGateLowOnBuffers ← StatsStringToIndex[
      "Pups not forwarded: Gateway low on buffers"];
    statGarbageSourceOrDest ← StatsStringToIndex[
      "Pups not forwarded: Garbage source or dest"];
    statNoRouteToNet ← StatsStringToIndex[
      "Pups not forwarded: No route to that network"];
    statTooManyHops ← StatsStringToIndex[
      "Pups not forwarded: Hop count exceeded"];
    END;

  PeekAtRoutingPup: PUBLIC PROCEDURE [b: Buffer.PupBuffer] =
    BEGIN
    net: CARDINAL ← b.pup.source.net;
    network: Network ← b.network;
    -- Forwarder got a Pup before it was turned on.  See if it is the reply that would tell us that we have a buggy network number.
    IF b.pup.pupType = gatewayInfo AND b.pup.source.socket = PupTypes.gatewaySoc
      AND (net # network.pupNetNumber OR b.pup.pupTransportControl # 0)
      AND network.pupNetNumber < 400B THEN Trouble.Bug["Wrong network number"L];
    Buffer.ReturnBuffer[b];
    END;

  -- initialization
  SetupForwarderThings[];
  Supervisor.AddDependency[client: broom, implementor: Event.aboutToSwap];
  END.