312 lines
11 KiB
C#
312 lines
11 KiB
C#
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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
|
|
}
|