PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

#
C# | 293 lines | 221 code | 56 blank | 16 comment | 27 complexity | db3c7a3702928713e9e5ba3be1714a42 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note: Simple Singularity test program.
  8. //
  9. using System;
  10. using System.Diagnostics;
  11. using System.Net.IP;
  12. using Microsoft.Singularity;
  13. using Microsoft.Singularity.Channels;
  14. using Microsoft.Singularity.Directory;
  15. using Microsoft.SingSharp;
  16. using NetStack.Contracts;
  17. using NetStack.Channels.Public;
  18. using Microsoft.Contracts;
  19. using Microsoft.SingSharp.Reflection;
  20. using Microsoft.Singularity.Applications;
  21. using Microsoft.Singularity.Io;
  22. using Microsoft.Singularity.Configuration;
  23. [assembly: Transform(typeof(ApplicationResourceTransform))]
  24. namespace Microsoft.Singularity.Applications.Network
  25. {
  26. [ConsoleCategory(Action="show", HelpMessage="Show network routing information")]
  27. internal class ShowConfig {
  28. [InputEndpoint("data")]
  29. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  30. [OutputEndpoint("data")]
  31. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  32. [Endpoint]
  33. public readonly TRef<RoutingContract.Imp:Start> routingRef;
  34. reflective internal ShowConfig();
  35. internal int AppMain() {
  36. return Route.Show(this);
  37. }
  38. }
  39. [ConsoleCategory(HelpMessage="Add network routing information",DefaultAction=true)]
  40. internal class AddConfig {
  41. [Endpoint]
  42. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  43. [Endpoint]
  44. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  45. [Endpoint]
  46. public readonly TRef<RoutingContract.Imp:Start> routingRef;
  47. [Endpoint]
  48. public readonly TRef<IPContract.Imp:Start> ipRef;
  49. [StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="destination to be added")]
  50. internal string destination;
  51. [StringParameter( "g", Mandatory=true, Position=1, HelpMessage="Gateway")]
  52. internal string gateway;
  53. [StringParameter( "i", Default=null, HelpMessage="ifAddress")]
  54. internal string ifAddress;
  55. reflective internal AddConfig();
  56. internal int AppMain() {
  57. Route.Add(this);
  58. return 0;
  59. }
  60. }
  61. [ConsoleCategory(Action="delete", HelpMessage="Remove network routing information")]
  62. internal class DeleteConfig {
  63. [Endpoint]
  64. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  65. [Endpoint]
  66. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  67. [Endpoint]
  68. public readonly TRef<RoutingContract.Imp:Start> routingRef;
  69. [StringParameter( "address", Mandatory=true, Position=0, HelpMessage="Address to be removed")]
  70. internal string address;
  71. [StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="destination to be removed")]
  72. internal string destination;
  73. reflective internal DeleteConfig();
  74. internal int AppMain() {
  75. return Route.Delete(this);
  76. }
  77. }
  78. /// <summary>
  79. /// Class for routing related configuration.
  80. /// </summary>
  81. public class Route
  82. {
  83. internal static int Show(ShowConfig! config)
  84. {
  85. RouteEntry[] in ExHeap routes;
  86. RoutingContract.Imp routeConn = ((!)config.routingRef).Acquire();
  87. if (routeConn == null) {
  88. Console.WriteLine("Could not initialize routing endpoint.");
  89. return 1;
  90. }
  91. routeConn.RecvReady();
  92. routeConn.SendGetRoutingTable();
  93. routeConn.RecvRoutingTable(out routes);
  94. if (routes == null)
  95. throw new Exception("routes is null");
  96. for (int i = 0; i < routes.Length; i++) {
  97. Console.WriteLine("Network : " + ChannelUtils.NetworkToString(routes[i].network));
  98. Console.WriteLine("Gateway : " + ChannelUtils.AddressToString(routes[i].gateway));
  99. Console.WriteLine("Interface address : " + ChannelUtils.AddressToString(routes[i].ifaddr));
  100. Console.WriteLine("Metric : " + routes[i].metric);
  101. Console.WriteLine(String.Format("Tag : {0:x8}\n", routes[i].tag));
  102. }
  103. delete routes;
  104. delete routeConn;
  105. return 0;
  106. }
  107. internal static int Add(AddConfig! config)
  108. {
  109. IPv4 gateway;
  110. RoutingContract.Imp routeConn = ((!)config.routingRef).Acquire();
  111. if (routeConn == null) {
  112. Console.WriteLine("Could not initialize routing endpoint.");
  113. return 1;
  114. }
  115. routeConn.RecvReady();
  116. if (IPv4.Parse(config.gateway, out gateway) == false) {
  117. Console.WriteLine("Could not parse gateway address.");
  118. delete routeConn;
  119. return -1;
  120. }
  121. try {
  122. // NOTE: for some reason the compiler doesn't
  123. // realize that ifaddr will definitely be assigned if
  124. // we survive the if/switch-receive sequence. Work
  125. // around that by initializing.
  126. IPv4 ifaddr = new IPv4(0);
  127. if (config.ifAddress == null) {
  128. routeConn.SendFindHostRoute((uint)gateway);
  129. switch receive {
  130. case routeConn.Route(RouteEntry r) :
  131. ifaddr = new IPv4(r.ifaddr);
  132. break;
  133. case routeConn.NoRouteFound() :
  134. Console.WriteLine("No route to gateway.");
  135. delete routeConn;
  136. return -1;
  137. break;
  138. case routeConn.ChannelClosed() :
  139. Console.WriteLine("routeConn channel closed.");
  140. throw new Exception("routeConn channel closed.");
  141. }
  142. }
  143. else if (IPv4.Parse(config.ifAddress, out ifaddr) == false) {
  144. Console.WriteLine("Could not parse interface address.");
  145. delete routeConn;
  146. return -1;
  147. }
  148. IPContract.Imp ipConn = ((!)config.ipRef).Acquire();
  149. if (ipConn == null) {
  150. Console.WriteLine("Could not initialize IP endpoint.");
  151. delete routeConn;
  152. return -1;
  153. }
  154. try {
  155. bool isLocal;
  156. ipConn.SendIsLocalAddress((uint)ifaddr);
  157. ipConn.RecvIsLocal(out isLocal);
  158. if (!isLocal) {
  159. Console.WriteLine("Proposed interface address is not bound to an interface.");
  160. delete routeConn;
  161. return -1;
  162. }
  163. }
  164. finally {
  165. delete ipConn;
  166. ipConn = null;
  167. }
  168. IPv4Network destination;
  169. if (IPv4Network.Parse(config.destination, out destination) == false) {
  170. Console.WriteLine("Could not parse destination address.");
  171. delete routeConn;
  172. return -1;
  173. }
  174. NetStack.Contracts.Network nwrk = new NetStack.Contracts.Network();
  175. nwrk.network = (uint)destination.Network;
  176. nwrk.netmask = (uint)destination.NetMask;
  177. routeConn.SendAddRoute(nwrk, (uint)gateway, (uint)ifaddr);
  178. switch receive {
  179. case routeConn.Err() :
  180. Console.WriteLine("Route could not be added -- it may already exist.");
  181. break;
  182. case routeConn.OK() :
  183. Console.WriteLine("Route added successfully");
  184. break;
  185. case routeConn.ChannelClosed() :
  186. throw new Exception("routeConn channel closed");
  187. }
  188. }
  189. catch (Exception e) {
  190. Console.WriteLine("Exception: {0}", e);
  191. }
  192. delete routeConn;
  193. return 0;
  194. }
  195. internal static int Delete(DeleteConfig! config)
  196. {
  197. RoutingContract.Imp routeConn = ((!)config.routingRef).Acquire();
  198. if (routeConn == null) {
  199. Console.WriteLine("Could not initialize routing endpoint.");
  200. return 1;
  201. }
  202. routeConn.RecvReady();
  203. IPv4Network destination;
  204. if (IPv4Network.Parse(config.destination, out destination) == false) {
  205. Console.WriteLine("Could not parse destination address.");
  206. }
  207. Network destNet = ChannelUtils.NetworkToChannelNetwork(destination);
  208. routeConn.SendFindSpecificNetRoute(destNet);
  209. switch receive {
  210. case routeConn.NoRouteFound() :
  211. Console.WriteLine("No route for destination.");
  212. delete routeConn;
  213. return -1;
  214. case routeConn.Route(RouteEntry r) :
  215. // Do nothing; success.
  216. break;
  217. case routeConn.ChannelClosed() :
  218. Console.WriteLine("routeConn channel closed.");
  219. throw new Exception("routeConn channel closed.");
  220. }
  221. routeConn.SendDeleteRoute(destNet);
  222. switch receive {
  223. case routeConn.NoRouteFound() :
  224. Console.WriteLine("Unexpected error attempting to delete the route");
  225. break;
  226. case routeConn.OK() :
  227. Console.WriteLine("Route successfully deleted");
  228. break;
  229. case routeConn.ChannelClosed() :
  230. Console.WriteLine("routeConn channel closed");
  231. throw new Exception("routeConn channel closed");
  232. }
  233. delete routeConn;
  234. return 0;
  235. }
  236. } // end class Route
  237. }