2
0
Эх сурвалжийг харах

* Dns.cs: Initial work submitted to repository.
* IPHostEntry.cs: Initial work submitted to repository.
---------------------------------------------------------------------

svn path=/trunk/mcs/; revision=929

Mads Pultz 24 жил өмнө
parent
commit
d15c8ac724

+ 250 - 0
mcs/class/System/System.Net/Dns.cs

@@ -0,0 +1,250 @@
+// System.Net.Dns.cs
+//
+// Author: Mads Pultz ([email protected])
+//
+// (C) Mads Pultz, 2001
+
+using System;
+using System.Net.Sockets;
+using System.Text;
+using System.Collections;
+using System.Runtime.InteropServices;
+
+namespace System.Net {
+
+	public sealed class Dns {
+		
+		/// <summary>
+		///     This class conforms to the C structure <c>hostent</c> and is used
+		///     by the Dns class when doing native calls.
+		/// </summary>
+		[StructLayout(LayoutKind.Sequential)]
+		private unsafe class Hostent {
+			public string h_name;       /* official name */
+			public byte** h_aliases;    /* alias list */
+			public short h_addrtype;    /* address type */
+			public short h_length;      /* address length */
+			public byte** h_addr_list;  /* address list */
+		}
+		
+		public static IAsyncResult BeginGetHostByName(string hostName,
+                                                  AsyncCallback requestCallback,
+                                                  object stateObject) {
+			// TODO
+			throw new NotImplementedException();
+		}
+		
+		public static IAsyncResult BeginResolve(string hostName,
+	                                        AsyncCallback requestCallback,
+						object stateObject) {
+			// TODO
+			throw new NotImplementedException();
+		}
+		
+		public static IPHostEntry EndGetHostByName(IAsyncResult asyncResult) {
+			// TODO
+			throw new NotImplementedException();
+		}
+		
+		public static IPHostEntry EndResolve(IAsyncResult asyncResult) {
+			// TODO
+			throw new NotImplementedException();
+		}
+		
+		/// <param name=hostName>
+		///		IP address in network byte order (e.g. Big-Endian).
+		///	</param>
+		/// <param name=length>
+		///		Length of IP address
+		/// </param>
+		/// <param name=type>
+		///		Type (should be 2, equals AF_INET)
+		/// </param>
+		[DllImport("cygwin1", EntryPoint="gethostbyaddr")]
+		private static extern IntPtr _GetHostByAddress(byte[] hostName,
+							       short length,
+							       short type);
+		
+		/// <param name=address>
+		///		IP address in network byte order (e.g. Big-Endian).
+		/// </param>
+		private static IPHostEntry GetHostByAddress(long address) {
+			short length = 4;
+			if (address > uint.MaxValue)
+				length = 8;
+			byte[] addr = new byte[length];
+			for(int i = length - 1, j = 0; i >= 0; --i, ++j) {
+				byte b = (byte)(address >> i * 8);
+				Console.WriteLine(b);
+				addr[j] = b;
+			}
+			IntPtr p = _GetHostByAddress(addr, length, 2);  // TODO: set type
+			if (p == IntPtr.Zero)
+				throw new SocketException();  // TODO: set error code
+			Hostent h = new Hostent();
+			System.Runtime.InteropServices.Marshal.PtrToStructure(p, h);
+			return ToIPHostEntry(h);
+		}
+		
+		public static IPHostEntry GetHostByAddress(IPAddress address) {
+			if (address == null)
+				throw new ArgumentNullException();
+			return GetHostByAddress(IPAddress.HostToNetworkOrder(address.Address));
+		}
+		
+		public static IPHostEntry GetHostByAddress(string address) {
+			if (address == null)
+				throw new ArgumentNullException();
+			return GetHostByAddress(CreateAddress(address));
+		}
+		
+/*
+    [DllImport("cygwin1", EntryPoint="h_errno")]
+	private static extern int _h_errno;
+*/
+
+		[DllImport("cygwin1", EntryPoint="gethostbyname")]
+		private static extern IntPtr _GetHostByName(string hostName);
+		
+		public static IPHostEntry GetHostByName(string hostName) {
+			if (hostName == null)
+				throw new ArgumentNullException();
+			IntPtr p = _GetHostByName(hostName);
+			//	  int errNo = _h_errno;
+			if (p == IntPtr.Zero)
+				throw new SocketException();  // TODO: set error code
+			Hostent h = new Hostent();
+			System.Runtime.InteropServices.Marshal.PtrToStructure(p, h);
+			return ToIPHostEntry(h);
+		}
+		
+		/// <summary>
+		///	This method returns the host name associated with the local host.
+		/// </summary>
+		public static string GetHostName() {
+			IPHostEntry h = GetHostByAddress("127.0.0.1");
+			return h.HostName;
+		}
+		
+		/// <param name=address>
+		///	IP address in Little-Endian byte order.
+		/// </param>
+		/// <returns>
+		///	IP address in dotted notation form.
+		/// </returns>
+		public static string IpToString(int address) {
+			address = IPAddress.HostToNetworkOrder(address);
+			StringBuilder res = new StringBuilder();
+			for(int i = 3; i > 0; --i) {
+				byte b = (byte)(address >> i * 8);
+				res.Append(b);
+				res.Append('.');
+			}
+			res.Append((byte)address);
+			return res.ToString();
+		}
+		
+		/// <summary>
+		///	This method resovles a DNS-style host name or IP
+		///	address.
+		/// </summary>
+		/// <param name=hostName>
+		///	A string containing either a DNS-style host name (e.g.
+		///	www.go-mono.com) or IP address (e.g. 193.36.10.10).
+		/// </param>
+		public static IPHostEntry Resolve(string hostName) {
+			if (hostName == null)
+				throw new ArgumentNullException();
+			try {
+				long addr = CreateAddress(hostName);
+				if (addr > uint.MaxValue)
+					throw new FormatException("Only IP version 4 addresses are supported");
+				return GetHostByAddress(addr);
+			} catch (FormatException) {
+			  return GetHostByName(hostName);
+			}
+		}
+		
+		/// <remarks>
+		/// 	Utility method. This method converts a Hostent instance to a
+		/// 	IPHostEntry instance.
+		/// </remarks>
+		/// <param name=h>
+		///	Object which should be mapped to a IPHostEntry instance.
+		/// </param>
+		private static unsafe IPHostEntry ToIPHostEntry(Hostent h) {
+			IPHostEntry res = new IPHostEntry();
+			
+			// Set host name
+			res.HostName = h.h_name;
+			
+			// Set IP address list
+			byte** p = h.h_addr_list;
+			ArrayList tmp = new ArrayList(1);
+			while (*p != null) {
+				tmp.Add(CreateIPAddress(*p, h.h_length));
+				++p;
+			}
+			IPAddress[] addr_list = new IPAddress[tmp.Count];
+			for(int i = 0; i < tmp.Count; ++i)
+				addr_list[i] = (IPAddress)tmp[i];
+			res.AddressList = addr_list;
+			
+			// Set IP aliases
+			p = h.h_aliases;
+			tmp.Clear();
+			while (*p != null) {
+				tmp.Add(new string((sbyte*)*p));
+				++p;
+			}
+			string[] aliases = new string[tmp.Count];
+			for(int i = 0; i < tmp.Count; ++i)
+				aliases[i] = (string)tmp[i];
+			res.Aliases = aliases;
+			
+			return res;
+		}
+		
+		/// <summary>
+		///	Utility method. Convert IP address in dotted notation
+		///	to IP address.
+		/// </summary>
+		private static long CreateAddress(string address) {
+			string[] tokens = address.Split('.');
+			if (tokens.Length % 4 != 0)
+				throw new FormatException("IP address has invalid length");
+			long addr = 0;
+			for(int i = 0, j = tokens.Length - 1; i < tokens.Length; ++i, --j) {
+				try {
+					addr = addr | (((long)byte.Parse(tokens[i])) << j * 8);
+				} catch (OverflowException) {
+					throw new FormatException("Invalid IP address format");
+				}
+			}
+			return addr;
+		}
+	
+		/// <summary>
+		///	Utility method. This method creates a IP address.
+		/// </summary>
+		/// <param name=addr>
+		/// 	IP address in network byte order (e.g. Big-Endian).
+		/// </param>
+		/// <param name=length>
+		///	Length of IP address (4 or 8 bytes).
+		/// </param>
+		private static unsafe IPAddress CreateIPAddress(byte* addr, short length) {
+			byte* p = addr;
+			long res = 0;
+			for(int i = 0, j = length - 1; i < length; ++i, --j) {
+				res += *p << j * 8;
+				++p;
+			}
+			if (res > uint.MaxValue)
+				return new IPAddress(IPAddress.NetworkToHostOrder(res));
+			else
+				return new IPAddress(IPAddress.NetworkToHostOrder((int)res));
+		}
+	}
+}
+

+ 75 - 0
mcs/class/System/System.Net/IPHostEntry.cs

@@ -0,0 +1,75 @@
+// System.Net.IPHostEntry.cs
+//
+// Author: Mads Pultz ([email protected])
+//
+// (C) Mads Pultz, 2001
+
+using System;
+
+namespace System.Net {
+	
+	public class IPHostEntry {
+		private IPAddress[] addressList;
+		private String[] aliases;
+		private String hostName;
+		
+		public IPHostEntry() {
+			hostName = "localhost";
+			addressList = new IPAddress[1];
+			addressList[0] = IPAddress.Loopback;
+			aliases = new String[0];
+		}
+		
+		public IPAddress[] AddressList {
+			get { return addressList; }
+			set { addressList = value; }
+		}
+		
+		public string[] Aliases	{
+			get { return aliases; }
+			set { aliases = value; }
+		}
+		
+		public string HostName {
+			get { return hostName; }
+			set { hostName = value; }
+		}
+		
+/* According to the .NET Framework SDK Documentation (beta 2) the following
+   methods from Object are not overrided. I implemented them before realizing
+   this but I leave the implementation here if needed in the future.
+   
+		public override string ToString() {
+			string res = hostName;
+			if (addressList != null && addressList.Length > 0)
+				res += " [" + addressList[0] + "]";
+			return res;
+		}
+		
+		public override bool Equals(object obj) {
+			if (obj is IPHostEntry) {
+				IPHostEntry h = (IPHostEntry)obj;
+				return hostName.Equals(h.HostName) && aliases.Equals(h.Aliases) &&
+					addressList.Equals(h.AddressList);
+			}
+			else
+			  return false;
+		}
+		
+		public override int GetHashCode() {
+			return hostName.GetHashCode();
+		}
+		
+		protected new object MemberwiseClone() {
+			IPHostEntry res = new IPHostEntry();
+			res.AddressList = new IPAddress[addressList.Length];
+			Array.Copy(addressList, res.AddressList, addressList.Length);
+			res.Aliases = new String[aliases.Length];
+			Array.Copy(aliases, res.Aliases, aliases.Length);
+			res.HostName = hostName;
+			return res;
+		}
+*/
+	}
+}
+