singrdk/base/Services/NetStack/Runtime/HostConfiguration.cs

454 lines
13 KiB
C#
Raw Permalink Normal View History

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 System;
using System.Collections;
using System.Net.IP;
2008-11-17 18:29:00 -05:00
using Microsoft.Contracts;
using Microsoft.Singularity;
using NetStack.Common;
2008-03-05 09:52:00 -05:00
using NetStack.Protocols;
2008-11-17 18:29:00 -05:00
using NetStack.NetDrivers;
2008-03-05 09:52:00 -05:00
#if !SINGULARITY
using System.Reflection;
using System.Net;
#endif
namespace NetStack.Runtime
{
// define the InterfaceList
public class InterfaceList : ArrayList {}
2008-11-17 18:29:00 -05:00
///
// The local host IP configuration
//
2008-03-05 09:52:00 -05:00
public class HostConfiguration
{
private string hostname;
private string domainname;
private bool isRouter;
private RoutingTable! routingTable;
private IList! nameServers;
private IPAdapterBindingTable! bindings;
private ArrayList! dhcpClients;
[NotDelayed]
public HostConfiguration()
{
2008-11-17 18:29:00 -05:00
RoutingTable! routingTableOnStack = new RoutingTable();
2008-03-05 09:52:00 -05:00
2008-11-17 18:29:00 -05:00
isRouter = false;
routingTable = routingTableOnStack;
2008-03-05 09:52:00 -05:00
nameServers = ArrayList.Synchronized(new ArrayList());
2008-11-17 18:29:00 -05:00
bindings = new IPAdapterBindingTable(routingTableOnStack);
dhcpClients = new ArrayList();
2008-03-05 09:52:00 -05:00
base();
SetHostName("singularity");
SetDomainName("microsoft.com");
2008-11-17 18:29:00 -05:00
#if false
IAdapter loopbackAdapter = new LoopbackAdapter();
Core.Instance().RegisterAdapter(loopbackAdapter, "loopback", LoopbackAdapter.RingSize);
2008-03-05 09:52:00 -05:00
2008-11-17 18:29:00 -05:00
this.bindings.Add(loopbackAdapter,
new InterfaceIPConfiguration(
IPv4.Loopback,
new IPv4(0xff000000),
IPv4.Loopback,
1));
#endif
2008-03-05 09:52:00 -05:00
routingTable.AddRoute(
new RouteEntry(IPv4Network.Loopback,
IPv4.Loopback,
IPv4.Loopback,
RouteEntry.InterfaceMetric,
RouteEntry.InterfaceRouteTag)
);
}
public string! GetHostName()
{
return hostname;
}
public bool SetHostName(string! name)
{
int dot = name.IndexOf('.');
2008-11-17 18:29:00 -05:00
if (dot >= 0) {
2008-03-05 09:52:00 -05:00
string hostpart = name.Substring(0, dot);
string domainpart = name.Substring(dot + 1);
if ((ValidDnsName(hostpart, false) == false) ||
(ValidDnsName(domainpart, true) == false))
return false;
hostname = hostpart;
domainname = domainpart;
return true;
}
if (ValidDnsName(name, false) == false)
return false;
hostname = name;
return true;
}
public string! GetDomainName()
{
return domainname;
}
public bool SetDomainName(string! name)
{
2008-11-17 18:29:00 -05:00
if (ValidDnsName(name, true) == false) {
2008-03-05 09:52:00 -05:00
return false;
}
domainname = name;
return true;
}
private static bool ValidDnsName(string! name, bool dotsAllowed)
{
if (name.Length <= 2)
return false;
// Dashes are okay as long as not first or last character
int last = name.Length - 1;
if (name[0] == '-' || name[last] == '-')
return false;
2008-11-17 18:29:00 -05:00
for (int i = 0; i <= last; i++) {
2008-03-05 09:52:00 -05:00
// Letters, digits, and dashes are okay
if (Char.IsLetterOrDigit(name[i]) == true || name[i] == '-')
continue;
// Dots are okay in domain-names
if (name[i] == '.' && dotsAllowed == true)
continue;
return false;
}
return true;
}
public bool IsRouter
{
get { return isRouter; }
}
public RoutingTable! RoutingTable
{
get { return routingTable; }
}
public IPAdapterBindingTable! Bindings
{
get { return bindings; }
}
public void AddNameServer(IPv4 address)
{
nameServers.Add(address);
}
public bool DeleteNameServer(IPv4 address)
{
2008-11-17 18:29:00 -05:00
lock (nameServers.SyncRoot) {
2008-03-05 09:52:00 -05:00
int index = this.nameServers.IndexOf(address);
if (index < 0)
return false;
nameServers.RemoveAt(index);
return true;
}
}
/// <summary>
/// Get enumerable interface of IPv4 collection
/// containing name servers.
/// </summary>
public IEnumerable! NameServers()
{
return nameServers;
}
/// <summary>
/// Get the current name server.
/// </summary>
public IPv4 GetCurrentNameServer()
{
2008-11-17 18:29:00 -05:00
lock (nameServers.SyncRoot) {
if (nameServers.Count > 0) {
2008-03-05 09:52:00 -05:00
return (IPv4) (!) nameServers[0];
}
return IPv4.Zero;
}
}
/// <summary>
/// Rotate name servers.
/// </summary>
public void RotateNameServers()
{
2008-11-17 18:29:00 -05:00
lock (nameServers.SyncRoot) {
2008-03-05 09:52:00 -05:00
if (nameServers.Count < 2)
return;
IPv4 retiree = (IPv4) (!) nameServers[0];
nameServers.RemoveAt(0);
nameServers.Add(retiree);
}
}
public bool IsLocalAddress(IPv4 ipAddress)
{
return bindings.IsLocalAddress(ipAddress);
}
public bool StartDhcp(IAdapter adapter)
{
2008-11-17 18:29:00 -05:00
lock (dhcpClients) {
foreach (DhcpClient! client in dhcpClients) {
2008-03-05 09:52:00 -05:00
if (client.Adapter == adapter)
return false;
}
DhcpClient dc = new DhcpClient(adapter);
dc.Start();
dhcpClients.Add(dc);
}
return true;
}
public bool StopDhcp(IAdapter adapter)
{
2008-11-17 18:29:00 -05:00
lock (dhcpClients) {
for (int i = 0; i < dhcpClients.Count; i++) {
2008-03-05 09:52:00 -05:00
DhcpClient client = (DhcpClient!) dhcpClients[i];
2008-11-17 18:29:00 -05:00
if (client.Adapter == adapter) {
2008-03-05 09:52:00 -05:00
client.Stop();
dhcpClients.RemoveAt(i);
return true;
}
}
}
return false;
}
public bool IsRunningDhcp(IAdapter adapter)
{
2008-11-17 18:29:00 -05:00
lock (dhcpClients) {
foreach (DhcpClient! client in dhcpClients) {
2008-03-05 09:52:00 -05:00
if (client.Adapter == adapter)
return true;
}
}
return false;
}
}
// an interface ip address
public class InterfaceIPConfiguration
{
IPv4 address;
IPv4 netmask;
IPv4 gateway;
int ttl;
public InterfaceIPConfiguration(IPv4 address,
IPv4 netmask,
IPv4 gateway,
int ttl)
{
this.address = address;
this.netmask = netmask;
this.gateway = gateway;
this.ttl = ttl;
}
public InterfaceIPConfiguration(IPv4 address,
IPv4 netmask,
IPv4 gateway)
: this(address, netmask, gateway, IPFormat.DefaultTTL)
{
}
public IPv4 Address
{
get { return address; }
}
public IPv4 NetMask
{
get { return netmask; }
}
public IPv4 Gateway
{
get { return gateway; }
}
public int TTL
{
get { return ttl; }
set { ttl = value; }
}
}
// this is the local ip table entry
// binds an IP to a specific adapter
public class IPBinding
{
private IAdapter! adapter;
private InterfaceIPConfiguration! ipConfig;
public IPBinding(IAdapter! ad, InterfaceIPConfiguration! ipc)
{
adapter = ad;
ipConfig = ipc;
base();
}
public IAdapter! Adapter
{
get { return adapter; }
}
public InterfaceIPConfiguration! IPConfiguration
{
get { return ipConfig; }
}
}
public class IPAdapterBindingTable
{
Hashtable ipBindings; // <IPv4,IPBinding>
RoutingTable routingTable;
public IPAdapterBindingTable(RoutingTable routingTable)
{
this.ipBindings = new Hashtable();
this.routingTable = routingTable;
}
private void AddInterfaceRoutes(InterfaceIPConfiguration! ipConfig)
{
//
// Add subnet route
//
IPv4Network subnet = new IPv4Network(ipConfig.Address,
ipConfig.NetMask);
routingTable.AddRoute(
new RouteEntry(subnet,
ipConfig.Address,
ipConfig.Address,
RouteEntry.DirectlyConnectedMetric,
RouteEntry.InterfaceRouteTag)
);
//
// Add route to gateway
//
routingTable.AddRoute(
new RouteEntry(ipConfig.Gateway,
ipConfig.Address,
ipConfig.Address,
RouteEntry.DirectlyConnectedMetric,
RouteEntry.InterfaceRouteTag)
);
//
// Add default route if none exists
//
2008-11-17 18:29:00 -05:00
if (routingTable.Lookup(IPv4Network.Default) == null) {
2008-03-05 09:52:00 -05:00
routingTable.AddRoute(
new RouteEntry(IPv4Network.Default,
ipConfig.Gateway,
ipConfig.Address,
RouteEntry.DefaultRouteMetric,
RouteEntry.InterfaceRouteTag)
);
}
}
private void DeleteInterfaceRoutes(InterfaceIPConfiguration! ipConfig)
{
routingTable.DeleteInterfaceRoutes(ipConfig.Address);
}
public bool Add(IAdapter! adapter, InterfaceIPConfiguration! ipConfig)
{
2008-11-17 18:29:00 -05:00
if (ipBindings[ipConfig.Address] != null) {
2008-03-05 09:52:00 -05:00
return false;
}
ipBindings[ipConfig.Address] = new IPBinding(adapter, ipConfig);
AddInterfaceRoutes(ipConfig);
return true;
}
/// <summary>
/// Delete all IP address bindings associated with adapter.
/// </summary>
public void Flush(IAdapter adapter)
{
Stack flushItems = new Stack();
2008-11-17 18:29:00 -05:00
foreach (IPBinding! ipb in ipBindings.Values) {
if (ipb.Adapter == adapter) {
2008-03-05 09:52:00 -05:00
flushItems.Push(ipb.IPConfiguration);
}
}
2008-11-17 18:29:00 -05:00
while (flushItems.Count != 0) {
2008-03-05 09:52:00 -05:00
Flush((InterfaceIPConfiguration!) flushItems.Pop());
}
}
/// <summary>
/// Delete specific IP address binding from adapter.
/// </summary>
internal void Flush(IAdapter adapter, IPv4 address)
{
IPBinding ipb = (IPBinding) ipBindings[address];
2008-11-17 18:29:00 -05:00
if (ipb != null && ipb.Adapter == adapter) {
2008-03-05 09:52:00 -05:00
Flush(ipb.IPConfiguration);
}
}
private void Flush(InterfaceIPConfiguration! ipConfig)
{
DeleteInterfaceRoutes(ipConfig);
ipBindings.Remove(ipConfig.Address);
}
public IAdapter GetAdapter(IPv4 address)
{
IPBinding ipb = (IPBinding) ipBindings[address];
2008-11-17 18:29:00 -05:00
if (ipb == null) {
2008-03-05 09:52:00 -05:00
return null;
}
return ipb.Adapter;
}
// is the given ip defined?
public bool IsLocalAddress(IPv4 ipAddress)
{
return ipBindings[ipAddress] != null;
}
public ArrayList! GetAdapterIPConfigurations(IAdapter adapter)
{
ArrayList results = new ArrayList();
2008-11-17 18:29:00 -05:00
foreach (IPBinding! ipb in ipBindings.Values) {
2008-03-05 09:52:00 -05:00
if (ipb.Adapter == adapter)
results.Add(ipb.IPConfiguration);
}
return results;
}
}
}