diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2017-08-16 02:43:41 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2017-08-16 02:43:41 -0400 |
| commit | bfcd1b520fd79b893e721ba916ae5e1656407d2f (patch) | |
| tree | 6a05119800484435fb384da25c6390054a27c3c3 /Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs | |
| parent | e3531534b85aeaaa3e4aaf462d5e77ea142dc762 (diff) | |
merge common implementations and server implementations
Diffstat (limited to 'Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs')
| -rw-r--r-- | Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs | 920 |
1 files changed, 920 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs new file mode 100644 index 000000000..c64d385f1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs @@ -0,0 +1,920 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Linq; +using System.Net; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; +using Extensions = SharpCifs.Util.Sharpen.Extensions; + +namespace SharpCifs.Netbios +{ + /// <summary>This class represents a NetBIOS over TCP/IP address.</summary> + /// <remarks> + /// This class represents a NetBIOS over TCP/IP address. Under normal + /// conditions, users of jCIFS need not be concerned with this class as + /// name resolution and session services are handled internally by the smb package. + /// <p> Applications can use the methods <code>getLocalHost</code>, + /// <code>getByName</code>, and + /// <code>getAllByAddress</code> to create a new NbtAddress instance. This + /// class is symmetric with + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// . + /// <p><b>About NetBIOS:</b> The NetBIOS name + /// service is a dynamic distributed service that allows hosts to resolve + /// names by broadcasting a query, directing queries to a server such as + /// Samba or WINS. NetBIOS is currently the primary networking layer for + /// providing name service, datagram service, and session service to the + /// Microsoft Windows platform. A NetBIOS name can be 15 characters long + /// and hosts usually registers several names on the network. From a + /// Windows command prompt you can see + /// what names a host registers with the nbtstat command. + /// <p><blockquote><pre> + /// C:\>nbtstat -a 192.168.1.15 + /// NetBIOS Remote Machine Name Table + /// Name Type Status + /// --------------------------------------------- + /// JMORRIS2 <00> UNIQUE Registered + /// BILLING-NY <00> GROUP Registered + /// JMORRIS2 <03> UNIQUE Registered + /// JMORRIS2 <20> UNIQUE Registered + /// BILLING-NY <1E> GROUP Registered + /// JMORRIS <03> UNIQUE Registered + /// MAC Address = 00-B0-34-21-FA-3B + /// </blockquote></pre> + /// <p> The hostname of this machine is <code>JMORRIS2</code>. It is + /// a member of the group(a.k.a workgroup and domain) <code>BILLING-NY</code>. To + /// obtain an + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// for a host one might do: + /// <pre> + /// InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress(); + /// </pre> + /// <p>From a UNIX platform with Samba installed you can perform similar + /// diagnostics using the <code>nmblookup</code> utility. + /// </remarks> + /// <author>Michael B. Allen</author> + /// <seealso cref="System.Net.IPAddress">System.Net.IPAddress</seealso> + /// <since>jcifs-0.1</since> + public sealed class NbtAddress + { + internal static readonly string AnyHostsName = "*\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"; + + /// <summary> + /// This is a special name for querying the master browser that serves the + /// list of hosts found in "Network Neighborhood". + /// </summary> + /// <remarks> + /// This is a special name for querying the master browser that serves the + /// list of hosts found in "Network Neighborhood". + /// </remarks> + public static readonly string MasterBrowserName = "\u0001\u0002__MSBROWSE__\u0002"; + + /// <summary> + /// A special generic name specified when connecting to a host for which + /// a name is not known. + /// </summary> + /// <remarks> + /// A special generic name specified when connecting to a host for which + /// a name is not known. Not all servers respond to this name. + /// </remarks> + public static readonly string SmbserverName = "*SMBSERVER "; + + /// <summary>A B node only broadcasts name queries.</summary> + /// <remarks> + /// A B node only broadcasts name queries. This is the default if a + /// nameserver such as WINS or Samba is not specified. + /// </remarks> + public const int BNode = 0; + + /// <summary> + /// A Point-to-Point node, or P node, unicasts queries to a nameserver + /// only. + /// </summary> + /// <remarks> + /// A Point-to-Point node, or P node, unicasts queries to a nameserver + /// only. Natrually the <code>jcifs.netbios.nameserver</code> property must + /// be set. + /// </remarks> + public const int PNode = 1; + + /// <summary> + /// Try Broadcast queries first, then try to resolve the name using the + /// nameserver. + /// </summary> + /// <remarks> + /// Try Broadcast queries first, then try to resolve the name using the + /// nameserver. + /// </remarks> + public const int MNode = 2; + + /// <summary>A Hybrid node tries to resolve a name using the nameserver first.</summary> + /// <remarks> + /// A Hybrid node tries to resolve a name using the nameserver first. If + /// that fails use the broadcast address. This is the default if a nameserver + /// is provided. This is the behavior of Microsoft Windows machines. + /// </remarks> + public const int HNode = 3; + + internal static readonly IPAddress[] Nbns = Config.GetInetAddressArray("jcifs.netbios.wins" + , ",", new IPAddress[0]); + + private static readonly NameServiceClient Client = new NameServiceClient(); + + private const int DefaultCachePolicy = 30; + + private static readonly int CachePolicy = Config.GetInt("jcifs.netbios.cachePolicy" + , DefaultCachePolicy); + + private const int Forever = -1; + + private static int _nbnsIndex; + + private static readonly Hashtable AddressCache = new Hashtable(); + + private static readonly Hashtable LookupTable = new Hashtable(); + + internal static readonly Name UnknownName = new Name("0.0.0.0", unchecked(0x00), null); + + internal static readonly NbtAddress UnknownAddress = new NbtAddress + (UnknownName, 0, false, BNode); + + internal static readonly byte[] UnknownMacAddress = { unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)) }; + + internal sealed class CacheEntry + { + internal Name HostName; + + internal NbtAddress Address; + + internal long Expiration; + + internal CacheEntry(Name hostName, NbtAddress address, long expiration) + { + this.HostName = hostName; + this.Address = address; + this.Expiration = expiration; + } + } + + internal static NbtAddress Localhost; + + static NbtAddress() + { + IPAddress localInetAddress; + string localHostname; + Name localName; + AddressCache.Put(UnknownName, new CacheEntry(UnknownName, UnknownAddress + , Forever)); + localInetAddress = Client.laddr; + if (localInetAddress == null) + { + try + { + localInetAddress = Extensions.GetAddressByName("127.0.0.1"); + } + catch (UnknownHostException) + { + + } + } + localHostname = Config.GetProperty("jcifs.netbios.hostname", null); + if (string.IsNullOrEmpty(localHostname)) + { + byte[] addr = localInetAddress.GetAddressBytes(); + + /*localHostname = "JCIFS" + (addr[2] & unchecked((int)(0xFF))) + "_" + (addr[3] & unchecked( + (int)(0xFF))) + "_" + Hexdump.ToHexString((int)(new Random().NextDouble() * (double)unchecked( + (int)(0xFF))), 2);*/ + localHostname = "JCIFS_127_0_0_1"; + } + localName = new Name(localHostname, unchecked(0x00), Config.GetProperty("jcifs.netbios.scope" + , null)); + Localhost = new NbtAddress(localName, localInetAddress.GetHashCode(), false, BNode + , false, false, true, false, UnknownMacAddress); + CacheAddress(localName, Localhost, Forever); + } + + internal static void CacheAddress(Name hostName, NbtAddress addr) + { + if (CachePolicy == 0) + { + return; + } + long expiration = -1; + if (CachePolicy != Forever) + { + expiration = Runtime.CurrentTimeMillis() + CachePolicy * 1000; + } + CacheAddress(hostName, addr, expiration); + } + + internal static void CacheAddress(Name hostName, NbtAddress addr, long expiration + ) + { + if (CachePolicy == 0) + { + return; + } + lock (AddressCache) + { + CacheEntry entry = (CacheEntry)AddressCache.Get(hostName); + if (entry == null) + { + entry = new CacheEntry(hostName, addr, expiration); + AddressCache.Put(hostName, entry); + } + else + { + entry.Address = addr; + entry.Expiration = expiration; + } + } + } + + internal static void CacheAddressArray(NbtAddress[] addrs) + { + if (CachePolicy == 0) + { + return; + } + long expiration = -1; + if (CachePolicy != Forever) + { + expiration = Runtime.CurrentTimeMillis() + CachePolicy * 1000; + } + lock (AddressCache) + { + for (int i = 0; i < addrs.Length; i++) + { + CacheEntry entry = (CacheEntry)AddressCache.Get(addrs[i].HostName + ); + if (entry == null) + { + entry = new CacheEntry(addrs[i].HostName, addrs[i], expiration); + AddressCache.Put(addrs[i].HostName, entry); + } + else + { + entry.Address = addrs[i]; + entry.Expiration = expiration; + } + } + } + } + + internal static NbtAddress GetCachedAddress(Name hostName) + { + if (CachePolicy == 0) + { + return null; + } + lock (AddressCache) + { + CacheEntry entry = (CacheEntry)AddressCache.Get(hostName); + if (entry != null && entry.Expiration < Runtime.CurrentTimeMillis() && entry.Expiration + >= 0) + { + entry = null; + } + return entry != null ? entry.Address : null; + } + } + + /// <exception cref="UnknownHostException"></exception> + internal static NbtAddress DoNameQuery(Name name, IPAddress svr) + { + NbtAddress addr; + if (name.HexCode == unchecked(0x1d) && svr == null) + { + svr = Client.Baddr; + } + // bit of a hack but saves a lookup + name.SrcHashCode = svr != null ? svr.GetHashCode() : 0; + addr = GetCachedAddress(name); + if (addr == null) + { + if ((addr = (NbtAddress)CheckLookupTable(name)) == null) + { + try + { + addr = Client.GetByName(name, svr); + } + catch (UnknownHostException) + { + addr = UnknownAddress; + } + finally + { + CacheAddress(name, addr); + UpdateLookupTable(name); + } + } + } + if (addr == UnknownAddress) + { + throw new UnknownHostException(name.ToString()); + } + return addr; + } + + private static object CheckLookupTable(Name name) + { + object obj; + lock (LookupTable) + { + if (LookupTable.ContainsKey(name) == false) + { + LookupTable.Put(name, name); + return null; + } + while (LookupTable.ContainsKey(name)) + { + try + { + Runtime.Wait(LookupTable); + } + catch (Exception) + { + } + } + } + obj = GetCachedAddress(name); + if (obj == null) + { + lock (LookupTable) + { + LookupTable.Put(name, name); + } + } + return obj; + } + + private static void UpdateLookupTable(Name name) + { + lock (LookupTable) + { + //Sharpen.Collections.Remove(LOOKUP_TABLE, name); + LookupTable.Remove(name); + Runtime.NotifyAll(LookupTable); + } + } + + /// <summary>Retrieves the local host address.</summary> + /// <remarks>Retrieves the local host address.</remarks> + /// <exception cref="UnknownHostException"> + /// This is not likely as the IP returned + /// by <code>InetAddress</code> should be available + /// </exception> + public static NbtAddress GetLocalHost() + { + return Localhost; + } + + public static NbtAddress[] GetHosts() + { + return new NameServiceClient().GetHosts(); + } + + public static Name GetLocalName() + { + return Localhost.HostName; + } + + /// <summary>Determines the address of a host given it's host name.</summary> + /// <remarks> + /// Determines the address of a host given it's host name. The name can be a NetBIOS name like + /// "freto" or an IP address like "192.168.1.15". It cannot be a DNS name; + /// the analygous + /// <see cref="SharpCifs.UniAddress">Jcifs.UniAddress</see> + /// or + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// <code>getByName</code> methods can be used for that. + /// </remarks> + /// <param name="host">hostname to resolve</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress GetByName(string host) + { + return GetByName(host, unchecked(0x00), null); + } + + /// <summary>Determines the address of a host given it's host name.</summary> + /// <remarks> + /// Determines the address of a host given it's host name. NetBIOS + /// names also have a <code>type</code>. Types(aka Hex Codes) + /// are used to distiquish the various services on a host. <a + /// href="../../../nbtcodes.html">Here</a> is + /// a fairly complete list of NetBIOS hex codes. Scope is not used but is + /// still functional in other NetBIOS products and so for completeness it has been + /// implemented. A <code>scope</code> of <code>null</code> or <code>""</code> + /// signifies no scope. + /// </remarks> + /// <param name="host">the name to resolve</param> + /// <param name="type">the hex code of the name</param> + /// <param name="scope">the scope of the name</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress GetByName(string host, int type, string scope) + { + return GetByName(host, type, scope, null); + } + + /// <exception cref="UnknownHostException"></exception> + public static NbtAddress GetByName(string host, int type, string scope, IPAddress + svr) + { + if (string.IsNullOrEmpty(host)) + { + return GetLocalHost(); + } + if (!char.IsDigit(host[0])) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + int ip = unchecked(0x00); + int hitDots = 0; + char[] data = host.ToCharArray(); + for (int i = 0; i < data.Length; i++) + { + char c = data[i]; + if (c < 48 || c > 57) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + int b = unchecked(0x00); + while (c != '.') + { + if (c < 48 || c > 57) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + b = b * 10 + c - '0'; + if (++i >= data.Length) + { + break; + } + c = data[i]; + } + if (b > unchecked(0xFF)) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + ip = (ip << 8) + b; + hitDots++; + } + if (hitDots != 4 || host.EndsWith(".")) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + return new NbtAddress(UnknownName, ip, false, BNode); + } + + /// <exception cref="UnknownHostException"></exception> + public static NbtAddress[] GetAllByName(string host, int type, string scope, IPAddress + svr) + { + return Client.GetAllByName(new Name(host, type, scope), svr); + } + + /// <summary>Retrieve all addresses of a host by it's address.</summary> + /// <remarks> + /// Retrieve all addresses of a host by it's address. NetBIOS hosts can + /// have many names for a given IP address. The name and IP address make the + /// NetBIOS address. This provides a way to retrieve the other names for a + /// host with the same IP address. + /// </remarks> + /// <param name="host">hostname to lookup all addresses for</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress[] GetAllByAddress(string host) + { + return GetAllByAddress(GetByName(host, unchecked(0x00), null)); + } + + /// <summary>Retrieve all addresses of a host by it's address.</summary> + /// <remarks> + /// Retrieve all addresses of a host by it's address. NetBIOS hosts can + /// have many names for a given IP address. The name and IP address make + /// the NetBIOS address. This provides a way to retrieve the other names + /// for a host with the same IP address. See + /// <see cref="GetByName(string)">GetByName(string)</see> + /// for a description of <code>type</code> + /// and <code>scope</code>. + /// </remarks> + /// <param name="host">hostname to lookup all addresses for</param> + /// <param name="type">the hexcode of the name</param> + /// <param name="scope">the scope of the name</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress[] GetAllByAddress(string host, int type, string scope) + { + return GetAllByAddress(GetByName(host, type, scope)); + } + + /// <summary>Retrieve all addresses of a host by it's address.</summary> + /// <remarks> + /// Retrieve all addresses of a host by it's address. NetBIOS hosts can + /// have many names for a given IP address. The name and IP address make the + /// NetBIOS address. This provides a way to retrieve the other names for a + /// host with the same IP address. + /// </remarks> + /// <param name="addr">the address to query</param> + /// <exception cref="UnknownHostException">if address cannot be resolved</exception> + public static NbtAddress[] GetAllByAddress(NbtAddress addr) + { + try + { + NbtAddress[] addrs = Client.GetNodeStatus(addr); + CacheAddressArray(addrs); + return addrs; + } + catch (UnknownHostException) + { + throw new UnknownHostException("no name with type 0x" + Hexdump.ToHexString(addr. + HostName.HexCode, 2) + (((addr.HostName.Scope == null) || (addr.HostName.Scope.Length + == 0)) ? " with no scope" : " with scope " + addr.HostName.Scope) + " for host " + + addr.GetHostAddress()); + } + } + + public static IPAddress GetWinsAddress() + { + return Nbns.Length == 0 ? null : Nbns[_nbnsIndex]; + } + + public static bool IsWins(IPAddress svr) + { + for (int i = 0; svr != null && i < Nbns.Length; i++) + { + if (svr.GetHashCode() == Nbns[i].GetHashCode()) + { + return true; + } + } + return false; + } + + internal static IPAddress SwitchWins() + { + _nbnsIndex = (_nbnsIndex + 1) < Nbns.Length ? _nbnsIndex + 1 : 0; + return Nbns.Length == 0 ? null : Nbns[_nbnsIndex]; + } + + internal Name HostName; + + internal int Address; + + internal int NodeType; + + internal bool GroupName; + + internal bool isBeingDeleted; + + internal bool isInConflict; + + internal bool isActive; + + internal bool isPermanent; + + internal bool IsDataFromNodeStatus; + + internal byte[] MacAddress; + + internal string CalledName; + + internal NbtAddress(Name hostName, int address, bool groupName, int nodeType) + { + this.HostName = hostName; + this.Address = address; + this.GroupName = groupName; + this.NodeType = nodeType; + } + + internal NbtAddress(Name hostName, int address, bool groupName, int nodeType, bool + isBeingDeleted, bool isInConflict, bool isActive, bool isPermanent, byte[] macAddress + ) + { + this.HostName = hostName; + this.Address = address; + this.GroupName = groupName; + this.NodeType = nodeType; + this.isBeingDeleted = isBeingDeleted; + this.isInConflict = isInConflict; + this.isActive = isActive; + this.isPermanent = isPermanent; + this.MacAddress = macAddress; + IsDataFromNodeStatus = true; + } + + public string FirstCalledName() + { + CalledName = HostName.name; + if (char.IsDigit(CalledName[0])) + { + int i; + int len; + int dots; + char[] data; + i = dots = 0; + len = CalledName.Length; + data = CalledName.ToCharArray(); + while (i < len && char.IsDigit(data[i++])) + { + if (i == len && dots == 3) + { + // probably an IP address + CalledName = SmbserverName; + break; + } + if (i < len && data[i] == '.') + { + dots++; + i++; + } + } + } + else + { + switch (HostName.HexCode) + { + case unchecked(0x1B): + case unchecked(0x1C): + case unchecked(0x1D): + { + CalledName = SmbserverName; + break; + } + } + } + return CalledName; + } + + public string NextCalledName() + { + if (CalledName == HostName.name) + { + CalledName = SmbserverName; + } + else + { + if (CalledName == SmbserverName) + { + NbtAddress[] addrs; + try + { + addrs = Client.GetNodeStatus(this); + if (HostName.HexCode == unchecked(0x1D)) + { + for (int i = 0; i < addrs.Length; i++) + { + if (addrs[i].HostName.HexCode == unchecked(0x20)) + { + return addrs[i].HostName.name; + } + } + return null; + } + if (IsDataFromNodeStatus) + { + CalledName = null; + return HostName.name; + } + } + catch (UnknownHostException) + { + CalledName = null; + } + } + else + { + CalledName = null; + } + } + return CalledName; + } + + /// <exception cref="UnknownHostException"></exception> + internal void CheckData() + { + if (HostName == UnknownName) + { + GetAllByAddress(this); + } + } + + /// <exception cref="UnknownHostException"></exception> + internal void CheckNodeStatusData() + { + if (IsDataFromNodeStatus == false) + { + GetAllByAddress(this); + } + } + + /// <summary>Determines if the address is a group address.</summary> + /// <remarks> + /// Determines if the address is a group address. This is also + /// known as a workgroup name or group name. + /// </remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsGroupAddress() + { + CheckData(); + return GroupName; + } + + /// <summary>Checks the node type of this address.</summary> + /// <remarks>Checks the node type of this address.</remarks> + /// <returns> + /// + /// <see cref="BNode">B_NODE</see> + /// , + /// <see cref="PNode">P_NODE</see> + /// , + /// <see cref="MNode">M_NODE</see> + /// , + /// <see cref="HNode">H_NODE</see> + /// </returns> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public int GetNodeType() + { + CheckData(); + return NodeType; + } + + /// <summary>Determines if this address in the process of being deleted.</summary> + /// <remarks>Determines if this address in the process of being deleted.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsBeingDeleted() + { + CheckNodeStatusData(); + return isBeingDeleted; + } + + /// <summary>Determines if this address in conflict with another address.</summary> + /// <remarks>Determines if this address in conflict with another address.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsInConflict() + { + CheckNodeStatusData(); + return isInConflict; + } + + /// <summary>Determines if this address is active.</summary> + /// <remarks>Determines if this address is active.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsActive() + { + CheckNodeStatusData(); + return isActive; + } + + /// <summary>Determines if this address is set to be permanent.</summary> + /// <remarks>Determines if this address is set to be permanent.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsPermanent() + { + CheckNodeStatusData(); + return isPermanent; + } + + /// <summary>Retrieves the MAC address of the remote network interface.</summary> + /// <remarks>Retrieves the MAC address of the remote network interface. Samba returns all zeros. + /// </remarks> + /// <returns>the MAC address as an array of six bytes</returns> + /// <exception cref="UnknownHostException"> + /// if the host cannot be resolved to + /// determine the MAC address. + /// </exception> + public byte[] GetMacAddress() + { + CheckNodeStatusData(); + return MacAddress; + } + + /// <summary>The hostname of this address.</summary> + /// <remarks> + /// The hostname of this address. If the hostname is null the local machines + /// IP address is returned. + /// </remarks> + /// <returns>the text representation of the hostname associated with this address</returns> + public string GetHostName() + { + if (HostName == UnknownName) + { + return GetHostAddress(); + } + return HostName.name; + } + + /// <summary>Returns the raw IP address of this NbtAddress.</summary> + /// <remarks> + /// Returns the raw IP address of this NbtAddress. The result is in network + /// byte order: the highest order byte of the address is in getAddress()[0]. + /// </remarks> + /// <returns>a four byte array</returns> + public byte[] GetAddress() + { + byte[] addr = new byte[4]; + addr[0] = unchecked((byte)(((int)(((uint)Address) >> 24)) & unchecked(0xFF + ))); + addr[1] = unchecked((byte)(((int)(((uint)Address) >> 16)) & unchecked(0xFF + ))); + addr[2] = unchecked((byte)(((int)(((uint)Address) >> 8)) & unchecked(0xFF) + )); + addr[3] = unchecked((byte)(Address & unchecked(0xFF))); + return addr; + } + + /// <summary>To convert this address to an <code>InetAddress</code>.</summary> + /// <remarks>To convert this address to an <code>InetAddress</code>.</remarks> + /// <returns> + /// the + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// representation of this address. + /// </returns> + /// <exception cref="UnknownHostException"></exception> + public IPAddress GetInetAddress() + { + return Extensions.GetAddressByName(GetHostAddress()); + } + + /// <summary> + /// Returns this IP adress as a + /// <see cref="string">string</see> + /// in the form "%d.%d.%d.%d". + /// </summary> + public string GetHostAddress() + { + return (((int)(((uint)Address) >> 24)) & unchecked(0xFF)) + "." + (((int)( + ((uint)Address) >> 16)) & unchecked(0xFF)) + "." + (((int)(((uint)Address + ) >> 8)) & unchecked(0xFF)) + "." + (((int)(((uint)Address) >> 0)) & unchecked( + 0xFF)); + } + + /// <summary>Returned the hex code associated with this name(e.g.</summary> + /// <remarks>Returned the hex code associated with this name(e.g. 0x20 is for the file service) + /// </remarks> + public int GetNameType() + { + return HostName.HexCode; + } + + /// <summary>Returns a hashcode for this IP address.</summary> + /// <remarks> + /// Returns a hashcode for this IP address. The hashcode comes from the IP address + /// and is not generated from the string representation. So because NetBIOS nodes + /// can have many names, all names associated with an IP will have the same + /// hashcode. + /// </remarks> + public override int GetHashCode() + { + return Address; + } + + /// <summary>Determines if this address is equal two another.</summary> + /// <remarks> + /// Determines if this address is equal two another. Only the IP Addresses + /// are compared. Similar to the + /// <see cref="GetHashCode()">GetHashCode()</see> + /// method, the comparison + /// is based on the integer IP address and not the string representation. + /// </remarks> + public override bool Equals(object obj) + { + return (obj != null) && (obj is NbtAddress) && (((NbtAddress)obj).Address == Address + ); + } + + /// <summary> + /// Returns the + /// <see cref="string">string</see> + /// representaion of this address. + /// </summary> + public override string ToString() + { + return HostName + "/" + GetHostAddress(); + } + } +} |
