aboutsummaryrefslogtreecommitdiff
path: root/Emby.Common.Implementations/IO/SharpCifs/Netbios
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Common.Implementations/IO/SharpCifs/Netbios')
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs337
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/Name.cs419
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs56
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs87
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs318
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs807
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs1828
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtException.cs285
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs70
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs232
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs71
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs55
-rw-r--r--Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs266
13 files changed, 2548 insertions, 2283 deletions
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs
index c94d0a260..7d8dd8bbf 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs
@@ -21,182 +21,181 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- public class Lmhosts
- {
- private static readonly string Filename = Config.GetProperty("jcifs.netbios.lmhosts"
- );
+ public class Lmhosts
+ {
+ private static readonly string Filename = Config.GetProperty("jcifs.netbios.lmhosts");
- private static readonly Hashtable Tab = new Hashtable();
+ private static readonly Hashtable Tab = new Hashtable();
- private static long _lastModified = 1L;
+ private static long _lastModified = 1L;
- private static int _alt;
+ private static int _alt;
- private static LogStream _log = LogStream.GetInstance();
+ private static LogStream _log = LogStream.GetInstance();
- /// <summary>
- /// This is really just for
- /// <see cref="SharpCifs.UniAddress">Jcifs.UniAddress</see>
- /// . It does
- /// not throw an
- /// <see cref="UnknownHostException">Sharpen.UnknownHostException</see>
- /// because this
- /// is queried frequently and exceptions would be rather costly to
- /// throw on a regular basis here.
- /// </summary>
- public static NbtAddress GetByName(string host)
- {
- lock (typeof(Lmhosts))
- {
- return GetByName(new Name(host, 0x20, null));
- }
- }
+ /// <summary>
+ /// This is really just for
+ /// <see cref="SharpCifs.UniAddress">Jcifs.UniAddress</see>
+ /// . It does
+ /// not throw an
+ /// <see cref="UnknownHostException">Sharpen.UnknownHostException</see>
+ /// because this
+ /// is queried frequently and exceptions would be rather costly to
+ /// throw on a regular basis here.
+ /// </summary>
+ public static NbtAddress GetByName(string host)
+ {
+ lock (typeof(Lmhosts))
+ {
+ return GetByName(new Name(host, 0x20, null));
+ }
+ }
- internal static NbtAddress GetByName(Name name)
- {
- lock (typeof(Lmhosts))
- {
- NbtAddress result = null;
- try
- {
- if (Filename != null)
- {
- FilePath f = new FilePath(Filename);
- long lm;
- if ((lm = f.LastModified()) > _lastModified)
- {
- _lastModified = lm;
- Tab.Clear();
- _alt = 0;
-
- //path -> fileStream
- //Populate(new FileReader(f));
+ internal static NbtAddress GetByName(Name name)
+ {
+ lock (typeof(Lmhosts))
+ {
+ NbtAddress result = null;
+ try
+ {
+ if (Filename != null)
+ {
+ FilePath f = new FilePath(Filename);
+ long lm;
+ if ((lm = f.LastModified()) > _lastModified)
+ {
+ _lastModified = lm;
+ Tab.Clear();
+ _alt = 0;
+
+ //path -> fileStream
+ //Populate(new FileReader(f));
Populate(new FileReader(new FileStream(f, FileMode.Open)));
- }
- result = (NbtAddress)Tab[name];
- }
- }
- catch (FileNotFoundException fnfe)
- {
- if (_log.Level > 1)
- {
- _log.WriteLine("lmhosts file: " + Filename);
- Runtime.PrintStackTrace(fnfe, _log);
- }
- }
- catch (IOException ioe)
- {
- if (_log.Level > 0)
- {
- Runtime.PrintStackTrace(ioe, _log);
- }
- }
- return result;
- }
- }
+ }
+ result = (NbtAddress)Tab[name];
+ }
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ if (_log.Level > 1)
+ {
+ _log.WriteLine("lmhosts file: " + Filename);
+ Runtime.PrintStackTrace(fnfe, _log);
+ }
+ }
+ catch (IOException ioe)
+ {
+ if (_log.Level > 0)
+ {
+ Runtime.PrintStackTrace(ioe, _log);
+ }
+ }
+ return result;
+ }
+ }
- /// <exception cref="System.IO.IOException"></exception>
- internal static void Populate(StreamReader r)
- {
- string line;
+ /// <exception cref="System.IO.IOException"></exception>
+ internal static void Populate(StreamReader r)
+ {
+ string line;
BufferedReader br = new BufferedReader((InputStreamReader)r);
- while ((line = br.ReadLine()) != null)
- {
- line = line.ToUpper().Trim();
- if (line.Length == 0)
- {
- }
- else
- {
- if (line[0] == '#')
- {
- if (line.StartsWith("#INCLUDE "))
- {
- line = Runtime.Substring(line, line.IndexOf('\\'));
- string url = "smb:" + line.Replace('\\', '/');
- if (_alt > 0)
- {
- try
- {
- Populate(new InputStreamReader(new SmbFileInputStream(url)));
- }
- catch (IOException ioe)
- {
- _log.WriteLine("lmhosts URL: " + url);
- Runtime.PrintStackTrace(ioe, _log);
- continue;
- }
- _alt--;
- while ((line = br.ReadLine()) != null)
- {
- line = line.ToUpper().Trim();
- if (line.StartsWith("#END_ALTERNATE"))
- {
- break;
- }
- }
- }
- else
- {
- Populate(new InputStreamReader(new SmbFileInputStream(url)));
- }
- }
- else
- {
- if (line.StartsWith("#BEGIN_ALTERNATE"))
- {
- _alt++;
- }
- else
- {
- if (line.StartsWith("#END_ALTERNATE") && _alt > 0)
- {
- _alt--;
- throw new IOException("no lmhosts alternate includes loaded");
- }
- }
- }
- }
- else
- {
- if (char.IsDigit(line[0]))
- {
- char[] data = line.ToCharArray();
- int ip;
- int i;
- int j;
- Name name;
- NbtAddress addr;
- char c;
- c = '.';
- ip = i = 0;
- for (; i < data.Length && c == '.'; i++)
- {
- int b = unchecked(0x00);
- for (; i < data.Length && (c = data[i]) >= 48 && c <= 57; i++)
- {
- b = b * 10 + c - '0';
- }
- ip = (ip << 8) + b;
- }
- while (i < data.Length && char.IsWhiteSpace(data[i]))
- {
- i++;
- }
- j = i;
- while (j < data.Length && char.IsWhiteSpace(data[j]) == false)
- {
- j++;
- }
- name = new Name(Runtime.Substring(line, i, j), unchecked(0x20), null
- );
- addr = new NbtAddress(name, ip, false, NbtAddress.BNode, false, false, true, true
- , NbtAddress.UnknownMacAddress);
- Tab.Put(name, addr);
- }
- }
- }
- }
- }
- }
+ while ((line = br.ReadLine()) != null)
+ {
+ line = line.ToUpper().Trim();
+ if (line.Length == 0)
+ {
+ }
+ else
+ {
+ if (line[0] == '#')
+ {
+ if (line.StartsWith("#INCLUDE "))
+ {
+ line = Runtime.Substring(line, line.IndexOf('\\'));
+ string url = "smb:" + line.Replace('\\', '/');
+ if (_alt > 0)
+ {
+ try
+ {
+ Populate(new InputStreamReader(new SmbFileInputStream(url)));
+ }
+ catch (IOException ioe)
+ {
+ _log.WriteLine("lmhosts URL: " + url);
+ Runtime.PrintStackTrace(ioe, _log);
+ continue;
+ }
+ _alt--;
+ while ((line = br.ReadLine()) != null)
+ {
+ line = line.ToUpper().Trim();
+ if (line.StartsWith("#END_ALTERNATE"))
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ Populate(new InputStreamReader(new SmbFileInputStream(url)));
+ }
+ }
+ else
+ {
+ if (line.StartsWith("#BEGIN_ALTERNATE"))
+ {
+ _alt++;
+ }
+ else
+ {
+ if (line.StartsWith("#END_ALTERNATE") && _alt > 0)
+ {
+ _alt--;
+ throw new IOException("no lmhosts alternate includes loaded");
+ }
+ }
+ }
+ }
+ else
+ {
+ if (char.IsDigit(line[0]))
+ {
+ char[] data = line.ToCharArray();
+ int ip;
+ int i;
+ int j;
+ Name name;
+ NbtAddress addr;
+ char c;
+ c = '.';
+ ip = i = 0;
+ for (; i < data.Length && c == '.'; i++)
+ {
+ int b = unchecked(0x00);
+ for (; i < data.Length && (c = data[i]) >= 48 && c <= 57; i++)
+ {
+ b = b * 10 + c - '0';
+ }
+ ip = (ip << 8) + b;
+ }
+ while (i < data.Length && char.IsWhiteSpace(data[i]))
+ {
+ i++;
+ }
+ j = i;
+ while (j < data.Length && char.IsWhiteSpace(data[j]) == false)
+ {
+ j++;
+ }
+ name = new Name(Runtime.Substring(line, i, j), unchecked(0x20), null
+ );
+ addr = new NbtAddress(name, ip, false, NbtAddress.BNode, false, false, true, true
+ , NbtAddress.UnknownMacAddress);
+ Tab.Put(name, addr);
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/Name.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/Name.cs
index 6c37d57a4..4166e1af8 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/Name.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/Name.cs
@@ -21,102 +21,110 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- public class Name
- {
- private const int TypeOffset = 31;
+ public class Name
+ {
+ private const int TypeOffset = 31;
- private const int ScopeOffset = 33;
+ private const int ScopeOffset = 33;
- private static readonly string DefaultScope = Config.GetProperty("jcifs.netbios.scope"
- );
+ private static readonly string DefaultScope
+ = Config.GetProperty("jcifs.netbios.scope");
- internal static readonly string OemEncoding = Config.GetProperty("jcifs.encoding"
- , Runtime.GetProperty("file.encoding"));
+ internal static readonly string OemEncoding
+ = Config.GetProperty("jcifs.encoding", Runtime.GetProperty("file.encoding"));
- public string name;
+ public string name;
- public string Scope;
+ public string Scope;
- public int HexCode;
+ public int HexCode;
- internal int SrcHashCode;
+ internal int SrcHashCode;
- public Name()
- {
- }
+ public Name()
+ {
+ }
- public Name(string name, int hexCode, string scope)
- {
- if (name.Length > 15)
- {
- name = Runtime.Substring(name, 0, 15);
- }
- this.name = name.ToUpper();
- this.HexCode = hexCode;
- this.Scope = !string.IsNullOrEmpty(scope) ? scope : DefaultScope;
- SrcHashCode = 0;
- }
+ public Name(string name, int hexCode, string scope)
+ {
+ if (name.Length > 15)
+ {
+ name = Runtime.Substring(name, 0, 15);
+ }
+ this.name = name.ToUpper();
+ this.HexCode = hexCode;
+ this.Scope = !string.IsNullOrEmpty(scope) ? scope : DefaultScope;
+ SrcHashCode = 0;
+ }
- internal virtual int WriteWireFormat(byte[] dst, int dstIndex)
- {
- // write 0x20 in first byte
- dst[dstIndex] = unchecked(0x20);
- // write name
- try
- {
- byte[] tmp = Runtime.GetBytesForString(name, OemEncoding
- );
- int i;
- for (i = 0; i < tmp.Length; i++)
- {
- dst[dstIndex + (2 * i + 1)] = unchecked((byte)(((tmp[i] & unchecked(0xF0))
- >> 4) + unchecked(0x41)));
- dst[dstIndex + (2 * i + 2)] = unchecked((byte)((tmp[i] & unchecked(0x0F))
- + unchecked(0x41)));
- }
- for (; i < 15; i++)
- {
- dst[dstIndex + (2 * i + 1)] = unchecked(unchecked(0x43));
- dst[dstIndex + (2 * i + 2)] = unchecked(unchecked(0x41));
- }
- dst[dstIndex + TypeOffset] = unchecked((byte)(((HexCode & unchecked(0xF0)
- ) >> 4) + unchecked(0x41)));
- dst[dstIndex + TypeOffset + 1] = unchecked((byte)((HexCode & unchecked(0x0F)) + unchecked(0x41)));
- }
- catch (UnsupportedEncodingException)
- {
- }
- return ScopeOffset + WriteScopeWireFormat(dst, dstIndex + ScopeOffset);
- }
+ internal virtual int WriteWireFormat(byte[] dst, int dstIndex)
+ {
+ // write 0x20 in first byte
+ dst[dstIndex] = unchecked(0x20);
+ // write name
+ try
+ {
+ byte[] tmp = Runtime.GetBytesForString(name, OemEncoding
+ );
+ int i;
+ for (i = 0; i < tmp.Length; i++)
+ {
+ dst[dstIndex + (2 * i + 1)]
+ = unchecked((byte)(((tmp[i] & unchecked(0xF0)) >> 4) + unchecked(0x41)));
+ dst[dstIndex + (2 * i + 2)]
+ = unchecked((byte)((tmp[i] & unchecked(0x0F)) + unchecked(0x41)));
+ }
+ for (; i < 15; i++)
+ {
+ dst[dstIndex + (2 * i + 1)] = unchecked(unchecked(0x43));
+ dst[dstIndex + (2 * i + 2)] = unchecked(unchecked(0x41));
+ }
+ dst[dstIndex + TypeOffset]
+ = unchecked((byte)(((HexCode & unchecked(0xF0)) >> 4) + unchecked(0x41)));
+ dst[dstIndex + TypeOffset + 1]
+ = unchecked((byte)((HexCode & unchecked(0x0F)) + unchecked(0x41)));
+ }
+ catch (UnsupportedEncodingException)
+ {
+ }
+ return ScopeOffset + WriteScopeWireFormat(dst, dstIndex + ScopeOffset);
+ }
- internal virtual int ReadWireFormat(byte[] src, int srcIndex)
- {
- byte[] tmp = new byte[ScopeOffset];
- int length = 15;
- for (int i = 0; i < 15; i++)
- {
- tmp[i] = unchecked((byte)(((src[srcIndex + (2 * i + 1)] & unchecked(0xFF))
- - unchecked(0x41)) << 4));
- tmp[i] |= unchecked((byte)(((src[srcIndex + (2 * i + 2)] & unchecked(0xFF)
- ) - unchecked(0x41)) & unchecked(0x0F)));
- if (tmp[i] != unchecked((byte)' '))
- {
- length = i + 1;
- }
- }
- try
- {
- name = Runtime.GetStringForBytes(tmp, 0, length, OemEncoding
- );
- }
- catch (UnsupportedEncodingException)
- {
- }
- HexCode = ((src[srcIndex + TypeOffset] & unchecked(0xFF)) - unchecked(0x41)) << 4;
- HexCode |= ((src[srcIndex + TypeOffset + 1] & unchecked(0xFF)) - unchecked(
- 0x41)) & unchecked(0x0F);
- return ScopeOffset + ReadScopeWireFormat(src, srcIndex + ScopeOffset);
- }
+ internal virtual int ReadWireFormat(byte[] src, int srcIndex)
+ {
+ byte[] tmp = new byte[ScopeOffset];
+ int length = 15;
+ for (int i = 0; i < 15; i++)
+ {
+ tmp[i] = unchecked(
+ (byte)(
+ ((src[srcIndex + (2 * i + 1)] & unchecked(0xFF)) - unchecked(0x41)) << 4
+ )
+ );
+ tmp[i] |= unchecked(
+ (byte)(
+ ((src[srcIndex + (2 * i + 2)] & unchecked(0xFF)) - unchecked(0x41))
+ & unchecked(0x0F)
+ )
+ );
+ if (tmp[i] != unchecked((byte)' '))
+ {
+ length = i + 1;
+ }
+ }
+ try
+ {
+ name = Runtime.GetStringForBytes(tmp, 0, length, OemEncoding
+ );
+ }
+ catch (UnsupportedEncodingException)
+ {
+ }
+ HexCode = ((src[srcIndex + TypeOffset] & unchecked(0xFF)) - unchecked(0x41)) << 4;
+ HexCode |= ((src[srcIndex + TypeOffset + 1] & unchecked(0xFF)) - unchecked(0x41))
+ & unchecked(0x0F);
+ return ScopeOffset + ReadScopeWireFormat(src, srcIndex + ScopeOffset);
+ }
internal int ReadWireFormatDos(byte[] src, int srcIndex)
{
@@ -130,9 +138,8 @@ namespace SharpCifs.Netbios
{
name = Runtime.GetStringForBytes(tmp, 0, length).Trim();
}
- catch (Exception ex)
+ catch (Exception)
{
-
}
HexCode = src[srcIndex + length];
@@ -141,129 +148,129 @@ namespace SharpCifs.Netbios
}
- internal virtual int WriteScopeWireFormat(byte[] dst, int dstIndex)
- {
- if (Scope == null)
- {
- dst[dstIndex] = unchecked(unchecked(0x00));
- return 1;
- }
- // copy new scope in
- dst[dstIndex++] = unchecked((byte)('.'));
- try
- {
- Array.Copy(Runtime.GetBytesForString(Scope, OemEncoding
- ), 0, dst, dstIndex, Scope.Length);
- }
- catch (UnsupportedEncodingException)
- {
- }
- dstIndex += Scope.Length;
- dst[dstIndex++] = unchecked(unchecked(0x00));
- // now go over scope backwards converting '.' to label length
- int i = dstIndex - 2;
- int e = i - Scope.Length;
- int c = 0;
- do
- {
- if (dst[i] == '.')
- {
- dst[i] = unchecked((byte)c);
- c = 0;
- }
- else
- {
- c++;
- }
- }
- while (i-- > e);
- return Scope.Length + 2;
- }
+ internal virtual int WriteScopeWireFormat(byte[] dst, int dstIndex)
+ {
+ if (Scope == null)
+ {
+ dst[dstIndex] = unchecked(unchecked(0x00));
+ return 1;
+ }
+ // copy new scope in
+ dst[dstIndex++] = unchecked((byte)('.'));
+ try
+ {
+ Array.Copy(Runtime.GetBytesForString(Scope, OemEncoding),
+ 0, dst, dstIndex, Scope.Length);
+ }
+ catch (UnsupportedEncodingException)
+ {
+ }
+ dstIndex += Scope.Length;
+ dst[dstIndex++] = unchecked(unchecked(0x00));
+ // now go over scope backwards converting '.' to label length
+ int i = dstIndex - 2;
+ int e = i - Scope.Length;
+ int c = 0;
+ do
+ {
+ if (dst[i] == '.')
+ {
+ dst[i] = unchecked((byte)c);
+ c = 0;
+ }
+ else
+ {
+ c++;
+ }
+ }
+ while (i-- > e);
+ return Scope.Length + 2;
+ }
- internal virtual int ReadScopeWireFormat(byte[] src, int srcIndex)
- {
- int start = srcIndex;
- int n;
- StringBuilder sb;
- if ((n = src[srcIndex++] & unchecked(0xFF)) == 0)
- {
- Scope = null;
- return 1;
- }
- try
- {
- sb = new StringBuilder(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding));
- srcIndex += n;
- while ((n = src[srcIndex++] & unchecked(0xFF)) != 0)
- {
- sb.Append('.').Append(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding));
- srcIndex += n;
- }
- Scope = sb.ToString();
- }
- catch (UnsupportedEncodingException)
- {
- }
- return srcIndex - start;
- }
+ internal virtual int ReadScopeWireFormat(byte[] src, int srcIndex)
+ {
+ int start = srcIndex;
+ int n;
+ StringBuilder sb;
+ if ((n = src[srcIndex++] & unchecked(0xFF)) == 0)
+ {
+ Scope = null;
+ return 1;
+ }
+ try
+ {
+ sb = new StringBuilder(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding));
+ srcIndex += n;
+ while ((n = src[srcIndex++] & unchecked(0xFF)) != 0)
+ {
+ sb.Append('.').Append(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding));
+ srcIndex += n;
+ }
+ Scope = sb.ToString();
+ }
+ catch (UnsupportedEncodingException)
+ {
+ }
+ return srcIndex - start;
+ }
- public override int GetHashCode()
- {
- int result;
- result = name.GetHashCode();
- result += 65599 * HexCode;
- result += 65599 * SrcHashCode;
- if (Scope != null && Scope.Length != 0)
- {
- result += Scope.GetHashCode();
- }
- return result;
- }
+ public override int GetHashCode()
+ {
+ int result;
+ result = name.GetHashCode();
+ result += 65599 * HexCode;
+ result += 65599 * SrcHashCode;
+ if (Scope != null && Scope.Length != 0)
+ {
+ result += Scope.GetHashCode();
+ }
+ return result;
+ }
- public override bool Equals(object obj)
- {
- Name n;
- if (!(obj is Name))
- {
- return false;
- }
- n = (Name)obj;
- if (Scope == null && n.Scope == null)
- {
- return name.Equals(n.name) && HexCode == n.HexCode;
- }
- return name.Equals(n.name) && HexCode == n.HexCode && Scope.Equals(n.Scope);
- }
+ public override bool Equals(object obj)
+ {
+ Name n;
+ if (!(obj is Name))
+ {
+ return false;
+ }
+ n = (Name)obj;
+ if (Scope == null && n.Scope == null)
+ {
+ return name.Equals(n.name) && HexCode == n.HexCode;
+ }
+ return name.Equals(n.name) && HexCode == n.HexCode && Scope.Equals(n.Scope);
+ }
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
- //return "";
+ //return "";
- string n = name;
- // fix MSBROWSE name
- if (n == null)
- {
- n = "null";
- }
- else
- {
- if (n[0] == unchecked(0x01))
- {
- char[] c = n.ToCharArray();
- c[0] = '.';
- c[1] = '.';
- c[14] = '.';
- n = new string(c);
- }
- }
- sb.Append(n).Append("<").Append(Hexdump.ToHexString(HexCode, 2)).Append(">");
- if (Scope != null)
- {
- sb.Append(".").Append(Scope);
- }
- return sb.ToString();
- }
- }
+ string n = name;
+ // fix MSBROWSE name
+ if (n == null)
+ {
+ n = "null";
+ }
+ else
+ {
+ if (n[0] == unchecked(0x01))
+ {
+ char[] c = n.ToCharArray();
+ c[0] = '.';
+ c[1] = '.';
+ c[14] = '.';
+ n = new string(c);
+ }
+ }
+ sb.Append(n).Append("<").Append(Hexdump.ToHexString(HexCode, 2)).Append(">");
+ if (Scope != null)
+ {
+ sb.Append(".").Append(Scope);
+ }
+ return sb.ToString();
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs
index 646e65bf8..1e9419638 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs
@@ -16,37 +16,37 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
namespace SharpCifs.Netbios
{
- internal class NameQueryRequest : NameServicePacket
- {
- internal NameQueryRequest(Name name)
- {
- QuestionName = name;
- QuestionType = Nb;
- }
+ internal class NameQueryRequest : NameServicePacket
+ {
+ internal NameQueryRequest(Name name)
+ {
+ QuestionName = name;
+ QuestionType = Nb;
+ }
- internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
- {
- return WriteQuestionSectionWireFormat(dst, dstIndex);
- }
+ internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
+ {
+ return WriteQuestionSectionWireFormat(dst, dstIndex);
+ }
- internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
- {
- return ReadQuestionSectionWireFormat(src, srcIndex);
- }
+ internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
+ {
+ return ReadQuestionSectionWireFormat(src, srcIndex);
+ }
- internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
- {
- return 0;
- }
+ internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
+ {
+ return 0;
+ }
- public override string ToString()
- {
- return "NameQueryRequest[" + base.ToString() + "]";
- }
- }
+ public override string ToString()
+ {
+ return "NameQueryRequest[" + base.ToString() + "]";
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs
index c7fac8e93..2285c6e7b 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs
@@ -16,53 +16,52 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
namespace SharpCifs.Netbios
{
- internal class NameQueryResponse : NameServicePacket
- {
- public NameQueryResponse()
- {
- RecordName = new Name();
- }
+ internal class NameQueryResponse : NameServicePacket
+ {
+ public NameQueryResponse()
+ {
+ RecordName = new Name();
+ }
- internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
- {
- return ReadResourceRecordWireFormat(src, srcIndex);
- }
+ internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
+ {
+ return ReadResourceRecordWireFormat(src, srcIndex);
+ }
- internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
- {
- if (ResultCode != 0 || OpCode != Query)
- {
- return 0;
- }
- bool groupName = ((src[srcIndex] & unchecked(0x80)) == unchecked(0x80)) ? true : false;
- int nodeType = (src[srcIndex] & unchecked(0x60)) >> 5;
- srcIndex += 2;
- int address = ReadInt4(src, srcIndex);
- if (address != 0)
- {
- AddrEntry[AddrIndex] = new NbtAddress(RecordName, address, groupName, nodeType);
- }
- else
- {
- AddrEntry[AddrIndex] = null;
- }
- return 6;
- }
+ internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
+ {
+ if (ResultCode != 0 || OpCode != Query)
+ {
+ return 0;
+ }
+ bool groupName = ((src[srcIndex] & unchecked(0x80)) == unchecked(0x80)) ? true : false;
+ int nodeType = (src[srcIndex] & unchecked(0x60)) >> 5;
+ srcIndex += 2;
+ int address = ReadInt4(src, srcIndex);
+ if (address != 0)
+ {
+ AddrEntry[AddrIndex] = new NbtAddress(RecordName, address, groupName, nodeType);
+ }
+ else
+ {
+ AddrEntry[AddrIndex] = null;
+ }
+ return 6;
+ }
- public override string ToString()
- {
- return "NameQueryResponse[" + base.ToString() + ",addrEntry=" + AddrEntry
- + "]";
- }
- }
+ public override string ToString()
+ {
+ return "NameQueryResponse[" + base.ToString() + ",addrEntry=" + AddrEntry + "]";
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs
index 01700e64a..fb74c691b 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs
@@ -21,10 +21,13 @@ using System.Net;
using System.Net.Sockets;
using System.Linq;
using System.Threading;
+using SharpCifs.Smb;
using SharpCifs.Util;
+using SharpCifs.Util.DbsHelper;
using SharpCifs.Util.Sharpen;
using Thread = SharpCifs.Util.Sharpen.Thread;
+using System.Threading.Tasks;
namespace SharpCifs.Netbios
{
@@ -48,27 +51,29 @@ namespace SharpCifs.Netbios
internal const int ResolverWins = 3;
- private static readonly int SndBufSize = Config.GetInt("jcifs.netbios.snd_buf_size"
- , DefaultSndBufSize);
+ private static readonly int SndBufSize
+ = Config.GetInt("jcifs.netbios.snd_buf_size", DefaultSndBufSize);
- private static readonly int RcvBufSize = Config.GetInt("jcifs.netbios.rcv_buf_size"
- , DefaultRcvBufSize);
+ private static readonly int RcvBufSize
+ = Config.GetInt("jcifs.netbios.rcv_buf_size", DefaultRcvBufSize);
- private static readonly int SoTimeout = Config.GetInt("jcifs.netbios.soTimeout",
- DefaultSoTimeout);
+ private static readonly int SoTimeout
+ = Config.GetInt("jcifs.netbios.soTimeout", DefaultSoTimeout);
- private static readonly int RetryCount = Config.GetInt("jcifs.netbios.retryCount"
- , DefaultRetryCount);
+ private static readonly int RetryCount
+ = Config.GetInt("jcifs.netbios.retryCount", DefaultRetryCount);
- private static readonly int RetryTimeout = Config.GetInt("jcifs.netbios.retryTimeout"
- , DefaultRetryTimeout);
+ private static readonly int RetryTimeout
+ = Config.GetInt("jcifs.netbios.retryTimeout", DefaultRetryTimeout);
- private static readonly int Lport = Config.GetInt("jcifs.netbios.lport", 137);
+ private static readonly int Lport
+ = Config.GetInt("jcifs.netbios.lport", 137);
- private static readonly IPAddress Laddr = Config.GetInetAddress("jcifs.netbios.laddr"
- , null);
+ private static readonly IPAddress Laddr
+ = Config.GetInetAddress("jcifs.netbios.laddr", null);
- private static readonly string Ro = Config.GetProperty("jcifs.resolveOrder");
+ private static readonly string Ro
+ = Config.GetProperty("jcifs.resolveOrder");
private static LogStream _log = LogStream.GetInstance();
@@ -82,18 +87,20 @@ namespace SharpCifs.Netbios
private byte[] _rcvBuf;
- private SocketEx _socket;
+ private SocketEx _socketSender;
private Hashtable _responseTable = new Hashtable();
private Thread _thread;
-
+
private int _nextNameTrnId;
private int[] _resolveOrder;
private bool _waitResponse = true;
+ private bool _isActive = false;
+
private AutoResetEvent _autoResetWaitReceive;
internal IPAddress laddr;
@@ -109,13 +116,17 @@ namespace SharpCifs.Netbios
{
this._lport = lport;
- this.laddr = laddr
- ?? Config.GetLocalHost()
- ?? Extensions.GetAddressesByName(Dns.GetHostName()).FirstOrDefault();
+ this.laddr = laddr
+ ?? Config.GetLocalHost()
+ ?? Extensions.GetLocalAddresses()?.FirstOrDefault();
+
+ if (this.laddr == null)
+ throw new ArgumentNullException("IPAddress NOT found. if exec on localhost, set vallue to [jcifs.smb.client.laddr]");
try
{
- Baddr = Config.GetInetAddress("jcifs.netbios.baddr", Extensions.GetAddressByName("255.255.255.255"));
+ Baddr = Config.GetInetAddress("jcifs.netbios.baddr",
+ Extensions.GetAddressByName("255.255.255.255"));
}
catch (Exception ex)
{
@@ -161,8 +172,8 @@ namespace SharpCifs.Netbios
{
if (_log.Level > 1)
{
- _log.WriteLine("NetBIOS resolveOrder specifies WINS however the " + "jcifs.netbios.wins property has not been set"
- );
+ _log.WriteLine("NetBIOS resolveOrder specifies WINS however the "
+ + "jcifs.netbios.wins property has not been set");
}
continue;
}
@@ -208,53 +219,93 @@ namespace SharpCifs.Netbios
/// <exception cref="System.IO.IOException"></exception>
internal virtual void EnsureOpen(int timeout)
{
+ //Log.Out($"NameServiceClient.EnsureOpen");
+
_closeTimeout = 0;
if (SoTimeout != 0)
{
_closeTimeout = Math.Max(SoTimeout, timeout);
}
+
+ var localPort = (SmbConstants.Lport == 0) ? _lport : SmbConstants.Lport;
+
// If socket is still good, the new closeTimeout will
// be ignored; see tryClose comment.
- if (_socket == null)
+ if (
+ _socketSender == null
+ || _socketSender.LocalEndPoint == null
+ || _socketSender.GetLocalPort() != localPort
+ || !IPAddress.Any.Equals(_socketSender.GetLocalInetAddress())
+ )
{
- _socket = new SocketEx(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
-
- //IPAddress.`Address` property deleted
- //_socket.Bind(new IPEndPoint(laddr.Address, _lport));
- _socket.Bind(new IPEndPoint(laddr, _lport));
+ if (_socketSender != null)
+ {
+ _socketSender.Dispose();
+ _socketSender = null;
+ }
+
+ _socketSender = new SocketEx(AddressFamily.InterNetwork,
+ SocketType.Dgram,
+ ProtocolType.Udp);
+
+ _socketSender.Bind(new IPEndPoint(IPAddress.Any, localPort));
+
if (_waitResponse)
{
- _thread = new Thread(this); //new Sharpen.Thread(this, "JCIFS-NameServiceClient");
+ if (_thread != null)
+ {
+ _thread.Cancel(true);
+ _thread.Dispose();
+ }
+
+ _thread = new Thread(this);
_thread.SetDaemon(true);
- _thread.Start();
+ _thread.Start(true);
}
}
}
internal virtual void TryClose()
{
+ //Log.Out("NameSerciceClient.TryClose");
+
+ if (this._isActive)
+ {
+ //Log.Out("NameSerciceClient.TryClose - Now in Processing... Exit.");
+ return;
+ }
+
lock (_lock)
{
- if (_socket != null)
+ if (_socketSender != null)
{
- //Socket.`Close` method deleted
- //_socket.Close();
- _socket.Dispose();
- _socket = null;
+ _socketSender.Dispose();
+ _socketSender = null;
+ //Log.Out("NameSerciceClient.TryClose - _socketSender.Disposed");
+ }
+
+ if (_thread != null)
+ {
+ _thread.Cancel(true);
+ _thread.Dispose();
+ _thread = null;
+ //Log.Out("NameSerciceClient.TryClose - _thread.Aborted");
}
- _thread = null;
if (_waitResponse)
{
_responseTable.Clear();
- } else
+ }
+ else
{
_autoResetWaitReceive.Set();
}
}
}
+
+ private int _recievedLength = -1;
public virtual void Run()
{
int nameTrnId;
@@ -262,12 +313,38 @@ namespace SharpCifs.Netbios
try
{
-
- while (_thread == Thread.CurrentThread())
+ while (Thread.CurrentThread().Equals(_thread))
{
- _socket.SoTimeOut = _closeTimeout;
+ if (_thread.IsCanceled)
+ break;
+
+ var localPort = (SmbConstants.Lport == 0) ? _lport : SmbConstants.Lport;
+
+ var sockEvArg = new SocketAsyncEventArgs();
+ sockEvArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, localPort);
+ sockEvArg.SetBuffer(_rcvBuf, 0, RcvBufSize);
+ sockEvArg.Completed += this.OnReceiveCompleted;
+
+ _socketSender.SoTimeOut = _closeTimeout;
+
+ this._recievedLength = -1;
+
+ //Log.Out($"NameServiceClient.Run - Wait Recieve: {IPAddress.Any}: {localPort}");
+ _socketSender.ReceiveFromAsync(sockEvArg);
+
+ while (this._recievedLength == -1)
+ {
+ if (_thread.IsCanceled)
+ break;
+
+ Task.Delay(300).GetAwaiter().GetResult();
+ }
+
+ sockEvArg?.Dispose();
- int len = _socket.Receive(_rcvBuf, 0, RcvBufSize);
+
+ if (_thread.IsCanceled)
+ break;
if (_log.Level > 3)
{
@@ -284,12 +361,15 @@ namespace SharpCifs.Netbios
lock (response)
{
+ if (_thread.IsCanceled)
+ break;
+
response.ReadWireFormat(_rcvBuf, 0);
if (_log.Level > 3)
{
_log.WriteLine(response);
- Hexdump.ToHexdump(_log, _rcvBuf, 0, len);
+ Hexdump.ToHexdump(_log, _rcvBuf, 0, this._recievedLength);
}
if (response.IsResponse)
@@ -300,7 +380,6 @@ namespace SharpCifs.Netbios
}
}
}
-
}
catch (TimeoutException) { }
catch (Exception ex)
@@ -316,10 +395,21 @@ namespace SharpCifs.Netbios
}
}
+
+ private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
+ {
+ //Log.Out("NameServiceClient.OnReceiveCompleted");
+ this._recievedLength = e.BytesTransferred;
+ }
+
+
/// <exception cref="System.IO.IOException"></exception>
- internal virtual void Send(NameServicePacket request, NameServicePacket response,
- int timeout)
+ internal virtual void Send(NameServicePacket request,
+ NameServicePacket response,
+ int timeout)
{
+ //Log.Out("NameSerciceClient.Send - Start");
+
int nid = 0;
int max = NbtAddress.Nbns.Length;
if (max == 0)
@@ -329,6 +419,7 @@ namespace SharpCifs.Netbios
lock (response)
{
+ this._isActive = true;
while (max-- > 0)
{
@@ -338,45 +429,75 @@ namespace SharpCifs.Netbios
{
request.NameTrnId = GetNextNameTrnId();
nid = request.NameTrnId;
+
response.Received = false;
_responseTable.Put(nid, response);
+
+ //Log.Out($"NameSerciceClient.Send - timeout = {timeout}");
EnsureOpen(timeout + 1000);
+
int requestLenght = request.WriteWireFormat(_sndBuf, 0);
- _socket.Send(_sndBuf, 0, requestLenght, new IPEndPoint(request.Addr, _lport));
+ byte[] msg = new byte[requestLenght];
+ Array.Copy(_sndBuf, msg, requestLenght);
+
+ _socketSender.SetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.Broadcast,
+ request.IsBroadcast
+ ? 1
+ : 0);
+
+ _socketSender.SendTo(msg, new IPEndPoint(request.Addr, _lport));
+ //Log.Out("NameSerciceClient.Send - Sended");
+
if (_log.Level > 3)
{
_log.WriteLine(request);
Hexdump.ToHexdump(_log, _sndBuf, 0, requestLenght);
}
-
}
+
if (_waitResponse)
{
long start = Runtime.CurrentTimeMillis();
+ var isRecieved = false;
+ var startTime = DateTime.Now;
while (timeout > 0)
{
Runtime.Wait(response, timeout);
if (response.Received && request.QuestionType == response.RecordType)
{
- return;
+ //return;
+ isRecieved = true;
+ break;
}
response.Received = false;
timeout -= (int)(Runtime.CurrentTimeMillis() - start);
+
+ //if (timeout <= 0)
+ //{
+ // Log.Out($"NameSerciceClient.Send Timeout! - {(DateTime.Now - startTime).TotalMilliseconds} msec");
+ //}
}
+
+ if (isRecieved)
+ break;
}
}
catch (Exception ie)
{
+ if (_waitResponse)
+ _responseTable.Remove(nid);
+
+ //Log.Out("NameSerciceClient.Send - IOException");
+
throw new IOException(ie.Message);
}
finally
{
- //Sharpen.Collections.Remove(responseTable, nid);
if (_waitResponse)
- {
_responseTable.Remove(nid);
- }
}
+
if (_waitResponse)
{
lock (_lock)
@@ -393,17 +514,24 @@ namespace SharpCifs.Netbios
}
}
}
+
+ this._isActive = false;
+ //Log.Out("NameSerciceClient.Send - Normaly Ended.");
}
}
/// <exception cref="UnknownHostException"></exception>
internal virtual NbtAddress[] GetAllByName(Name name, IPAddress addr)
{
+ //Log.Out("NameSerciceClient.GetAllByName");
+
int n;
NameQueryRequest request = new NameQueryRequest(name);
NameQueryResponse response = new NameQueryResponse();
request.Addr = addr ?? NbtAddress.GetWinsAddress();
- request.IsBroadcast = request.Addr == null;
+ request.IsBroadcast = (request.Addr == null
+ || request.Addr.ToString() == Baddr.ToString());
+
if (request.IsBroadcast)
{
request.Addr = Baddr;
@@ -440,10 +568,12 @@ namespace SharpCifs.Netbios
/// <exception cref="UnknownHostException"></exception>
internal virtual NbtAddress GetByName(Name name, IPAddress addr)
{
- int n;
+ //Log.Out("NameSerciceClient.GetByName");
+ int n;
NameQueryRequest request = new NameQueryRequest(name);
NameQueryResponse response = new NameQueryResponse();
+
if (addr != null)
{
request.Addr = addr;
@@ -463,7 +593,9 @@ namespace SharpCifs.Netbios
}
throw new UnknownHostException(ioe);
}
- if (response.Received && response.ResultCode == 0
+
+ if (response.Received
+ && response.ResultCode == 0
&& response.IsResponse)
{
int last = response.AddrEntry.Length - 1;
@@ -471,9 +603,11 @@ namespace SharpCifs.Netbios
return response.AddrEntry[last];
}
}
+
while (--n > 0 && request.IsBroadcast);
throw new UnknownHostException();
}
+
for (int i = 0; i < _resolveOrder.Length; i++)
{
try
@@ -496,8 +630,9 @@ namespace SharpCifs.Netbios
case ResolverWins:
case ResolverBcast:
{
- if (_resolveOrder[i] == ResolverWins && name.name != NbtAddress.MasterBrowserName
- && name.HexCode != unchecked(0x1d))
+ if (_resolveOrder[i] == ResolverWins
+ && name.name != NbtAddress.MasterBrowserName
+ && name.HexCode != unchecked(0x1d))
{
request.Addr = NbtAddress.GetWinsAddress();
request.IsBroadcast = false;
@@ -522,11 +657,12 @@ namespace SharpCifs.Netbios
}
throw new UnknownHostException(ioe);
}
- if (response.Received && response.ResultCode == 0
+ if (response.Received
+ && response.ResultCode == 0
&& response.IsResponse)
{
-
- response.AddrEntry[0].HostName.SrcHashCode = request.Addr.GetHashCode();
+ response.AddrEntry[0].HostName.SrcHashCode
+ = request.Addr.GetHashCode();
return response.AddrEntry[0];
}
if (_resolveOrder[i] == ResolverWins)
@@ -542,12 +678,15 @@ namespace SharpCifs.Netbios
{
}
}
+
throw new UnknownHostException();
}
/// <exception cref="UnknownHostException"></exception>
internal virtual NbtAddress[] GetNodeStatus(NbtAddress addr)
{
+ //Log.Out("NameSerciceClient.GetNodeStatus");
+
int n;
int srcHashCode;
NodeStatusRequest request;
@@ -556,6 +695,7 @@ namespace SharpCifs.Netbios
request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked(0x00), null));
request.Addr = addr.GetInetAddress();
n = RetryCount;
+
while (n-- > 0)
{
try
@@ -585,6 +725,8 @@ namespace SharpCifs.Netbios
internal virtual NbtAddress[] GetHosts()
{
+ //Log.Out("NbtServiceClient.GetHosts");
+
try
{
_waitResponse = false;
@@ -593,6 +735,8 @@ namespace SharpCifs.Netbios
for (int i = 1; i <= 254; i++)
{
+ //Log.Out($"NbtServiceClient.GetHosts - {i}");
+
NodeStatusRequest request;
NodeStatusResponse response;
@@ -605,49 +749,59 @@ namespace SharpCifs.Netbios
IPAddress addr = new IPAddress(addrBytes);
- //response = new NodeStatusResponse(new NbtAddress(NbtAddress.UnknownName,
- // (int)addr.Address, false, 0x20));
- response = new NodeStatusResponse(new NbtAddress(NbtAddress.UnknownName,
- BitConverter.ToInt32(addr.GetAddressBytes(), 0) , false, 0x20));
+ response = new NodeStatusResponse(
+ new NbtAddress(NbtAddress.UnknownName,
+ BitConverter.ToInt32(addr.GetAddressBytes(), 0),
+ false,
+ 0x20)
+ );
+
+ request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName,
+ unchecked(0x20),
+ null))
+ {
+ Addr = addr
+ };
- request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked(0x20), null));
- request.Addr = addr;
Send(request, response, 0);
}
-
}
catch (IOException ioe)
{
+ //Log.Out(ioe);
+
if (_log.Level > 1)
{
Runtime.PrintStackTrace(ioe, _log);
}
throw new UnknownHostException(ioe);
}
-
+
_autoResetWaitReceive = new AutoResetEvent(false);
- _thread = new Thread(this);
+
+ if (_thread != null)
+ {
+ _thread.Cancel(true);
+ _thread.Dispose();
+ }
+
+ _thread = new Thread(this);
_thread.SetDaemon(true);
- _thread.Start();
+ _thread.Start(true);
- _autoResetWaitReceive.WaitOne();
+ _autoResetWaitReceive.WaitOne();
- List<NbtAddress> result = new List<NbtAddress>();
+ var result = new List<NbtAddress>();
foreach (var key in _responseTable.Keys)
{
- NodeStatusResponse resp = (NodeStatusResponse)_responseTable[key];
+ var resp = (NodeStatusResponse)_responseTable[key];
- if (resp.Received && resp.ResultCode == 0)
- {
- foreach (var entry in resp.AddressArray)
- {
- if (entry.HostName.HexCode == 0x20)
- {
- result.Add(entry);
- }
- }
- }
+ if (!resp.Received || resp.ResultCode != 0)
+ continue;
+
+ result.AddRange(resp.AddressArray
+ .Where(entry => entry.HostName.HexCode == 0x20));
}
_responseTable.Clear();
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs
index 28e98406e..1ac258a4e 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs
@@ -20,429 +20,474 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- internal abstract class NameServicePacket
- {
- internal const int Query = 0;
+ internal abstract class NameServicePacket
+ {
+ internal const int Query = 0;
- internal const int Wack = 7;
+ internal const int Wack = 7;
- internal const int FmtErr = 0x1;
+ internal const int FmtErr = 0x1;
- internal const int SrvErr = 0x2;
+ internal const int SrvErr = 0x2;
- internal const int ImpErr = 0x4;
+ internal const int ImpErr = 0x4;
- internal const int RfsErr = 0x5;
+ internal const int RfsErr = 0x5;
- internal const int ActErr = 0x6;
+ internal const int ActErr = 0x6;
- internal const int CftErr = 0x7;
+ internal const int CftErr = 0x7;
- internal const int NbIn = 0x00200001;
+ internal const int NbIn = 0x00200001;
- internal const int NbstatIn = 0x00210001;
+ internal const int NbstatIn = 0x00210001;
- internal const int Nb = 0x0020;
+ internal const int Nb = 0x0020;
- internal const int Nbstat = 0x0021;
+ internal const int Nbstat = 0x0021;
- internal const int In = 0x0001;
+ internal const int In = 0x0001;
- internal const int A = 0x0001;
+ internal const int A = 0x0001;
- internal const int Ns = 0x0002;
+ internal const int Ns = 0x0002;
- internal const int Null = 0x000a;
+ internal const int Null = 0x000a;
- internal const int HeaderLength = 12;
+ internal const int HeaderLength = 12;
- internal const int OpcodeOffset = 2;
+ internal const int OpcodeOffset = 2;
- internal const int QuestionOffset = 4;
+ internal const int QuestionOffset = 4;
- internal const int AnswerOffset = 6;
+ internal const int AnswerOffset = 6;
- internal const int AuthorityOffset = 8;
+ internal const int AuthorityOffset = 8;
- internal const int AdditionalOffset = 10;
+ internal const int AdditionalOffset = 10;
- // opcode
- // rcode
- // type/class
- // header field offsets
- internal static void WriteInt2(int val, byte[] dst, int dstIndex)
- {
- dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
- dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
- }
+ // opcode
+ // rcode
+ // type/class
+ // header field offsets
+ internal static void WriteInt2(int val, byte[] dst, int dstIndex)
+ {
+ dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
+ dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
+ }
- internal static void WriteInt4(int val, byte[] dst, int dstIndex)
- {
- dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF)));
- dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF)));
- dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
- dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
- }
+ internal static void WriteInt4(int val, byte[] dst, int dstIndex)
+ {
+ dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF)));
+ dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF)));
+ dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
+ dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
+ }
- internal static int ReadInt2(byte[] src, int srcIndex)
- {
- return ((src[srcIndex] & unchecked(0xFF)) << 8) + (src[srcIndex + 1] & unchecked(
- 0xFF));
- }
+ internal static int ReadInt2(byte[] src, int srcIndex)
+ {
+ return ((src[srcIndex] & unchecked(0xFF)) << 8) + (src[srcIndex + 1] & unchecked(
+ 0xFF));
+ }
- internal static int ReadInt4(byte[] src, int srcIndex)
- {
- return ((src[srcIndex] & unchecked(0xFF)) << 24) + ((src[srcIndex + 1] & unchecked(
- 0xFF)) << 16) + ((src[srcIndex + 2] & unchecked(0xFF)) << 8) + (src
- [srcIndex + 3] & unchecked(0xFF));
- }
+ internal static int ReadInt4(byte[] src, int srcIndex)
+ {
+ return ((src[srcIndex] & unchecked(0xFF)) << 24)
+ + ((src[srcIndex + 1] & unchecked(0xFF)) << 16)
+ + ((src[srcIndex + 2] & unchecked(0xFF)) << 8)
+ + (src[srcIndex + 3] & unchecked(0xFF));
+ }
- internal static int ReadNameTrnId(byte[] src, int srcIndex)
- {
- return ReadInt2(src, srcIndex);
- }
+ internal static int ReadNameTrnId(byte[] src, int srcIndex)
+ {
+ return ReadInt2(src, srcIndex);
+ }
- internal int AddrIndex;
+ internal int AddrIndex;
- internal NbtAddress[] AddrEntry;
+ internal NbtAddress[] AddrEntry;
- internal int NameTrnId;
+ internal int NameTrnId;
- internal int OpCode;
+ internal int OpCode;
- internal int ResultCode;
+ internal int ResultCode;
- internal int QuestionCount;
+ internal int QuestionCount;
- internal int AnswerCount;
+ internal int AnswerCount;
- internal int AuthorityCount;
+ internal int AuthorityCount;
- internal int AdditionalCount;
+ internal int AdditionalCount;
- internal bool Received;
+ internal bool Received;
- internal bool IsResponse;
+ internal bool IsResponse;
- internal bool IsAuthAnswer;
+ internal bool IsAuthAnswer;
- internal bool IsTruncated;
+ internal bool IsTruncated;
- internal bool IsRecurDesired;
+ internal bool IsRecurDesired;
- internal bool IsRecurAvailable;
+ internal bool IsRecurAvailable;
- internal bool IsBroadcast;
+ internal bool IsBroadcast;
- internal Name QuestionName;
+ internal Name QuestionName;
- internal Name RecordName;
-
- internal int QuestionType;
-
- internal int QuestionClass;
-
- internal int RecordType;
-
- internal int RecordClass;
-
- internal int Ttl;
-
- internal int RDataLength;
-
- internal IPAddress Addr;
-
- public NameServicePacket()
- {
- IsRecurDesired = true;
- IsBroadcast = true;
- QuestionCount = 1;
- QuestionClass = In;
- }
-
- internal virtual int WriteWireFormat(byte[] dst, int dstIndex)
- {
- int start = dstIndex;
- dstIndex += WriteHeaderWireFormat(dst, dstIndex);
- dstIndex += WriteBodyWireFormat(dst, dstIndex);
- return dstIndex - start;
- }
-
- internal virtual int ReadWireFormat(byte[] src, int srcIndex)
- {
- int start = srcIndex;
- srcIndex += ReadHeaderWireFormat(src, srcIndex);
- srcIndex += ReadBodyWireFormat(src, srcIndex);
- return srcIndex - start;
- }
-
- internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex)
- {
- int start = dstIndex;
- WriteInt2(NameTrnId, dst, dstIndex);
- dst[dstIndex + OpcodeOffset] = unchecked((byte)((IsResponse ? unchecked(0x80) : unchecked(0x00)) + ((OpCode << 3) & unchecked(0x78)) + (IsAuthAnswer
- ? unchecked(0x04) : unchecked(0x00)) + (IsTruncated ? unchecked(0x02) : unchecked(0x00)) + (IsRecurDesired ? unchecked(0x01)
- : unchecked(0x00))));
- dst[dstIndex + OpcodeOffset + 1] = unchecked((byte)((IsRecurAvailable ? unchecked(
- 0x80) : unchecked(0x00)) + (IsBroadcast ? unchecked(0x10) :
- unchecked(0x00)) + (ResultCode & unchecked(0x0F))));
- WriteInt2(QuestionCount, dst, start + QuestionOffset);
- WriteInt2(AnswerCount, dst, start + AnswerOffset);
- WriteInt2(AuthorityCount, dst, start + AuthorityOffset);
- WriteInt2(AdditionalCount, dst, start + AdditionalOffset);
- return HeaderLength;
- }
-
- internal virtual int ReadHeaderWireFormat(byte[] src, int srcIndex)
- {
- NameTrnId = ReadInt2(src, srcIndex);
- IsResponse = ((src[srcIndex + OpcodeOffset] & unchecked(0x80)) == 0) ? false
- : true;
- OpCode = (src[srcIndex + OpcodeOffset] & unchecked(0x78)) >> 3;
- IsAuthAnswer = ((src[srcIndex + OpcodeOffset] & unchecked(0x04)) == 0) ?
- false : true;
- IsTruncated = ((src[srcIndex + OpcodeOffset] & unchecked(0x02)) == 0) ? false
- : true;
- IsRecurDesired = ((src[srcIndex + OpcodeOffset] & unchecked(0x01)) == 0) ?
- false : true;
- IsRecurAvailable = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x80))
- == 0) ? false : true;
- IsBroadcast = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x10)) == 0)
- ? false : true;
- ResultCode = src[srcIndex + OpcodeOffset + 1] & unchecked(0x0F);
- QuestionCount = ReadInt2(src, srcIndex + QuestionOffset);
- AnswerCount = ReadInt2(src, srcIndex + AnswerOffset);
- AuthorityCount = ReadInt2(src, srcIndex + AuthorityOffset);
- AdditionalCount = ReadInt2(src, srcIndex + AdditionalOffset);
- return HeaderLength;
- }
-
- internal virtual int WriteQuestionSectionWireFormat(byte[] dst, int dstIndex)
- {
- int start = dstIndex;
- dstIndex += QuestionName.WriteWireFormat(dst, dstIndex);
- WriteInt2(QuestionType, dst, dstIndex);
- dstIndex += 2;
- WriteInt2(QuestionClass, dst, dstIndex);
- dstIndex += 2;
- return dstIndex - start;
- }
-
- internal virtual int ReadQuestionSectionWireFormat(byte[] src, int srcIndex)
- {
- int start = srcIndex;
- srcIndex += QuestionName.ReadWireFormat(src, srcIndex);
- QuestionType = ReadInt2(src, srcIndex);
- srcIndex += 2;
- QuestionClass = ReadInt2(src, srcIndex);
- srcIndex += 2;
- return srcIndex - start;
- }
-
- internal virtual int WriteResourceRecordWireFormat(byte[] dst, int dstIndex)
- {
- int start = dstIndex;
- if (RecordName == QuestionName)
- {
- dst[dstIndex++] = unchecked(unchecked(0xC0));
- // label string pointer to
- dst[dstIndex++] = unchecked(unchecked(0x0C));
- }
- else
- {
- // questionName (offset 12)
- dstIndex += RecordName.WriteWireFormat(dst, dstIndex);
- }
- WriteInt2(RecordType, dst, dstIndex);
- dstIndex += 2;
- WriteInt2(RecordClass, dst, dstIndex);
- dstIndex += 2;
- WriteInt4(Ttl, dst, dstIndex);
- dstIndex += 4;
- RDataLength = WriteRDataWireFormat(dst, dstIndex + 2);
- WriteInt2(RDataLength, dst, dstIndex);
- dstIndex += 2 + RDataLength;
- return dstIndex - start;
- }
-
- internal virtual int ReadResourceRecordWireFormat(byte[] src, int srcIndex)
- {
- int start = srcIndex;
- int end;
- if ((src[srcIndex] & unchecked(0xC0)) == unchecked(0xC0))
- {
- RecordName = QuestionName;
- // label string pointer to questionName
- srcIndex += 2;
- }
- else
- {
- srcIndex += RecordName.ReadWireFormat(src, srcIndex);
- }
- RecordType = ReadInt2(src, srcIndex);
- srcIndex += 2;
- RecordClass = ReadInt2(src, srcIndex);
- srcIndex += 2;
- Ttl = ReadInt4(src, srcIndex);
- srcIndex += 4;
- RDataLength = ReadInt2(src, srcIndex);
- srcIndex += 2;
- AddrEntry = new NbtAddress[RDataLength / 6];
- end = srcIndex + RDataLength;
- for (AddrIndex = 0; srcIndex < end; AddrIndex++)
- {
- srcIndex += ReadRDataWireFormat(src, srcIndex);
- }
- return srcIndex - start;
- }
-
- internal abstract int WriteBodyWireFormat(byte[] dst, int dstIndex);
-
- internal abstract int ReadBodyWireFormat(byte[] src, int srcIndex);
-
- internal abstract int WriteRDataWireFormat(byte[] dst, int dstIndex);
-
- internal abstract int ReadRDataWireFormat(byte[] src, int srcIndex);
-
- public override string ToString()
- {
- string opCodeString;
- string resultCodeString;
- string questionTypeString;
- string recordTypeString;
-
- switch (OpCode)
- {
- case Query:
- {
- opCodeString = "QUERY";
- break;
- }
-
- case Wack:
- {
- opCodeString = "WACK";
- break;
- }
-
- default:
- {
- opCodeString = Extensions.ToString(OpCode);
- break;
- }
- }
- switch (ResultCode)
- {
- case FmtErr:
- {
- resultCodeString = "FMT_ERR";
- break;
- }
-
- case SrvErr:
- {
- resultCodeString = "SRV_ERR";
- break;
- }
-
- case ImpErr:
- {
- resultCodeString = "IMP_ERR";
- break;
- }
-
- case RfsErr:
- {
- resultCodeString = "RFS_ERR";
- break;
- }
-
- case ActErr:
- {
- resultCodeString = "ACT_ERR";
- break;
- }
-
- case CftErr:
- {
- resultCodeString = "CFT_ERR";
- break;
- }
-
- default:
- {
- resultCodeString = "0x" + Hexdump.ToHexString(ResultCode, 1);
- break;
- }
- }
- switch (QuestionType)
- {
- case Nb:
- {
- questionTypeString = "NB";
- break;
- }
-
- case Nbstat:
- {
- questionTypeString = "NBSTAT";
- break;
- }
-
- default:
- {
- questionTypeString = "0x" + Hexdump.ToHexString(QuestionType, 4);
- break;
- }
- }
- switch (RecordType)
- {
- case A:
- {
- recordTypeString = "A";
- break;
- }
-
- case Ns:
- {
- recordTypeString = "NS";
- break;
- }
-
- case Null:
- {
- recordTypeString = "NULL";
- break;
- }
-
- case Nb:
- {
- recordTypeString = "NB";
- break;
- }
-
- case Nbstat:
- {
- recordTypeString = "NBSTAT";
- break;
- }
-
- default:
- {
- recordTypeString = "0x" + Hexdump.ToHexString(RecordType, 4);
- break;
- }
- }
- return "nameTrnId=" + NameTrnId + ",isResponse=" + IsResponse + ",opCode="
- + opCodeString + ",isAuthAnswer=" + IsAuthAnswer + ",isTruncated=" + IsTruncated
- + ",isRecurAvailable=" + IsRecurAvailable + ",isRecurDesired=" + IsRecurDesired
- + ",isBroadcast=" + IsBroadcast + ",resultCode=" + ResultCode + ",questionCount="
- + QuestionCount + ",answerCount=" + AnswerCount + ",authorityCount=" + AuthorityCount
- + ",additionalCount=" + AdditionalCount + ",questionName=" + QuestionName + ",questionType="
- + questionTypeString + ",questionClass=" + (QuestionClass == In ? "IN" : "0x" +
- Hexdump.ToHexString(QuestionClass, 4)) + ",recordName=" + RecordName + ",recordType="
- + recordTypeString + ",recordClass=" + (RecordClass == In ? "IN" : "0x" + Hexdump
- .ToHexString(RecordClass, 4)) + ",ttl=" + Ttl + ",rDataLength=" + RDataLength;
- }
- }
+ internal Name RecordName;
+
+ internal int QuestionType;
+
+ internal int QuestionClass;
+
+ internal int RecordType;
+
+ internal int RecordClass;
+
+ internal int Ttl;
+
+ internal int RDataLength;
+
+ internal IPAddress Addr;
+
+ public NameServicePacket()
+ {
+ IsRecurDesired = true;
+ IsBroadcast = true;
+ QuestionCount = 1;
+ QuestionClass = In;
+ }
+
+ internal virtual int WriteWireFormat(byte[] dst, int dstIndex)
+ {
+ int start = dstIndex;
+ dstIndex += WriteHeaderWireFormat(dst, dstIndex);
+ dstIndex += WriteBodyWireFormat(dst, dstIndex);
+ return dstIndex - start;
+ }
+
+ internal virtual int ReadWireFormat(byte[] src, int srcIndex)
+ {
+ int start = srcIndex;
+ srcIndex += ReadHeaderWireFormat(src, srcIndex);
+ srcIndex += ReadBodyWireFormat(src, srcIndex);
+ return srcIndex - start;
+ }
+
+ internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex)
+ {
+ int start = dstIndex;
+ WriteInt2(NameTrnId, dst, dstIndex);
+ dst[dstIndex + OpcodeOffset] = unchecked(
+ (byte)(
+ (IsResponse
+ ? unchecked(0x80)
+ : unchecked(0x00))
+ + ((OpCode << 3) & unchecked(0x78))
+ + (IsAuthAnswer
+ ? unchecked(0x04)
+ : unchecked(0x00))
+ + (IsTruncated
+ ? unchecked(0x02)
+ : unchecked(0x00))
+ + (IsRecurDesired
+ ? unchecked(0x01)
+ : unchecked(0x00))
+ )
+ );
+ dst[dstIndex + OpcodeOffset + 1] = unchecked(
+ (byte)(
+ (IsRecurAvailable
+ ? unchecked(0x80)
+ : unchecked(0x00))
+ + (IsBroadcast
+ ? unchecked(0x10)
+ : unchecked(0x00))
+ + (ResultCode & unchecked(0x0F))
+ )
+ );
+ WriteInt2(QuestionCount, dst, start + QuestionOffset);
+ WriteInt2(AnswerCount, dst, start + AnswerOffset);
+ WriteInt2(AuthorityCount, dst, start + AuthorityOffset);
+ WriteInt2(AdditionalCount, dst, start + AdditionalOffset);
+ return HeaderLength;
+ }
+
+ internal virtual int ReadHeaderWireFormat(byte[] src, int srcIndex)
+ {
+ NameTrnId = ReadInt2(src, srcIndex);
+
+ IsResponse = ((src[srcIndex + OpcodeOffset] & unchecked(0x80)) == 0)
+ ? false
+ : true;
+ OpCode = (src[srcIndex + OpcodeOffset] & unchecked(0x78)) >> 3;
+ IsAuthAnswer = ((src[srcIndex + OpcodeOffset] & unchecked(0x04)) == 0)
+ ? false
+ : true;
+ IsTruncated = ((src[srcIndex + OpcodeOffset] & unchecked(0x02)) == 0)
+ ? false
+ : true;
+ IsRecurDesired = ((src[srcIndex + OpcodeOffset] & unchecked(0x01)) == 0)
+ ? false
+ : true;
+ IsRecurAvailable = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x80)) == 0)
+ ? false
+ : true;
+ IsBroadcast = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x10)) == 0)
+ ? false
+ : true;
+ ResultCode = src[srcIndex + OpcodeOffset + 1] & unchecked(0x0F);
+ QuestionCount = ReadInt2(src, srcIndex + QuestionOffset);
+ AnswerCount = ReadInt2(src, srcIndex + AnswerOffset);
+ AuthorityCount = ReadInt2(src, srcIndex + AuthorityOffset);
+ AdditionalCount = ReadInt2(src, srcIndex + AdditionalOffset);
+ return HeaderLength;
+ }
+
+ internal virtual int WriteQuestionSectionWireFormat(byte[] dst, int dstIndex)
+ {
+ int start = dstIndex;
+ dstIndex += QuestionName.WriteWireFormat(dst, dstIndex);
+ WriteInt2(QuestionType, dst, dstIndex);
+ dstIndex += 2;
+ WriteInt2(QuestionClass, dst, dstIndex);
+ dstIndex += 2;
+ return dstIndex - start;
+ }
+
+ internal virtual int ReadQuestionSectionWireFormat(byte[] src, int srcIndex)
+ {
+ int start = srcIndex;
+ srcIndex += QuestionName.ReadWireFormat(src, srcIndex);
+ QuestionType = ReadInt2(src, srcIndex);
+ srcIndex += 2;
+ QuestionClass = ReadInt2(src, srcIndex);
+ srcIndex += 2;
+ return srcIndex - start;
+ }
+
+ internal virtual int WriteResourceRecordWireFormat(byte[] dst, int dstIndex)
+ {
+ int start = dstIndex;
+ if (RecordName == QuestionName)
+ {
+ dst[dstIndex++] = unchecked(unchecked(0xC0));
+ // label string pointer to
+ dst[dstIndex++] = unchecked(unchecked(0x0C));
+ }
+ else
+ {
+ // questionName (offset 12)
+ dstIndex += RecordName.WriteWireFormat(dst, dstIndex);
+ }
+ WriteInt2(RecordType, dst, dstIndex);
+ dstIndex += 2;
+ WriteInt2(RecordClass, dst, dstIndex);
+ dstIndex += 2;
+ WriteInt4(Ttl, dst, dstIndex);
+ dstIndex += 4;
+ RDataLength = WriteRDataWireFormat(dst, dstIndex + 2);
+ WriteInt2(RDataLength, dst, dstIndex);
+ dstIndex += 2 + RDataLength;
+ return dstIndex - start;
+ }
+
+ internal virtual int ReadResourceRecordWireFormat(byte[] src, int srcIndex)
+ {
+ int start = srcIndex;
+ int end;
+ if ((src[srcIndex] & unchecked(0xC0)) == unchecked(0xC0))
+ {
+ RecordName = QuestionName;
+ // label string pointer to questionName
+ srcIndex += 2;
+ }
+ else
+ {
+ srcIndex += RecordName.ReadWireFormat(src, srcIndex);
+ }
+ RecordType = ReadInt2(src, srcIndex);
+ srcIndex += 2;
+ RecordClass = ReadInt2(src, srcIndex);
+ srcIndex += 2;
+ Ttl = ReadInt4(src, srcIndex);
+ srcIndex += 4;
+ RDataLength = ReadInt2(src, srcIndex);
+ srcIndex += 2;
+ AddrEntry = new NbtAddress[RDataLength / 6];
+ end = srcIndex + RDataLength;
+ for (AddrIndex = 0; srcIndex < end; AddrIndex++)
+ {
+ srcIndex += ReadRDataWireFormat(src, srcIndex);
+ }
+ return srcIndex - start;
+ }
+
+ internal abstract int WriteBodyWireFormat(byte[] dst, int dstIndex);
+
+ internal abstract int ReadBodyWireFormat(byte[] src, int srcIndex);
+
+ internal abstract int WriteRDataWireFormat(byte[] dst, int dstIndex);
+
+ internal abstract int ReadRDataWireFormat(byte[] src, int srcIndex);
+
+ public override string ToString()
+ {
+ string opCodeString;
+ string resultCodeString;
+ string questionTypeString;
+ string recordTypeString;
+
+ switch (OpCode)
+ {
+ case Query:
+ {
+ opCodeString = "QUERY";
+ break;
+ }
+
+ case Wack:
+ {
+ opCodeString = "WACK";
+ break;
+ }
+
+ default:
+ {
+ opCodeString = Extensions.ToString(OpCode);
+ break;
+ }
+ }
+ switch (ResultCode)
+ {
+ case FmtErr:
+ {
+ resultCodeString = "FMT_ERR";
+ break;
+ }
+
+ case SrvErr:
+ {
+ resultCodeString = "SRV_ERR";
+ break;
+ }
+
+ case ImpErr:
+ {
+ resultCodeString = "IMP_ERR";
+ break;
+ }
+
+ case RfsErr:
+ {
+ resultCodeString = "RFS_ERR";
+ break;
+ }
+
+ case ActErr:
+ {
+ resultCodeString = "ACT_ERR";
+ break;
+ }
+
+ case CftErr:
+ {
+ resultCodeString = "CFT_ERR";
+ break;
+ }
+
+ default:
+ {
+ resultCodeString = "0x" + Hexdump.ToHexString(ResultCode, 1);
+ break;
+ }
+ }
+ switch (QuestionType)
+ {
+ case Nb:
+ {
+ questionTypeString = "NB";
+ break;
+ }
+
+ case Nbstat:
+ {
+ questionTypeString = "NBSTAT";
+ break;
+ }
+
+ default:
+ {
+ questionTypeString = "0x" + Hexdump.ToHexString(QuestionType, 4);
+ break;
+ }
+ }
+ switch (RecordType)
+ {
+ case A:
+ {
+ recordTypeString = "A";
+ break;
+ }
+
+ case Ns:
+ {
+ recordTypeString = "NS";
+ break;
+ }
+
+ case Null:
+ {
+ recordTypeString = "NULL";
+ break;
+ }
+
+ case Nb:
+ {
+ recordTypeString = "NB";
+ break;
+ }
+
+ case Nbstat:
+ {
+ recordTypeString = "NBSTAT";
+ break;
+ }
+
+ default:
+ {
+ recordTypeString = "0x" + Hexdump.ToHexString(RecordType, 4);
+ break;
+ }
+ }
+ return "nameTrnId=" + NameTrnId
+ + ",isResponse=" + IsResponse
+ + ",opCode=" + opCodeString
+ + ",isAuthAnswer=" + IsAuthAnswer
+ + ",isTruncated=" + IsTruncated
+ + ",isRecurAvailable=" + IsRecurAvailable
+ + ",isRecurDesired=" + IsRecurDesired
+ + ",isBroadcast=" + IsBroadcast
+ + ",resultCode=" + ResultCode
+ + ",questionCount=" + QuestionCount
+ + ",answerCount=" + AnswerCount
+ + ",authorityCount=" + AuthorityCount
+ + ",additionalCount=" + AdditionalCount
+ + ",questionName=" + QuestionName
+ + ",questionType=" + questionTypeString
+ + ",questionClass=" + (QuestionClass == In
+ ? "IN"
+ : "0x" + Hexdump.ToHexString(QuestionClass, 4))
+ + ",recordName=" + RecordName
+ + ",recordType=" + recordTypeString
+ + ",recordClass=" + (RecordClass == In
+ ? "IN"
+ : "0x" + Hexdump.ToHexString(RecordClass, 4))
+ + ",ttl=" + Ttl
+ + ",rDataLength=" + RDataLength;
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs
index c64d385f1..34f70d27b 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs
@@ -18,903 +18,949 @@ using System;
using System.Linq;
using System.Net;
using SharpCifs.Util;
+using SharpCifs.Util.DbsHelper;
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:\&gt;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
- {
+ /// <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:\&gt;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))
+ };
+
+ private 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;
+ }
+ }
+
+ private 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)
- {
+ }
+ 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
+ );
+ */
+ try
+ {
+ localHostname = Dns.GetHostName();
+ }
+ catch (Exception)
+ {
+ 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);
+ }
+
+ private 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);
+ }
+
+ private 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.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);
+ if (entry == null)
+ {
+ entry = new CacheEntry(hostName, addr, expiration);
+ AddressCache.Put(hostName, entry);
+ }
+ else
+ {
+ entry.Address = addr;
+ entry.Expiration = expiration;
+ }
+ }
+ }
+
+ private 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;
+ }
+ }
+ }
+ }
+
+ private 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>
+ private 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. &lt;a
- /// href="../../../nbtcodes.html"&gt;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();
- }
- }
+ 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()
+ {
+ //Log.Out("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. &lt;a
+ /// href="../../../nbtcodes.html"&gt;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();
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtException.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtException.cs
index e785c9943..9ade0e67c 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtException.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NbtException.cs
@@ -19,146 +19,147 @@ using System.IO;
namespace SharpCifs.Netbios
{
- public class NbtException : IOException
- {
- public const int Success = 0;
-
- public const int ErrNamSrvc = unchecked(0x01);
-
- public const int ErrSsnSrvc = unchecked(0x02);
-
- public const int FmtErr = unchecked(0x1);
-
- public const int SrvErr = unchecked(0x2);
-
- public const int ImpErr = unchecked(0x4);
-
- public const int RfsErr = unchecked(0x5);
-
- public const int ActErr = unchecked(0x6);
-
- public const int CftErr = unchecked(0x7);
-
- public const int ConnectionRefused = -1;
-
- public const int NotListeningCalled = unchecked(0x80);
-
- public const int NotListeningCalling = unchecked(0x81);
-
- public const int CalledNotPresent = unchecked(0x82);
-
- public const int NoResources = unchecked(0x83);
-
- public const int Unspecified = unchecked(0x8F);
-
- public int ErrorClass;
-
- public int ErrorCode;
-
- // error classes
- // name service error codes
- // session service error codes
- public static string GetErrorString(int errorClass, int errorCode)
- {
- string result = string.Empty;
- switch (errorClass)
- {
- case Success:
- {
- result += "SUCCESS";
- break;
- }
-
- case ErrNamSrvc:
- {
- result += "ERR_NAM_SRVC/";
- switch (errorCode)
- {
- case FmtErr:
- {
- result += "FMT_ERR: Format Error";
- goto default;
- }
-
- default:
- {
- result += "Unknown error code: " + errorCode;
- break;
- }
- }
- break;
- }
-
- case ErrSsnSrvc:
- {
- result += "ERR_SSN_SRVC/";
- switch (errorCode)
- {
- case ConnectionRefused:
- {
- result += "Connection refused";
- break;
- }
-
- case NotListeningCalled:
- {
- result += "Not listening on called name";
- break;
- }
-
- case NotListeningCalling:
- {
- result += "Not listening for calling name";
- break;
- }
-
- case CalledNotPresent:
- {
- result += "Called name not present";
- break;
- }
-
- case NoResources:
- {
- result += "Called name present, but insufficient resources";
- break;
- }
-
- case Unspecified:
- {
- result += "Unspecified error";
- break;
- }
-
- default:
- {
- result += "Unknown error code: " + errorCode;
- break;
- }
- }
- break;
- }
-
- default:
- {
- result += "unknown error class: " + errorClass;
- break;
- }
- }
- return result;
- }
-
- public NbtException(int errorClass, int errorCode) : base(GetErrorString(errorClass
- , errorCode))
- {
- this.ErrorClass = errorClass;
- this.ErrorCode = errorCode;
- }
-
- public override string ToString()
- {
- return "errorClass=" + ErrorClass + ",errorCode=" + ErrorCode + ",errorString="
- + GetErrorString(ErrorClass, ErrorCode);
- }
- }
+ public class NbtException : IOException
+ {
+ public const int Success = 0;
+
+ public const int ErrNamSrvc = unchecked(0x01);
+
+ public const int ErrSsnSrvc = unchecked(0x02);
+
+ public const int FmtErr = unchecked(0x1);
+
+ public const int SrvErr = unchecked(0x2);
+
+ public const int ImpErr = unchecked(0x4);
+
+ public const int RfsErr = unchecked(0x5);
+
+ public const int ActErr = unchecked(0x6);
+
+ public const int CftErr = unchecked(0x7);
+
+ public const int ConnectionRefused = -1;
+
+ public const int NotListeningCalled = unchecked(0x80);
+
+ public const int NotListeningCalling = unchecked(0x81);
+
+ public const int CalledNotPresent = unchecked(0x82);
+
+ public const int NoResources = unchecked(0x83);
+
+ public const int Unspecified = unchecked(0x8F);
+
+ public int ErrorClass;
+
+ public int ErrorCode;
+
+ // error classes
+ // name service error codes
+ // session service error codes
+ public static string GetErrorString(int errorClass, int errorCode)
+ {
+ string result = string.Empty;
+ switch (errorClass)
+ {
+ case Success:
+ {
+ result += "SUCCESS";
+ break;
+ }
+
+ case ErrNamSrvc:
+ {
+ result += "ERR_NAM_SRVC/";
+ switch (errorCode)
+ {
+ case FmtErr:
+ {
+ result += "FMT_ERR: Format Error";
+ goto default;
+ }
+
+ default:
+ {
+ result += "Unknown error code: " + errorCode;
+ break;
+ }
+ }
+ break;
+ }
+
+ case ErrSsnSrvc:
+ {
+ result += "ERR_SSN_SRVC/";
+ switch (errorCode)
+ {
+ case ConnectionRefused:
+ {
+ result += "Connection refused";
+ break;
+ }
+
+ case NotListeningCalled:
+ {
+ result += "Not listening on called name";
+ break;
+ }
+
+ case NotListeningCalling:
+ {
+ result += "Not listening for calling name";
+ break;
+ }
+
+ case CalledNotPresent:
+ {
+ result += "Called name not present";
+ break;
+ }
+
+ case NoResources:
+ {
+ result += "Called name present, but insufficient resources";
+ break;
+ }
+
+ case Unspecified:
+ {
+ result += "Unspecified error";
+ break;
+ }
+
+ default:
+ {
+ result += "Unknown error code: " + errorCode;
+ break;
+ }
+ }
+ break;
+ }
+
+ default:
+ {
+ result += "unknown error class: " + errorClass;
+ break;
+ }
+ }
+ return result;
+ }
+
+ public NbtException(int errorClass, int errorCode) : base(GetErrorString(errorClass
+ , errorCode))
+ {
+ this.ErrorClass = errorClass;
+ this.ErrorCode = errorCode;
+ }
+
+ public override string ToString()
+ {
+ return "errorClass=" + ErrorClass
+ + ",errorCode=" + ErrorCode
+ + ",errorString=" + GetErrorString(ErrorClass, ErrorCode);
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs
index 66d3bb3e5..b7922eb84 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs
@@ -16,44 +16,44 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
namespace SharpCifs.Netbios
{
- internal class NodeStatusRequest : NameServicePacket
- {
- internal NodeStatusRequest(Name name)
- {
- QuestionName = name;
- QuestionType = Nbstat;
- IsRecurDesired = false;
- IsBroadcast = false;
- }
+ internal class NodeStatusRequest : NameServicePacket
+ {
+ internal NodeStatusRequest(Name name)
+ {
+ QuestionName = name;
+ QuestionType = Nbstat;
+ IsRecurDesired = false;
+ IsBroadcast = false;
+ }
- internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
- {
- int tmp = QuestionName.HexCode;
- QuestionName.HexCode = unchecked(0x00);
- // type has to be 0x00 for node status
- int result = WriteQuestionSectionWireFormat(dst, dstIndex);
- QuestionName.HexCode = tmp;
- return result;
- }
+ internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
+ {
+ int tmp = QuestionName.HexCode;
+ QuestionName.HexCode = unchecked(0x00);
+ // type has to be 0x00 for node status
+ int result = WriteQuestionSectionWireFormat(dst, dstIndex);
+ QuestionName.HexCode = tmp;
+ return result;
+ }
- internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
- {
- return 0;
- }
+ internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
+ {
+ return 0;
+ }
- internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
- {
- return 0;
- }
+ internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
+ {
+ return 0;
+ }
- public override string ToString()
- {
- return "NodeStatusRequest[" + base.ToString() + "]";
- }
- }
+ public override string ToString()
+ {
+ return "NodeStatusRequest[" + base.ToString() + "]";
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs
index aa3214419..ac0210217 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs
@@ -19,122 +19,140 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- internal class NodeStatusResponse : NameServicePacket
- {
- private NbtAddress _queryAddress;
+ internal class NodeStatusResponse : NameServicePacket
+ {
+ private NbtAddress _queryAddress;
- private int _numberOfNames;
+ private int _numberOfNames;
- private byte[] _macAddress;
+ private byte[] _macAddress;
- private byte[] _stats;
+ private byte[] _stats;
- internal NbtAddress[] AddressArray;
+ internal NbtAddress[] AddressArray;
- internal NodeStatusResponse(NbtAddress queryAddress)
- {
- this._queryAddress = queryAddress;
- RecordName = new Name();
- _macAddress = new byte[6];
- }
+ internal NodeStatusResponse(NbtAddress queryAddress)
+ {
+ this._queryAddress = queryAddress;
+ RecordName = new Name();
+ _macAddress = new byte[6];
+ }
- internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteBodyWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
- {
- return ReadResourceRecordWireFormat(src, srcIndex);
- }
+ internal override int ReadBodyWireFormat(byte[] src, int srcIndex)
+ {
+ return ReadResourceRecordWireFormat(src, srcIndex);
+ }
- internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteRDataWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
- {
- int start = srcIndex;
- _numberOfNames = src[srcIndex] & unchecked(0xFF);
- int namesLength = _numberOfNames * 18;
- int statsLength = RDataLength - namesLength - 1;
- _numberOfNames = src[srcIndex++] & unchecked(0xFF);
- // gotta read the mac first so we can populate addressArray with it
- Array.Copy(src, srcIndex + namesLength, _macAddress, 0, 6);
- srcIndex += ReadNodeNameArray(src, srcIndex);
- _stats = new byte[statsLength];
- Array.Copy(src, srcIndex, _stats, 0, statsLength);
- srcIndex += statsLength;
- return srcIndex - start;
- }
+ internal override int ReadRDataWireFormat(byte[] src, int srcIndex)
+ {
+ int start = srcIndex;
+ _numberOfNames = src[srcIndex] & unchecked(0xFF);
+ int namesLength = _numberOfNames * 18;
+ int statsLength = RDataLength - namesLength - 1;
+ _numberOfNames = src[srcIndex++] & unchecked(0xFF);
+ // gotta read the mac first so we can populate addressArray with it
+ Array.Copy(src, srcIndex + namesLength, _macAddress, 0, 6);
+ srcIndex += ReadNodeNameArray(src, srcIndex);
+ _stats = new byte[statsLength];
+ Array.Copy(src, srcIndex, _stats, 0, statsLength);
+ srcIndex += statsLength;
+ return srcIndex - start;
+ }
- private int ReadNodeNameArray(byte[] src, int srcIndex)
- {
- int start = srcIndex;
- AddressArray = new NbtAddress[_numberOfNames];
- string n;
- int hexCode;
- string scope = _queryAddress.HostName.Scope;
- bool groupName;
- int ownerNodeType;
- bool isBeingDeleted;
- bool isInConflict;
- bool isActive;
- bool isPermanent;
- int j;
- bool addrFound = false;
- try
- {
- for (int i = 0; i < _numberOfNames; srcIndex += 18, i++)
- {
- for (j = srcIndex + 14; src[j] == unchecked(0x20); j--)
- {
- }
- n = Runtime.GetStringForBytes(src, srcIndex, j - srcIndex + 1, Name.OemEncoding
- );
- hexCode = src[srcIndex + 15] & unchecked(0xFF);
- groupName = ((src[srcIndex + 16] & unchecked(0x80)) == unchecked(0x80)) ? true : false;
- ownerNodeType = (src[srcIndex + 16] & unchecked(0x60)) >> 5;
- isBeingDeleted = ((src[srcIndex + 16] & unchecked(0x10)) == unchecked(0x10)) ? true : false;
- isInConflict = ((src[srcIndex + 16] & unchecked(0x08)) == unchecked(0x08)) ? true : false;
- isActive = ((src[srcIndex + 16] & unchecked(0x04)) == unchecked(0x04)) ? true : false;
- isPermanent = ((src[srcIndex + 16] & unchecked(0x02)) == unchecked(0x02)) ? true : false;
- if (!addrFound && _queryAddress.HostName.HexCode == hexCode && (_queryAddress.HostName
- == NbtAddress.UnknownName || _queryAddress.HostName.name.Equals(n)))
- {
- if (_queryAddress.HostName == NbtAddress.UnknownName)
- {
- _queryAddress.HostName = new Name(n, hexCode, scope);
- }
- _queryAddress.GroupName = groupName;
- _queryAddress.NodeType = ownerNodeType;
- _queryAddress.isBeingDeleted = isBeingDeleted;
- _queryAddress.isInConflict = isInConflict;
- _queryAddress.isActive = isActive;
- _queryAddress.isPermanent = isPermanent;
- _queryAddress.MacAddress = _macAddress;
- _queryAddress.IsDataFromNodeStatus = true;
- addrFound = true;
- AddressArray[i] = _queryAddress;
- }
- else
- {
- AddressArray[i] = new NbtAddress(new Name(n, hexCode, scope), _queryAddress.Address
- , groupName, ownerNodeType, isBeingDeleted, isInConflict, isActive, isPermanent,
- _macAddress);
- }
- }
- }
- catch (UnsupportedEncodingException)
- {
- }
- return srcIndex - start;
- }
+ private int ReadNodeNameArray(byte[] src, int srcIndex)
+ {
+ int start = srcIndex;
+ AddressArray = new NbtAddress[_numberOfNames];
+ string n;
+ int hexCode;
+ string scope = _queryAddress.HostName.Scope;
+ bool groupName;
+ int ownerNodeType;
+ bool isBeingDeleted;
+ bool isInConflict;
+ bool isActive;
+ bool isPermanent;
+ int j;
+ bool addrFound = false;
+ try
+ {
+ for (int i = 0; i < _numberOfNames; srcIndex += 18, i++)
+ {
+ for (j = srcIndex + 14; src[j] == unchecked(0x20); j--)
+ {
+ }
+ n = Runtime.GetStringForBytes(src, srcIndex, j - srcIndex + 1, Name.OemEncoding
+ );
+ hexCode = src[srcIndex + 15] & unchecked(0xFF);
+ groupName = ((src[srcIndex + 16] & unchecked(0x80)) == unchecked(0x80))
+ ? true
+ : false;
+ ownerNodeType = (src[srcIndex + 16] & unchecked(0x60)) >> 5;
+ isBeingDeleted = ((src[srcIndex + 16] & unchecked(0x10)) == unchecked(0x10))
+ ? true
+ : false;
+ isInConflict = ((src[srcIndex + 16] & unchecked(0x08)) == unchecked(0x08))
+ ? true
+ : false;
+ isActive = ((src[srcIndex + 16] & unchecked(0x04)) == unchecked(0x04))
+ ? true
+ : false;
+ isPermanent = ((src[srcIndex + 16] & unchecked(0x02)) == unchecked(0x02))
+ ? true
+ : false;
+ if (!addrFound
+ && _queryAddress.HostName.HexCode == hexCode
+ && (_queryAddress.HostName == NbtAddress.UnknownName
+ || _queryAddress.HostName.name.Equals(n)))
+ {
+ if (_queryAddress.HostName == NbtAddress.UnknownName)
+ {
+ _queryAddress.HostName = new Name(n, hexCode, scope);
+ }
+ _queryAddress.GroupName = groupName;
+ _queryAddress.NodeType = ownerNodeType;
+ _queryAddress.isBeingDeleted = isBeingDeleted;
+ _queryAddress.isInConflict = isInConflict;
+ _queryAddress.isActive = isActive;
+ _queryAddress.isPermanent = isPermanent;
+ _queryAddress.MacAddress = _macAddress;
+ _queryAddress.IsDataFromNodeStatus = true;
+ addrFound = true;
+ AddressArray[i] = _queryAddress;
+ }
+ else
+ {
+ AddressArray[i] = new NbtAddress(new Name(n, hexCode, scope),
+ _queryAddress.Address,
+ groupName,
+ ownerNodeType,
+ isBeingDeleted,
+ isInConflict,
+ isActive,
+ isPermanent,
+ _macAddress);
+ }
+ }
+ }
+ catch (UnsupportedEncodingException)
+ {
+ }
+ return srcIndex - start;
+ }
- public override string ToString()
- {
- return "NodeStatusResponse[" + base.ToString() + "]";
- }
- }
+ public override string ToString()
+ {
+ return "NodeStatusResponse[" + base.ToString() + "]";
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs
index a5243f7aa..0f4d7e5e2 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs
@@ -19,45 +19,44 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- public class SessionRequestPacket : SessionServicePacket
- {
- private Name _calledName;
+ public class SessionRequestPacket : SessionServicePacket
+ {
+ private Name _calledName;
- private Name _callingName;
+ private Name _callingName;
- public SessionRequestPacket()
- {
- _calledName = new Name();
- _callingName = new Name();
- }
+ public SessionRequestPacket()
+ {
+ _calledName = new Name();
+ _callingName = new Name();
+ }
- public SessionRequestPacket(Name calledName, Name callingName)
- {
- Type = SessionRequest;
- this._calledName = calledName;
- this._callingName = callingName;
- }
+ public SessionRequestPacket(Name calledName, Name callingName)
+ {
+ Type = SessionRequest;
+ this._calledName = calledName;
+ this._callingName = callingName;
+ }
- internal override int WriteTrailerWireFormat(byte[] dst, int dstIndex)
- {
- int start = dstIndex;
- dstIndex += _calledName.WriteWireFormat(dst, dstIndex);
- dstIndex += _callingName.WriteWireFormat(dst, dstIndex);
- return dstIndex - start;
- }
+ internal override int WriteTrailerWireFormat(byte[] dst, int dstIndex)
+ {
+ int start = dstIndex;
+ dstIndex += _calledName.WriteWireFormat(dst, dstIndex);
+ dstIndex += _callingName.WriteWireFormat(dst, dstIndex);
+ return dstIndex - start;
+ }
- /// <exception cref="System.IO.IOException"></exception>
- internal override int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex
- )
- {
- int start = bufferIndex;
- if (@in.Read(buffer, bufferIndex, Length) != Length)
- {
- throw new IOException("invalid session request wire format");
- }
- bufferIndex += _calledName.ReadWireFormat(buffer, bufferIndex);
- bufferIndex += _callingName.ReadWireFormat(buffer, bufferIndex);
- return bufferIndex - start;
- }
- }
+ /// <exception cref="System.IO.IOException"></exception>
+ internal override int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex)
+ {
+ int start = bufferIndex;
+ if (@in.Read(buffer, bufferIndex, Length) != Length)
+ {
+ throw new IOException("invalid session request wire format");
+ }
+ bufferIndex += _calledName.ReadWireFormat(buffer, bufferIndex);
+ bufferIndex += _callingName.ReadWireFormat(buffer, bufferIndex);
+ return bufferIndex - start;
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs
index c901c6e26..48c772bae 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs
@@ -19,36 +19,35 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- internal class SessionRetargetResponsePacket : SessionServicePacket
- {
- private NbtAddress _retargetAddress;
+ internal class SessionRetargetResponsePacket : SessionServicePacket
+ {
+ private NbtAddress _retargetAddress;
- private int _retargetPort;
+ private int _retargetPort;
- public SessionRetargetResponsePacket()
- {
- Type = SessionRetargetResponse;
- Length = 6;
- }
+ public SessionRetargetResponsePacket()
+ {
+ Type = SessionRetargetResponse;
+ Length = 6;
+ }
- internal override int WriteTrailerWireFormat(byte[] dst, int dstIndex)
- {
- return 0;
- }
+ internal override int WriteTrailerWireFormat(byte[] dst, int dstIndex)
+ {
+ return 0;
+ }
- /// <exception cref="System.IO.IOException"></exception>
- internal override int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex
- )
- {
- if (@in.Read(buffer, bufferIndex, Length) != Length)
- {
- throw new IOException("unexpected EOF reading netbios retarget session response");
- }
- int addr = ReadInt4(buffer, bufferIndex);
- bufferIndex += 4;
- _retargetAddress = new NbtAddress(null, addr, false, NbtAddress.BNode);
- _retargetPort = ReadInt2(buffer, bufferIndex);
- return Length;
- }
- }
+ /// <exception cref="System.IO.IOException"></exception>
+ internal override int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex)
+ {
+ if (@in.Read(buffer, bufferIndex, Length) != Length)
+ {
+ throw new IOException("unexpected EOF reading netbios retarget session response");
+ }
+ int addr = ReadInt4(buffer, bufferIndex);
+ bufferIndex += 4;
+ _retargetAddress = new NbtAddress(null, addr, false, NbtAddress.BNode);
+ _retargetPort = ReadInt2(buffer, bufferIndex);
+ return Length;
+ }
+ }
}
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs b/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs
index c8d194222..795dff9bd 100644
--- a/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs
+++ b/Emby.Common.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs
@@ -19,138 +19,136 @@ using SharpCifs.Util.Sharpen;
namespace SharpCifs.Netbios
{
- public abstract class SessionServicePacket
- {
- internal const int SessionMessage = unchecked(0x00);
-
- internal const int SessionRequest = unchecked(0x81);
-
- public const int PositiveSessionResponse = unchecked(0x82);
-
- public const int NegativeSessionResponse = unchecked(0x83);
-
- internal const int SessionRetargetResponse = unchecked(0x84);
-
- internal const int SessionKeepAlive = unchecked(0x85);
-
- internal const int MaxMessageSize = unchecked(0x0001FFFF);
-
- internal const int HeaderLength = 4;
-
- // session service packet types
- internal static void WriteInt2(int val, byte[] dst, int dstIndex)
- {
- dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
- dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
- }
-
- internal static void WriteInt4(int val, byte[] dst, int dstIndex)
- {
- dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF)));
- dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF)));
- dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
- dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
- }
-
- internal static int ReadInt2(byte[] src, int srcIndex)
- {
- return ((src[srcIndex] & unchecked(0xFF)) << 8) + (src[srcIndex + 1] & unchecked(
- 0xFF));
- }
-
- internal static int ReadInt4(byte[] src, int srcIndex)
- {
- return ((src[srcIndex] & unchecked(0xFF)) << 24) + ((src[srcIndex + 1] & unchecked(
- 0xFF)) << 16) + ((src[srcIndex + 2] & unchecked(0xFF)) << 8) + (src
- [srcIndex + 3] & unchecked(0xFF));
- }
-
- internal static int ReadLength(byte[] src, int srcIndex)
- {
- srcIndex++;
- return ((src[srcIndex++] & unchecked(0x01)) << 16) + ((src[srcIndex++] & unchecked(
- 0xFF)) << 8) + (src[srcIndex++] & unchecked(0xFF));
- }
-
- /// <exception cref="System.IO.IOException"></exception>
- internal static int Readn(InputStream @in, byte[] b, int off, int len)
- {
- int i = 0;
- int n;
- while (i < len)
- {
- n = @in.Read(b, off + i, len - i);
- if (n <= 0)
- {
- break;
- }
- i += n;
- }
- return i;
- }
-
- /// <exception cref="System.IO.IOException"></exception>
- internal static int ReadPacketType(InputStream @in, byte[] buffer, int bufferIndex
- )
- {
- int n;
- if ((n = Readn(@in, buffer, bufferIndex, HeaderLength)) != HeaderLength)
- {
- if (n == -1)
- {
- return -1;
- }
- throw new IOException("unexpected EOF reading netbios session header");
- }
- int t = buffer[bufferIndex] & unchecked(0xFF);
- return t;
- }
-
- internal int Type;
-
- internal int Length;
-
- public virtual int WriteWireFormat(byte[] dst, int dstIndex)
- {
- Length = WriteTrailerWireFormat(dst, dstIndex + HeaderLength);
- WriteHeaderWireFormat(dst, dstIndex);
- return HeaderLength + Length;
- }
-
- /// <exception cref="System.IO.IOException"></exception>
- internal virtual int ReadWireFormat(InputStream @in, byte[] buffer, int bufferIndex
- )
- {
- ReadHeaderWireFormat(@in, buffer, bufferIndex);
- return HeaderLength + ReadTrailerWireFormat(@in, buffer, bufferIndex);
- }
-
- internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex)
- {
- dst[dstIndex++] = unchecked((byte)Type);
- if (Length > unchecked(0x0000FFFF))
- {
- dst[dstIndex] = unchecked(unchecked(0x01));
- }
- dstIndex++;
- WriteInt2(Length, dst, dstIndex);
- return HeaderLength;
- }
-
- /// <exception cref="System.IO.IOException"></exception>
- internal virtual int ReadHeaderWireFormat(InputStream @in, byte[] buffer, int bufferIndex
- )
- {
- Type = buffer[bufferIndex++] & unchecked(0xFF);
- Length = ((buffer[bufferIndex] & unchecked(0x01)) << 16) + ReadInt2(buffer
- , bufferIndex + 1);
- return HeaderLength;
- }
-
- internal abstract int WriteTrailerWireFormat(byte[] dst, int dstIndex);
-
- /// <exception cref="System.IO.IOException"></exception>
- internal abstract int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex
- );
- }
+ public abstract class SessionServicePacket
+ {
+ internal const int SessionMessage = unchecked(0x00);
+
+ internal const int SessionRequest = unchecked(0x81);
+
+ public const int PositiveSessionResponse = unchecked(0x82);
+
+ public const int NegativeSessionResponse = unchecked(0x83);
+
+ internal const int SessionRetargetResponse = unchecked(0x84);
+
+ internal const int SessionKeepAlive = unchecked(0x85);
+
+ internal const int MaxMessageSize = unchecked(0x0001FFFF);
+
+ internal const int HeaderLength = 4;
+
+ // session service packet types
+ internal static void WriteInt2(int val, byte[] dst, int dstIndex)
+ {
+ dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
+ dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
+ }
+
+ internal static void WriteInt4(int val, byte[] dst, int dstIndex)
+ {
+ dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF)));
+ dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF)));
+ dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));
+ dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));
+ }
+
+ internal static int ReadInt2(byte[] src, int srcIndex)
+ {
+ return ((src[srcIndex] & unchecked(0xFF)) << 8)
+ + (src[srcIndex + 1] & unchecked(0xFF));
+ }
+
+ internal static int ReadInt4(byte[] src, int srcIndex)
+ {
+ return ((src[srcIndex] & unchecked(0xFF)) << 24)
+ + ((src[srcIndex + 1] & unchecked(0xFF)) << 16)
+ + ((src[srcIndex + 2] & unchecked(0xFF)) << 8)
+ + (src[srcIndex + 3] & unchecked(0xFF));
+ }
+
+ internal static int ReadLength(byte[] src, int srcIndex)
+ {
+ srcIndex++;
+ return ((src[srcIndex++] & unchecked(0x01)) << 16)
+ + ((src[srcIndex++] & unchecked(0xFF)) << 8)
+ + (src[srcIndex++] & unchecked(0xFF));
+ }
+
+ /// <exception cref="System.IO.IOException"></exception>
+ internal static int Readn(InputStream @in, byte[] b, int off, int len)
+ {
+ int i = 0;
+ int n;
+ while (i < len)
+ {
+ n = @in.Read(b, off + i, len - i);
+ if (n <= 0)
+ {
+ break;
+ }
+ i += n;
+ }
+ return i;
+ }
+
+ /// <exception cref="System.IO.IOException"></exception>
+ internal static int ReadPacketType(InputStream @in, byte[] buffer, int bufferIndex)
+ {
+ int n;
+ if ((n = Readn(@in, buffer, bufferIndex, HeaderLength)) != HeaderLength)
+ {
+ if (n == -1)
+ {
+ return -1;
+ }
+ throw new IOException("unexpected EOF reading netbios session header");
+ }
+ int t = buffer[bufferIndex] & unchecked(0xFF);
+ return t;
+ }
+
+ internal int Type;
+
+ internal int Length;
+
+ public virtual int WriteWireFormat(byte[] dst, int dstIndex)
+ {
+ Length = WriteTrailerWireFormat(dst, dstIndex + HeaderLength);
+ WriteHeaderWireFormat(dst, dstIndex);
+ return HeaderLength + Length;
+ }
+
+ /// <exception cref="System.IO.IOException"></exception>
+ internal virtual int ReadWireFormat(InputStream @in, byte[] buffer, int bufferIndex)
+ {
+ ReadHeaderWireFormat(@in, buffer, bufferIndex);
+ return HeaderLength + ReadTrailerWireFormat(@in, buffer, bufferIndex);
+ }
+
+ internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex)
+ {
+ dst[dstIndex++] = unchecked((byte)Type);
+ if (Length > unchecked(0x0000FFFF))
+ {
+ dst[dstIndex] = unchecked(unchecked(0x01));
+ }
+ dstIndex++;
+ WriteInt2(Length, dst, dstIndex);
+ return HeaderLength;
+ }
+
+ /// <exception cref="System.IO.IOException"></exception>
+ internal virtual int ReadHeaderWireFormat(InputStream @in, byte[] buffer, int bufferIndex)
+ {
+ Type = buffer[bufferIndex++] & unchecked(0xFF);
+ Length = ((buffer[bufferIndex] & unchecked(0x01)) << 16)
+ + ReadInt2(buffer, bufferIndex + 1);
+ return HeaderLength;
+ }
+
+ internal abstract int WriteTrailerWireFormat(byte[] dst, int dstIndex);
+
+ /// <exception cref="System.IO.IOException"></exception>
+ internal abstract int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex);
+ }
}