mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 10:37:22 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			592 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			592 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // 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.IO;
 | |
| using System.Linq;
 | |
| using System.Net;
 | |
| using SharpCifs.Netbios;
 | |
| using SharpCifs.Util;
 | |
| using SharpCifs.Util.Sharpen;
 | |
| using Extensions = SharpCifs.Util.Sharpen.Extensions;
 | |
| 
 | |
| namespace SharpCifs
 | |
| {
 | |
| 	/// <summary>
 | |
| 	/// <p>Under normal conditions it is not necessary to use
 | |
| 	/// this class to use jCIFS properly.
 | |
| 	/// </summary>
 | |
| 	/// <remarks>
 | |
| 	/// <p>Under normal conditions it is not necessary to use
 | |
| 	/// this class to use jCIFS properly. Name resolusion is
 | |
| 	/// handled internally to the <code>jcifs.smb</code> package.
 | |
| 	/// <p>
 | |
| 	/// This class is a wrapper for both
 | |
| 	/// <see cref="Jcifs.Netbios.NbtAddress">Jcifs.Netbios.NbtAddress</see>
 | |
| 	/// and
 | |
| 	/// <see cref="System.Net.IPAddress">System.Net.IPAddress</see>
 | |
| 	/// . The name resolution mechanisms
 | |
| 	/// used will systematically query all available configured resolution
 | |
| 	/// services including WINS, broadcasts, DNS, and LMHOSTS. See
 | |
| 	/// <a href="../../resolver.html">Setting Name Resolution Properties</a>
 | |
| 	/// and the <code>jcifs.resolveOrder</code> property. Changing
 | |
| 	/// jCIFS name resolution properties can greatly affect the behavior of
 | |
| 	/// the client and may be necessary for proper operation.
 | |
| 	/// <p>
 | |
| 	/// This class should be used in favor of <tt>InetAddress</tt> to resolve
 | |
| 	/// hostnames on LANs and WANs that support a mixture of NetBIOS/WINS and
 | |
| 	/// DNS resolvable hosts.
 | |
| 	/// </remarks>
 | |
| 	public class UniAddress
 | |
| 	{
 | |
| 		private const int ResolverWins = 0;
 | |
| 
 | |
| 		private const int ResolverBcast = 1;
 | |
| 
 | |
| 		private const int ResolverDns = 2;
 | |
| 
 | |
| 		private const int ResolverLmhosts = 3;
 | |
| 
 | |
| 		private static int[] _resolveOrder;
 | |
| 
 | |
| 		private static IPAddress _baddr;
 | |
| 
 | |
| 		private static LogStream _log = LogStream.GetInstance();
 | |
| 
 | |
| 		static UniAddress()
 | |
| 		{
 | |
| 			string ro = Config.GetProperty("jcifs.resolveOrder");
 | |
| 			IPAddress nbns = NbtAddress.GetWinsAddress();
 | |
| 			try
 | |
| 			{
 | |
| 				_baddr = Config.GetInetAddress("jcifs.netbios.baddr", Extensions.GetAddressByName
 | |
| 					("255.255.255.255"));
 | |
| 			}
 | |
| 			catch (UnknownHostException)
 | |
| 			{
 | |
| 			}
 | |
| 			if (string.IsNullOrEmpty(ro))
 | |
| 			{
 | |
| 				if (nbns == null)
 | |
| 				{
 | |
| 					_resolveOrder = new int[3];
 | |
| 					_resolveOrder[0] = ResolverLmhosts;
 | |
| 					_resolveOrder[1] = ResolverDns;
 | |
| 					_resolveOrder[2] = ResolverBcast;
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					_resolveOrder = new int[4];
 | |
| 					_resolveOrder[0] = ResolverLmhosts;
 | |
| 					_resolveOrder[1] = ResolverWins;
 | |
| 					_resolveOrder[2] = ResolverDns;
 | |
| 					_resolveOrder[3] = ResolverBcast;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				int[] tmp = new int[4];
 | |
| 				StringTokenizer st = new StringTokenizer(ro, ",");
 | |
| 				int i = 0;
 | |
| 				while (st.HasMoreTokens())
 | |
| 				{
 | |
| 					string s = st.NextToken().Trim();
 | |
| 					if (Runtime.EqualsIgnoreCase(s, "LMHOSTS"))
 | |
| 					{
 | |
| 						tmp[i++] = ResolverLmhosts;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						if (Runtime.EqualsIgnoreCase(s, "WINS"))
 | |
| 						{
 | |
| 							if (nbns == null)
 | |
| 							{
 | |
| 								if (_log.Level > 1)
 | |
| 								{
 | |
| 									_log.WriteLine("UniAddress resolveOrder specifies WINS however the " + "jcifs.netbios.wins property has not been set"
 | |
| 										);
 | |
| 								}
 | |
| 								continue;
 | |
| 							}
 | |
| 							tmp[i++] = ResolverWins;
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							if (Runtime.EqualsIgnoreCase(s, "BCAST"))
 | |
| 							{
 | |
| 								tmp[i++] = ResolverBcast;
 | |
| 							}
 | |
| 							else
 | |
| 							{
 | |
| 								if (Runtime.EqualsIgnoreCase(s, "DNS"))
 | |
| 								{
 | |
| 									tmp[i++] = ResolverDns;
 | |
| 								}
 | |
| 								else
 | |
| 								{
 | |
| 									if (_log.Level > 1)
 | |
| 									{
 | |
| 										_log.WriteLine("unknown resolver method: " + s);
 | |
| 									}
 | |
| 								}
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				_resolveOrder = new int[i];
 | |
| 				Array.Copy(tmp, 0, _resolveOrder, 0, i);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		internal class Sem
 | |
| 		{
 | |
| 			internal Sem(int count)
 | |
| 			{
 | |
| 				this.Count = count;
 | |
| 			}
 | |
| 
 | |
| 			internal int Count;
 | |
| 		}
 | |
| 
 | |
| 		internal class QueryThread : Thread
 | |
| 		{
 | |
| 			internal Sem Sem;
 | |
| 
 | |
| 			internal string Host;
 | |
| 
 | |
| 			internal string Scope;
 | |
| 
 | |
| 			internal int Type;
 | |
| 
 | |
| 			internal NbtAddress[] Ans;
 | |
| 
 | |
| 			internal IPAddress Svr;
 | |
| 
 | |
| 			internal UnknownHostException Uhe;
 | |
| 
 | |
| 			internal QueryThread(Sem sem, string host, int type, string scope, IPAddress
 | |
| 				 svr) : base("JCIFS-QueryThread: " + host)
 | |
| 			{
 | |
| 				this.Sem = sem;
 | |
| 				this.Host = host;
 | |
| 				this.Type = type;
 | |
| 				this.Scope = scope;
 | |
| 				this.Svr = svr;
 | |
| 			}
 | |
| 
 | |
| 			public override void Run()
 | |
| 			{
 | |
| 				try
 | |
| 				{
 | |
| 				    //Ans = new [] { NbtAddress.GetByName(Host, Type, Scope, Svr) };
 | |
| 				    Ans = NbtAddress.GetAllByName(Host, Type, Scope, Svr);
 | |
| 				}
 | |
| 				catch (UnknownHostException uhe)
 | |
| 				{
 | |
| 					this.Uhe = uhe;
 | |
| 				}
 | |
| 				catch (Exception ex)
 | |
| 				{
 | |
| 					Uhe = new UnknownHostException(ex.Message);
 | |
| 				}
 | |
| 				finally
 | |
| 				{
 | |
| 					lock (Sem)
 | |
| 					{
 | |
| 						Sem.Count--;
 | |
| 						Runtime.Notify(Sem);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <exception cref="UnknownHostException"></exception>
 | |
| 		internal static NbtAddress[] LookupServerOrWorkgroup(string name, IPAddress svr)
 | |
| 		{
 | |
| 			Sem sem = new Sem(2);
 | |
| 			int type = NbtAddress.IsWins(svr) ? unchecked(0x1b) : unchecked(0x1d);
 | |
| 			QueryThread q1X = new QueryThread(sem, name, type, null, svr
 | |
| 				);
 | |
| 			QueryThread q20 = new QueryThread(sem, name, unchecked(0x20), null, svr);
 | |
| 			q1X.SetDaemon(true);
 | |
| 			q20.SetDaemon(true);
 | |
| 			try
 | |
| 			{
 | |
| 				lock (sem)
 | |
| 				{
 | |
| 					q1X.Start();
 | |
| 					q20.Start();
 | |
| 					while (sem.Count > 0 && q1X.Ans == null && q20.Ans == null)
 | |
| 					{
 | |
| 						Runtime.Wait(sem);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			catch (Exception)
 | |
| 			{
 | |
| 				throw new UnknownHostException(name);
 | |
| 			}
 | |
| 			if (q1X.Ans != null)
 | |
| 			{
 | |
| 				return q1X.Ans;
 | |
| 			}
 | |
| 		    if (q20.Ans != null)
 | |
| 		    {
 | |
| 		        return q20.Ans;
 | |
| 		    }
 | |
| 		    throw q1X.Uhe;
 | |
| 		}
 | |
| 
 | |
| 		/// <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
 | |
| 		/// machine name like "jcifs.samba.org",  or an IP address like "192.168.1.15".
 | |
| 		/// </remarks>
 | |
| 		/// <param name="hostname">NetBIOS or DNS hostname to resolve</param>
 | |
| 		/// <exception cref="UnknownHostException">if there is an error resolving the name
 | |
| 		/// 	</exception>
 | |
| 		public static UniAddress GetByName(string hostname)
 | |
| 		{
 | |
| 			return GetByName(hostname, false);
 | |
| 		}
 | |
| 
 | |
| 		internal static bool IsDotQuadIp(string hostname)
 | |
| 		{
 | |
| 			if (char.IsDigit(hostname[0]))
 | |
| 			{
 | |
| 				int i;
 | |
| 				int len;
 | |
| 				int dots;
 | |
| 				char[] data;
 | |
| 				i = dots = 0;
 | |
| 				len = hostname.Length;
 | |
| 				data = hostname.ToCharArray();
 | |
| 				while (i < len && char.IsDigit(data[i++]))
 | |
| 				{
 | |
| 					if (i == len && dots == 3)
 | |
| 					{
 | |
| 						// probably an IP address
 | |
| 						return true;
 | |
| 					}
 | |
| 					if (i < len && data[i] == '.')
 | |
| 					{
 | |
| 						dots++;
 | |
| 						i++;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		internal static bool IsAllDigits(string hostname)
 | |
| 		{
 | |
| 			for (int i = 0; i < hostname.Length; i++)
 | |
| 			{
 | |
| 				if (char.IsDigit(hostname[i]) == false)
 | |
| 				{
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Lookup <tt>hostname</tt> and return it's <tt>UniAddress</tt>.</summary>
 | |
| 		/// <remarks>
 | |
| 		/// Lookup <tt>hostname</tt> and return it's <tt>UniAddress</tt>. If the
 | |
| 		/// <tt>possibleNTDomainOrWorkgroup</tt> parameter is <tt>true</tt> an
 | |
| 		/// addtional name query will be performed to locate a master browser.
 | |
| 		/// </remarks>
 | |
| 		/// <exception cref="UnknownHostException"></exception>
 | |
| 		public static UniAddress GetByName(string hostname, bool possibleNtDomainOrWorkgroup
 | |
| 			)
 | |
| 		{
 | |
| 			UniAddress[] addrs = GetAllByName(hostname, possibleNtDomainOrWorkgroup
 | |
| 				);
 | |
| 			return addrs[0];
 | |
| 		}
 | |
| 
 | |
| 		/// <exception cref="UnknownHostException"></exception>
 | |
| 		public static UniAddress[] GetAllByName(string hostname, bool possibleNtDomainOrWorkgroup
 | |
| 			)
 | |
| 		{
 | |
| 			object addr;
 | |
| 			int i;
 | |
| 			if (string.IsNullOrEmpty(hostname))
 | |
| 			{
 | |
| 				throw new UnknownHostException();
 | |
| 			}
 | |
| 			if (IsDotQuadIp(hostname))
 | |
| 			{
 | |
| 				UniAddress[] addrs = new UniAddress[1];
 | |
| 				addrs[0] = new UniAddress(NbtAddress.GetByName(hostname));
 | |
| 				return addrs;
 | |
| 			}
 | |
| 			for (i = 0; i < _resolveOrder.Length; i++)
 | |
| 			{
 | |
| 				try
 | |
| 				{
 | |
| 					switch (_resolveOrder[i])
 | |
| 					{
 | |
| 						case ResolverLmhosts:
 | |
| 						{
 | |
| 							if ((addr = Lmhosts.GetByName(hostname)) == null)
 | |
| 							{
 | |
| 								continue;
 | |
| 							}
 | |
| 							break;
 | |
| 						}
 | |
| 
 | |
| 						case ResolverWins:
 | |
| 						{
 | |
| 							if (hostname == NbtAddress.MasterBrowserName || hostname.Length > 15)
 | |
| 							{
 | |
| 								// invalid netbios name
 | |
| 								continue;
 | |
| 							}
 | |
| 							if (possibleNtDomainOrWorkgroup)
 | |
| 							{
 | |
| 								addr = LookupServerOrWorkgroup(hostname, NbtAddress.GetWinsAddress());
 | |
| 							}
 | |
| 							else
 | |
| 							{
 | |
| 								addr = NbtAddress.GetByName(hostname, unchecked(0x20), null, NbtAddress.GetWinsAddress
 | |
| 									());
 | |
| 							}
 | |
| 							break;
 | |
| 						}
 | |
| 
 | |
| 						case ResolverBcast:
 | |
| 						{
 | |
| 							if (hostname.Length > 15)
 | |
| 							{
 | |
| 								// invalid netbios name
 | |
| 								continue;
 | |
| 							}
 | |
| 
 | |
| 						    try
 | |
| 						    {
 | |
|                                 if (possibleNtDomainOrWorkgroup)
 | |
|                                 {
 | |
|                                     NbtAddress[] iaddrs = LookupServerOrWorkgroup(hostname, _baddr);
 | |
| 
 | |
|                                     UniAddress[] addrs = new UniAddress[iaddrs.Length];
 | |
|                                     for (int ii = 0; ii < iaddrs.Length; ii++)
 | |
|                                     {
 | |
|                                         addrs[ii] = new UniAddress(iaddrs[ii]);
 | |
|                                     }
 | |
|                                     return addrs;
 | |
| 
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     addr = NbtAddress.GetByName(hostname, unchecked(0x20), null, _baddr);
 | |
|                                 }
 | |
| 
 | |
| 						    }
 | |
| 						    catch (Exception ex)
 | |
| 						    {
 | |
| 						        if (i == _resolveOrder.Length - 1)
 | |
| 						        {
 | |
| 						            throw ex;
 | |
| 						        }
 | |
| 						        else
 | |
| 						        {
 | |
| 						            continue;
 | |
| 						        }
 | |
| 						    }
 | |
| 							break;
 | |
| 						}
 | |
| 
 | |
| 						case ResolverDns:
 | |
| 						{
 | |
| 							if (IsAllDigits(hostname))
 | |
| 							{
 | |
| 								throw new UnknownHostException(hostname);
 | |
| 							}
 | |
| 
 | |
|                             IPAddress[] iaddrs = Extensions.GetAddressesByName(hostname);
 | |
| 
 | |
|                             if (iaddrs == null || iaddrs.Length == 0)
 | |
|                             {
 | |
|                                 continue;
 | |
|                             }
 | |
| 
 | |
|                             return iaddrs.Select(iaddr => new UniAddress(iaddr)).ToArray();                            
 | |
| 						}
 | |
| 
 | |
| 						default:
 | |
| 						{
 | |
| 							// Success
 | |
| 							throw new UnknownHostException(hostname);
 | |
| 						}
 | |
| 					}
 | |
| 					UniAddress[] addrs1 = new UniAddress[1];
 | |
| 					addrs1[0] = new UniAddress(addr);
 | |
| 					return addrs1;
 | |
| 				}
 | |
| 				catch (IOException)
 | |
| 				{
 | |
| 				}
 | |
| 			}
 | |
| 			// Success
 | |
| 			// Failure
 | |
| 			throw new UnknownHostException(hostname);
 | |
| 		}
 | |
| 
 | |
| 		internal object Addr;
 | |
| 
 | |
| 		internal string CalledName;
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Create a <tt>UniAddress</tt> by wrapping an <tt>InetAddress</tt> or
 | |
| 		/// <tt>NbtAddress</tt>.
 | |
| 		/// </summary>
 | |
| 		/// <remarks>
 | |
| 		/// Create a <tt>UniAddress</tt> by wrapping an <tt>InetAddress</tt> or
 | |
| 		/// <tt>NbtAddress</tt>.
 | |
| 		/// </remarks>
 | |
| 		public UniAddress(object addr)
 | |
| 		{
 | |
| 			if (addr == null)
 | |
| 			{
 | |
| 				throw new ArgumentException();
 | |
| 			}
 | |
| 			this.Addr = addr;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Return the IP address of this address as a 32 bit integer.</summary>
 | |
| 		/// <remarks>Return the IP address of this address as a 32 bit integer.</remarks>
 | |
| 		public override int GetHashCode()
 | |
| 		{
 | |
| 			return Addr.GetHashCode();
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Compare two addresses for equality.</summary>
 | |
| 		/// <remarks>
 | |
| 		/// Compare two addresses for equality. Two <tt>UniAddress</tt>s are equal
 | |
| 		/// if they are both <tt>UniAddress</tt>' and refer to the same IP address.
 | |
| 		/// </remarks>
 | |
| 		public override bool Equals(object obj)
 | |
| 		{
 | |
| 			return obj is UniAddress && Addr.Equals(((UniAddress)obj).Addr);
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Guess first called name to try for session establishment.</summary>
 | |
| 		/// <remarks>
 | |
| 		/// Guess first called name to try for session establishment. This
 | |
| 		/// method is used exclusively by the <tt>jcifs.smb</tt> package.
 | |
| 		/// </remarks>
 | |
| 		public virtual string FirstCalledName()
 | |
| 		{
 | |
| 			if (Addr is NbtAddress)
 | |
| 			{
 | |
| 				return ((NbtAddress)Addr).FirstCalledName();
 | |
| 			}
 | |
| 		    CalledName = ((IPAddress) Addr).GetHostAddress();
 | |
| 		    if (IsDotQuadIp(CalledName))
 | |
| 		    {
 | |
| 		        CalledName = NbtAddress.SmbserverName;
 | |
| 		    }
 | |
| 		    else
 | |
| 		    {
 | |
| 		        int i = CalledName.IndexOf('.');
 | |
| 		        if (i > 1 && i < 15)
 | |
| 		        {
 | |
| 		            CalledName = Runtime.Substring(CalledName, 0, i).ToUpper();
 | |
| 		        }
 | |
| 		        else
 | |
| 		        {
 | |
| 		            if (CalledName.Length > 15)
 | |
| 		            {
 | |
| 		                CalledName = NbtAddress.SmbserverName;
 | |
| 		            }
 | |
| 		            else
 | |
| 		            {
 | |
| 		                CalledName = CalledName.ToUpper();
 | |
| 		            }
 | |
| 		        }
 | |
| 		    }
 | |
| 		    return CalledName;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Guess next called name to try for session establishment.</summary>
 | |
| 		/// <remarks>
 | |
| 		/// Guess next called name to try for session establishment. This
 | |
| 		/// method is used exclusively by the <tt>jcifs.smb</tt> package.
 | |
| 		/// </remarks>
 | |
| 		public virtual string NextCalledName()
 | |
| 		{
 | |
| 			if (Addr is NbtAddress)
 | |
| 			{
 | |
| 				return ((NbtAddress)Addr).NextCalledName();
 | |
| 			}
 | |
| 		    if (CalledName != NbtAddress.SmbserverName)
 | |
| 		    {
 | |
| 		        CalledName = NbtAddress.SmbserverName;
 | |
| 		        return CalledName;
 | |
| 		    }
 | |
| 		    return null;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Return the underlying <tt>NbtAddress</tt> or <tt>InetAddress</tt>.</summary>
 | |
| 		/// <remarks>Return the underlying <tt>NbtAddress</tt> or <tt>InetAddress</tt>.</remarks>
 | |
| 		public virtual object GetAddress()
 | |
| 		{
 | |
| 			return Addr;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Return the hostname of this address such as "MYCOMPUTER".</summary>
 | |
| 		/// <remarks>Return the hostname of this address such as "MYCOMPUTER".</remarks>
 | |
| 		public virtual string GetHostName()
 | |
| 		{
 | |
| 			if (Addr is NbtAddress)
 | |
| 			{
 | |
| 				return ((NbtAddress)Addr).GetHostName();
 | |
| 			}
 | |
| 		    return ((IPAddress) Addr).GetHostAddress();
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>Return the IP address as text such as "192.168.1.15".</summary>
 | |
| 		/// <remarks>Return the IP address as text such as "192.168.1.15".</remarks>
 | |
| 		public virtual string GetHostAddress()
 | |
| 		{
 | |
| 			if (Addr is NbtAddress)
 | |
| 			{
 | |
| 				return ((NbtAddress)Addr).GetHostAddress();
 | |
| 			}
 | |
| 			return ((IPAddress)Addr).GetHostAddress();
 | |
| 		}
 | |
| 
 | |
| 	    public virtual IPAddress GetHostIpAddress()
 | |
| 	    {
 | |
| 	        return (IPAddress) Addr;
 | |
| 	    }
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Return the a text representation of this address such as
 | |
| 		/// <tt>MYCOMPUTER/192.168.1.15</tt>.
 | |
| 		/// </summary>
 | |
| 		/// <remarks>
 | |
| 		/// Return the a text representation of this address such as
 | |
| 		/// <tt>MYCOMPUTER/192.168.1.15</tt>.
 | |
| 		/// </remarks>
 | |
| 		public override string ToString()
 | |
| 		{
 | |
| 			return Addr.ToString();
 | |
| 		}
 | |
| 	}
 | |
| }
 |