//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // 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 Stdin; [OutputEndpoint("data")] public readonly TRef Stdout; [Endpoint] public readonly TRef 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 Stdin; [Endpoint] public readonly TRef Stdout; [Endpoint] public readonly TRef routingRef; [Endpoint] public readonly TRef 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="Remove network routing information")] internal class DeleteConfig { [Endpoint] public readonly TRef Stdin; [Endpoint] public readonly TRef Stdout; [Endpoint] public readonly TRef routingRef; [StringParameter( "address", Mandatory=true, Position=0, HelpMessage="Address to be removed")] internal string address; [StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="destination to be removed")] internal string destination; reflective internal DeleteConfig(); internal int AppMain() { return Route.Delete(this); } } /// /// Class for routing related configuration. /// 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 }