| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- // 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));
- }
- }
- }
|