2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
///
|
|
|
|
// Microsoft Research, Cambridge
|
|
|
|
//
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
using NetStack.Common;
|
|
|
|
using System;
|
|
|
|
using System.Net;
|
|
|
|
using System.Text;
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
using System.Net.IP;
|
|
|
|
using Drivers.Net;
|
|
|
|
using NetStack.Configuration;
|
|
|
|
using NetStack.Protocols;
|
|
|
|
using NetStack.NetDrivers;
|
|
|
|
|
|
|
|
namespace NetStack.Runtime
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Parses XML configuration file and instantiates runtime components.
|
|
|
|
/// </summary>
|
|
|
|
public class XmlConfiguration
|
|
|
|
{
|
|
|
|
string configFile;
|
|
|
|
|
|
|
|
// the driver's path (for dynamic loading)
|
|
|
|
protected string driversPath;
|
|
|
|
|
|
|
|
// the protocols' path (for dynamic loading)
|
|
|
|
// where the actual module reside
|
|
|
|
protected string protocolsPath;
|
|
|
|
|
|
|
|
public XmlConfiguration(string configFile)
|
|
|
|
{
|
|
|
|
this.configFile = configFile;
|
2008-11-17 18:29:00 -05:00
|
|
|
if (System.IO.File.Exists(configFile) == false) {
|
2008-03-05 09:52:00 -05:00
|
|
|
Core.Panic("Can't locate configuration file, Exit!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public XmlConfiguration()
|
|
|
|
{
|
|
|
|
// check if the file exists...
|
|
|
|
// 1. check for <appName>.xml
|
|
|
|
// 2. then for config.xml locally
|
|
|
|
string appFullPath = AppDomain.CurrentDomain.BaseDirectory +
|
|
|
|
AppDomain.CurrentDomain.FriendlyName;
|
|
|
|
string configFile1 = AppDomain.CurrentDomain.BaseDirectory + @"config.xml";
|
|
|
|
string configFile2 = appFullPath.Substring(0,appFullPath.Length-4) + @".xml";
|
2008-11-17 18:29:00 -05:00
|
|
|
if (System.IO.File.Exists(configFile1)) {
|
2008-03-05 09:52:00 -05:00
|
|
|
configFile = configFile1;
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
else if (System.IO.File.Exists(configFile2)) {
|
2008-03-05 09:52:00 -05:00
|
|
|
configFile = configFile2;
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
else {
|
2008-03-05 09:52:00 -05:00
|
|
|
Core.Panic("Can't locate configuration file, Exit!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// loads an adapter's driver and add the relevant data structures
|
|
|
|
// for managing it.
|
|
|
|
protected bool LoadAdapter(ProtocolParams args, string driversPath)
|
|
|
|
{
|
|
|
|
// the user can ignore an adapter
|
|
|
|
// so ignore it...
|
|
|
|
string ignore = args["ignore"];
|
|
|
|
if (ignore != null && ignore == "true")
|
|
|
|
return true;
|
|
|
|
|
|
|
|
string name =
|
|
|
|
ProtocolParams.LookupString(args, "name", "unknown");
|
|
|
|
string typeName =
|
|
|
|
ProtocolParams.LookupString(args, "type", "unknown");
|
|
|
|
string id =
|
|
|
|
ProtocolParams.LookupString(args, "id", "unknown");
|
|
|
|
|
|
|
|
int mtu = ProtocolParams.LookupInt32(args, "mtu",
|
|
|
|
EthernetFormat.MaxFrameSize);
|
|
|
|
int txRing = ProtocolParams.LookupInt32(args, "txRing", 64);
|
|
|
|
int rxRing = ProtocolParams.LookupInt32(args, "rxRing", 64);
|
|
|
|
int fwQueue = ProtocolParams.LookupInt32(args, "fwQueue", 64);
|
|
|
|
|
|
|
|
IAdapterFactory factory = null;
|
|
|
|
IAdapter adapter = null;
|
|
|
|
try {
|
|
|
|
string factoryTypeName = typeName + "Factory";
|
|
|
|
Assembly assembly = Assembly.LoadFrom(driversPath);
|
|
|
|
Type[] types = assembly.GetTypes();
|
2008-11-17 18:29:00 -05:00
|
|
|
foreach (Type t in types) {
|
|
|
|
if (t.IsClass && t.Name.Equals(typeName)) {
|
2008-03-05 09:52:00 -05:00
|
|
|
factory = (IAdapterFactory)Activator.CreateInstance(t, null);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (factory == null)
|
|
|
|
throw new Exception("Can't find Adapter's Factory.");
|
|
|
|
|
|
|
|
adapter = factory.CreateAdapter(name, id, txRing, rxRing);
|
|
|
|
Core.Instance().RegisterAdapter(adapter, fwQueue);
|
|
|
|
}
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
catch (Exception e) {
|
2008-03-05 09:52:00 -05:00
|
|
|
adapter = null;
|
|
|
|
Console.Out.WriteLine(e.Message);
|
|
|
|
Environment.Exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
IPModule ipModule = Core.Instance().GetProtocolByName("IP") as IPModule;
|
|
|
|
HostConfiguration hostConfig = ipModule.HostConfiguration;
|
2008-11-17 18:29:00 -05:00
|
|
|
for (int i = 0;; i++) {
|
2008-03-05 09:52:00 -05:00
|
|
|
string ipTag = String.Format("ip{0}", i);
|
|
|
|
string maskTag = String.Format("mask{0}", i);
|
|
|
|
string gatewayTag = String.Format("gateway{0}", i);
|
|
|
|
|
|
|
|
// XXX No point-to-point support here.
|
|
|
|
IPv4 address = ProtocolParams.LookupIPv4(args, ipTag,
|
|
|
|
IPv4.AllOnes);
|
|
|
|
IPv4 netmask = ProtocolParams.LookupIPv4(args, maskTag,
|
|
|
|
IPv4.AllOnes);
|
|
|
|
IPv4 gateway = ProtocolParams.LookupIPv4(args, gatewayTag,
|
|
|
|
IPv4.Zero);
|
2008-11-17 18:29:00 -05:00
|
|
|
if (address == IPv4.AllOnes || netmask == IPv4.AllOnes) {
|
2008-03-05 09:52:00 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
hostConfig.Bindings.Add(adapter,
|
|
|
|
new InterfaceIPConfiguration(address, netmask, gateway, 128)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
System.Console.Out.WriteLine("[Interface {0}]", args["name"]);
|
|
|
|
System.Console.Out.WriteLine("-----------------------------");
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// This method dynamically loads a protocol and
|
|
|
|
// initializes it.
|
|
|
|
protected bool LoadProtocolModule(ProtocolParams args)
|
|
|
|
{
|
|
|
|
// the user can mark a protocol ignore field so
|
|
|
|
// we just ignore it...
|
|
|
|
string ignore = args["ignore"];
|
|
|
|
if (ignore != null && ignore == "true")
|
|
|
|
return true;
|
|
|
|
#if DEBUG
|
|
|
|
System.Console.Out.WriteLine("[Protocol {0}]", args["name"]);
|
|
|
|
foreach (string s in args.Keys)
|
|
|
|
System.Console.Out.WriteLine("{0}={1}",s,args[s]);
|
|
|
|
System.Console.Out.WriteLine("-----------------------------");
|
|
|
|
#endif
|
|
|
|
// dynamic load the protocol
|
|
|
|
// by default it is in the Runtime assembly
|
|
|
|
string protocolType = args["type"];
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
try {
|
2008-03-05 09:52:00 -05:00
|
|
|
IProtocol protocol = (IProtocol)Activator.CreateInstance(Type.GetType(protocolType));
|
|
|
|
|
|
|
|
if (protocol == null)
|
|
|
|
throw new Exception("Can't find Protocol's Class.");
|
|
|
|
|
|
|
|
// initialize the protocol
|
|
|
|
protocol.Initialize(args);
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
catch (Exception e) {
|
2008-03-05 09:52:00 -05:00
|
|
|
Console.Out.WriteLine(String.Format("Can't load protocol class: {0}",protocolType));
|
|
|
|
Console.Out.WriteLine(e.Message);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse the configuration file return the root or
|
|
|
|
// null if error.
|
|
|
|
protected ConfigElement ParseConfiguration(bool toPrint)
|
|
|
|
{
|
|
|
|
ConfigElement root = null;
|
|
|
|
root = ConfigFileParser.parseFile(configFile);
|
2008-11-17 18:29:00 -05:00
|
|
|
if (root != null && toPrint) {
|
2008-03-05 09:52:00 -05:00
|
|
|
System.Text.StringBuilder tree = new System.Text.StringBuilder();
|
|
|
|
ConfigFileParser.printConfigurationTree(root,tree,0);
|
|
|
|
System.Console.WriteLine(tree);
|
|
|
|
}
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
|
|
|
//handle host config
|
|
|
|
protected void HandleConfiguration()
|
|
|
|
{
|
|
|
|
Core core = Core.Instance();
|
|
|
|
|
|
|
|
// the path of the driver assembly
|
|
|
|
ConfigElement config = ParseConfiguration(false);
|
|
|
|
|
|
|
|
// we start with the configuration tag...
|
|
|
|
// we assume that the XML is valid!
|
|
|
|
|
|
|
|
// if we have children, and we have...
|
2008-11-17 18:29:00 -05:00
|
|
|
if (config.ChildElements.Count > 0) {
|
|
|
|
foreach (ConfigElement element in config.ChildElements) {
|
|
|
|
switch (element.TagName) {
|
2008-03-05 09:52:00 -05:00
|
|
|
case "creator":
|
|
|
|
break;
|
|
|
|
case "date":
|
|
|
|
break;
|
|
|
|
case "hostname":
|
|
|
|
break;
|
|
|
|
case "forwarding":
|
|
|
|
break;
|
|
|
|
case "OutQHandlerTimeout":
|
|
|
|
core.SetOutQueueHandlerInterval(Convert.ToInt32(element.Text,10));
|
|
|
|
break;
|
|
|
|
case "protocol-path":
|
|
|
|
protocolsPath = element.Text;
|
|
|
|
break;
|
|
|
|
case "drivers-path":
|
|
|
|
driversPath = element.Text;
|
|
|
|
break;
|
|
|
|
case "backlog-size":
|
|
|
|
int freeListSize = Convert.ToInt32(element.Text,10);
|
|
|
|
core.ProvisionDemux(
|
|
|
|
freeListSize,
|
|
|
|
EthernetFormat.MaxFrameSize
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case "protocols":
|
|
|
|
// handle the protocols
|
|
|
|
// use a generic scheme and apply
|
|
|
|
// it to the adapters in the future ;-)
|
|
|
|
|
|
|
|
// the args include the name and type!
|
|
|
|
ProtocolParams args = new ProtocolParams();;
|
2008-11-17 18:29:00 -05:00
|
|
|
foreach (ConfigElement prot in element.ChildElements) {
|
2008-03-05 09:52:00 -05:00
|
|
|
args.Clear();
|
|
|
|
foreach (string attr in prot.Attributes.Keys)
|
|
|
|
args.Add(attr,prot.Attribute(attr));
|
|
|
|
foreach (ConfigElement protInfo in prot.ChildElements)
|
|
|
|
args.Add(protInfo.TagName,protInfo.Text);
|
|
|
|
// done with one...
|
|
|
|
if (!LoadProtocolModule(args))
|
|
|
|
Core.Panic("Error while loading Protocol");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "adapters":
|
|
|
|
// handle the adapters
|
|
|
|
ProtocolParams adArgs = new ProtocolParams();;
|
2008-11-17 18:29:00 -05:00
|
|
|
foreach (ConfigElement ad in element.ChildElements) {
|
2008-03-05 09:52:00 -05:00
|
|
|
adArgs.Clear();
|
|
|
|
foreach (string attr in ad.Attributes.Keys)
|
|
|
|
adArgs.Add(attr,ad.Attribute(attr));
|
|
|
|
foreach (ConfigElement adInfo in ad.ChildElements)
|
|
|
|
adArgs.Add(adInfo.TagName,adInfo.Text);
|
|
|
|
// done with one...
|
|
|
|
if (!LoadAdapter(adArgs,driversPath))
|
|
|
|
Core.Panic("Error while loading an Adapter");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public string ConfigurationFilename { get { return configFile; } }
|
|
|
|
}
|
|
|
|
} // NetStack.Runtime
|