singrdk/base/Applications/Network/Route/Route.cs

312 lines
11 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: Route.cs
//
// Note: Simple Singularity test program.
//
using System;
using System.Diagnostics;
using System.Net.IP;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using Microsoft.SingSharp;
using NetStack.Contracts;
using NetStack.Channels.Public;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
namespace Microsoft.Singularity.Applications.Network {
[ConsoleCategory(Action="show", HelpMessage="Show network routing information")]
internal class ShowConfig {
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[Endpoint]
public readonly TRef<RoutingContract.Imp:Start> routingRef;
reflective internal ShowConfig();
internal int AppMain() {
return Route.Show(this);
}
}
[ConsoleCategory(HelpMessage="Add network routing information",DefaultAction=true)]
internal class AddConfig {
[Endpoint]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[Endpoint]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[Endpoint]
public readonly TRef<RoutingContract.Imp:Start> routingRef;
[Endpoint]
public readonly TRef<IPContract.Imp:Start> ipRef;
[StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="destination to be added")]
internal string destination;
[StringParameter( "g", Mandatory=true, Position=1, HelpMessage="Gateway")]
internal string gateway;
[StringParameter( "i", Default=null, HelpMessage="ifAddress")]
internal string ifAddress;
reflective internal AddConfig();
internal int AppMain() {
Route.Add(this);
return 0;
}
}
[ConsoleCategory(Action="delete", HelpMessage="Show network routing information")]
internal class DeleteConfig {
[Endpoint]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[Endpoint]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[Endpoint]
public readonly TRef<RoutingContract.Imp:Start> routingRef;
[StringParameter( "address", Mandatory=true, Position=0, HelpMessage="Address to be deleted")]
internal string address;
[StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="Address to be added")]
internal string destination;
reflective internal DeleteConfig();
internal int AppMain() {
return Route.Delete(this);
}
}
/// <summary>
/// Class for routing related configuration.
/// </summary>
public class Route
{
internal static int Show(ShowConfig! config)
{
RouteEntry[] in ExHeap routes;
RoutingContract.Imp routeConn = (config.routingRef).Acquire();
if (routeConn == null) {
Console.WriteLine("Could not initialize routing endpoint.");
return 1;
}
routeConn.RecvReady();
routeConn.SendGetRoutingTable();
routeConn.RecvRoutingTable(out routes);
if (routes == null)
throw new Exception("routes is null");
for (int i = 0; i < routes.Length; i++)
{
Console.WriteLine("Network : " + ChannelUtils.NetworkToString(routes[i].network));
Console.WriteLine("Gateway : " + ChannelUtils.AddressToString(routes[i].gateway));
Console.WriteLine("Interface address : " + ChannelUtils.AddressToString(routes[i].ifaddr));
Console.WriteLine("Metric : " + routes[i].metric);
Console.WriteLine(String.Format("Tag : {0:x8}\n", routes[i].tag));
}
delete routes;
delete routeConn;
return 0;
}
internal static int Add(AddConfig! config)
{
IPv4 gateway;
RoutingContract.Imp routeConn = (config.routingRef).Acquire();
if (routeConn == null) {
Console.WriteLine("Could not initialize routing endpoint.");
return 1;
}
routeConn.RecvReady();
if (IPv4.Parse(config.gateway, out gateway) == false)
{
Console.WriteLine("Could not parse gateway address.");
delete routeConn;
return -1;
}
try
{
// note for some reason the compiler doesn't
// realize that ifaddr will definitely be assigned if
// we survive the if/switch-receive sequence. Work
// around that by initializing.
IPv4 ifaddr = new IPv4(0);
if (config.ifAddress == null)
{
routeConn.SendFindHostRoute((uint)gateway);
switch receive
{
case routeConn.Route(RouteEntry r) :
ifaddr = new IPv4(r.ifaddr);
break;
case routeConn.NoRouteFound() :
Console.WriteLine("No route to gateway.");
delete routeConn;
return -1;
break;
case routeConn.ChannelClosed() :
Console.WriteLine("routeConn channel closed.");
throw new Exception("routeConn channel closed.");
}
}
else if (IPv4.Parse(config.ifAddress, out ifaddr) == false)
{
Console.WriteLine("Could not parse interface address.");
delete routeConn;
return -1;
}
IPContract.Imp ipConn = (config.ipRef).Acquire();
if (ipConn == null)
{
Console.WriteLine("Could not initialize IP endpoint.");
delete routeConn;
return -1;
}
try
{
bool isLocal;
ipConn.SendIsLocalAddress((uint)ifaddr);
ipConn.RecvIsLocal(out isLocal);
if (!isLocal)
{
Console.WriteLine("Proposed interface address is not bound to an interface.");
delete routeConn;
return -1;
}
}
finally
{
delete ipConn;
ipConn = null;
}
IPv4Network destination;
if (IPv4Network.Parse(config.destination, out destination) == false)
{
Console.WriteLine("Could not parse destination address.");
delete routeConn;
return -1;
}
NetStack.Contracts.Network nwrk = new NetStack.Contracts.Network();
nwrk.network = (uint)destination.Network;
nwrk.netmask = (uint)destination.NetMask;
routeConn.SendAddRoute(nwrk, (uint)gateway, (uint)ifaddr);
switch receive
{
case routeConn.Err() :
Console.WriteLine("Route could not be added -- it may already exist.");
break;
case routeConn.OK() :
Console.WriteLine("Route added successfully");
break;
case routeConn.ChannelClosed() :
throw new Exception("routeConn channel closed");
}
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e);
}
delete routeConn;
return 0;
}
internal static int Delete(DeleteConfig! config)
{
RoutingContract.Imp routeConn = (config.routingRef).Acquire();
if (routeConn == null)
{
Console.WriteLine("Could not initialize routing endpoint.");
return 1;
}
routeConn.RecvReady();
IPv4Network destination;
if (IPv4Network.Parse(config.destination, out destination) == false)
{
Console.WriteLine("Could not parse destination address.");
}
Network destNet = ChannelUtils.NetworkToChannelNetwork(destination);
routeConn.SendFindSpecificNetRoute(destNet);
switch receive
{
case routeConn.NoRouteFound() :
Console.WriteLine("No route for destination.");
delete routeConn;
return -1;
case routeConn.Route(RouteEntry r) :
// Do nothing; success.
break;
case routeConn.ChannelClosed() :
Console.WriteLine("routeConn channel closed.");
throw new Exception("routeConn channel closed.");
}
routeConn.SendDeleteRoute(destNet);
switch receive
{
case routeConn.NoRouteFound() :
Console.WriteLine("Unexpected error attempting to delete the route");
break;
case routeConn.OK() :
Console.WriteLine("Route successfully deleted");
break;
case routeConn.ChannelClosed() :
Console.WriteLine("routeConn channel closed");
throw new Exception("routeConn channel closed");
}
delete routeConn;
return 0;
}
} // end class Route
}