using IFS.Gateway;
using IFS.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IFS.Gateway
{
public struct GatewayInformation
{
public byte TargetNet;
public byte GatewayNet;
public byte GatewayHost;
public byte HopCount;
}
///
/// Gateway Information Protocol (see http://xeroxalto.computerhistory.org/_cd8_/pup/.gatewayinformation.press!1.pdf)
///
public class GatewayInformationProtocol : PUPProtocolBase
{
public GatewayInformationProtocol()
{
// TODO:
// load host tables, etc.
// spin up thread that spits out a GatewayInformation PUP periodically.
}
///
/// Called by dispatcher to send incoming data destined for this protocol
///
///
public override void RecvData(PUP p)
{
switch (p.Type)
{
case PupType.GatewayInformationRequest:
SendGatewayInformationResponse(p);
break;
default:
Log.Write(LogComponent.MiscServices, String.Format("Unhandled Gateway protocol {0}", p.Type));
break;
}
}
private void SendGatewayInformationResponse(PUP p)
{
//
// Pup Type: 201 (octal)
// Pup ID: same as in Request Pup
// Pup Contents: one or more groups of four bytes, each providing routing information for
// one network, as follows:
//
//
//
// In each group, the first byte specifies the target network number. If the gateway host is
// directly connected to that network, then the is zero and the and
// describe the gateway’s connection to the network.
// If the gateway host is not directly connected to the target network, then the second and
// third bytes give the network and host numbers of another gateway through which the
// responding gateway routes Pups to that network, and the fourth byte gives the hop count,
// i.e., the number of additional gateways (not including itself) through which the responding
// gateway believes a Pup must pass to reach the specified network. A hop count greater than
// the constant maxHops (presently 15) signifies that the target network is believed to be
// inaccessible.
//
// Right now, we know of only one network (our own) and we are directly connected to it.
//
GatewayInformation info = new GatewayInformation();
info.TargetNet = DirectoryServices.Instance.LocalNetwork;
info.GatewayNet = DirectoryServices.Instance.LocalNetwork;
info.GatewayHost = DirectoryServices.Instance.LocalNetwork;
info.HopCount = 0;
PUPPort localPort = new PUPPort(DirectoryServices.Instance.LocalHostAddress, p.DestinationPort.Socket);
// Response must contain our network number; this is used to tell clients what network they're on if they don't already know.
PUPPort remotePort = new PUPPort(DirectoryServices.Instance.LocalNetwork, p.SourcePort.Host, p.SourcePort.Socket);
PUP response = new PUP(PupType.GatewayInformationResponse, p.ID, remotePort, localPort, Serializer.Serialize(info));
Router.Instance.SendPup(response);
}
}
}